diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 14e4afa..5b06a83 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -51,8 +51,8 @@ jobs: LC_ALL: C run: | # The scan action splits args; reject characters that could introduce properties. - if [[ ! "$PROJECT_KEY" =~ ^[a-zA-Z0-9_.:-]+$ ]]; then - echo "::error::Invalid SonarCloud project key: use only letters, digits, dash, underscore, period or colon." + if [[ ! "$PROJECT_KEY" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_.:-]*$ || ${#PROJECT_KEY} -gt 400 ]]; then + echo "::error::Invalid SonarCloud project key: must start with an alphanumeric character or underscore and contain only letters, digits, dash, underscore, period or colon (max 400 characters)." exit 1 fi printf 'key=%s\n' "$PROJECT_KEY" >>"$GITHUB_OUTPUT" diff --git a/tests/test_freebsd.py b/tests/test_freebsd.py index 748bceb..36e26eb 100644 --- a/tests/test_freebsd.py +++ b/tests/test_freebsd.py @@ -398,6 +398,18 @@ fi text=True, capture_output=True, timeout=15) self.assertEqual(result.returncode, code, result) + def test_freebsd_workflow_rejects_unsupported_architectures_before_the_vm(self): + workflow = yaml.load((ROOT / ".github/workflows/freebsd.yml").read_text(), Loader=yaml.BaseLoader) + steps = workflow["jobs"]["freebsd"]["steps"] + check = next(step for step in steps if step.get("name") == "Validate the architecture") + self.assertEqual(check["env"]["ARCH"], "${{ matrix.arch }}") + for arch, code in (("x86_64", 0), ("aarch64", 0), ("riscv64", 1), ("amd64", 1), ("", 1), + ("x86_64; id", 1), ("`touch injected`", 1)): + with self.subTest(arch=arch): + result = subprocess.run(["bash", "-e", "-c", check["run"]], env={**os.environ, "ARCH": arch}, + text=True, capture_output=True, timeout=15) + self.assertEqual(result.returncode, code, result) + def vm_steps(self): release = yaml.load((ROOT / ".github/workflows/release.yml").read_text(), Loader=yaml.BaseLoader) for name, job in (("freebsd.yml", DATA["jobs"]["freebsd"]), ("release.yml", release["jobs"]["freebsd"])): diff --git a/tests/test_sonarcloud.py b/tests/test_sonarcloud.py index 63329f9..58f0222 100644 --- a/tests/test_sonarcloud.py +++ b/tests/test_sonarcloud.py @@ -44,12 +44,14 @@ class SonarCloudTests(unittest.TestCase): def test_invalid_keys_cannot_publish_scanner_arguments(self): for key in ( - '', 'key -Dsonar.host.url=https://attacker.invalid', + '', '-Dsonar.host.url=https://attacker.invalid', + '-leading-dash', 'key -Dsonar.host.url=https://attacker.invalid', 'key\t-Dsonar.host.url=https://attacker.invalid', 'key\n-Dsonar.host.url=https://attacker.invalid', 'key\r\nkey=other', 'key" -Dsonar.host.url="https://attacker.invalid', "key' -Dsonar.host.url='https://attacker.invalid", 'key\\ value', '$(touch injected)', '`touch injected`', 'key/other', + 'a' * 401, ): with self.subTest(key=key): result, output = self.run_step(self.validation, PROJECT_KEY=key)