Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions utils/tests/verify_action_build/test_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,42 @@ def test_calculate_sha256_function_name_recognized(self):
content = f"const sha = {func_name}(downloadPath)\n"
assert self._has_verification(content) is True, func_name

def test_validate_checksum_function_name_recognized(self):
# astral-sh/setup-uv@v8.2.0 shape: ``src/download/download-version.ts``
# downloads via ``tc.downloadTool`` then calls ``validateChecksum(...)``,
# whose implementation was extracted into a sibling module
# (``./checksum/checksum``). The call name is the in-file evidence the
# scanner must accept; without it, #910 false-flagged the download as
# unverified.
for func_name in (
"validateChecksum",
"validateFileCheckSum",
"validateHash",
"validateDigest",
"validateSHA256",
):
content = (
"const downloadPath = await tc.downloadTool(url)\n"
f"await {func_name}(checksum, downloadPath, arch, platform, version)\n"
)
assert self._has_verification(content) is True, func_name

def test_validate_checksum_real_setup_uv_snippet_recognized(self):
# Faithful trim of the real download → validate sequence so the
# regression is anchored to the actual source, not just the bare name.
content = """\
import * as tc from "@actions/tool-cache";
import { validateChecksum } from "./checksum/checksum";

const downloadPath = await tc.downloadTool(
downloadUrl,
undefined,
githubToken,
);
await validateChecksum(checksum, downloadPath, arch, platform, version);
"""
assert self._has_verification(content) is True

def test_verify_hash_function_recognized(self):
# Whether named ``verifyHash`` or referenced inline.
for snippet in (
Expand Down
13 changes: 13 additions & 0 deletions utils/verify_action_build/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,19 @@ def analyze_action_metadata(
re.compile(r"\bcalculate(?:SHA[\d]+|Checksum|Digest)\b", re.IGNORECASE),
re.compile(r"\bverifyHash\b"),
re.compile(r"\bcomputeChecksum\b"),
# ``validate*`` checksum helpers — the call site counts as verification
# even when the helper's implementation lives in a sibling module.
# astral-sh/setup-uv's ``src/download/download-version.ts`` downloads via
# ``tc.downloadTool`` then immediately calls ``validateChecksum(checksum,
# downloadPath, …)`` (imported from ``./checksum/checksum``), which SHA-256s
# the artifact against a provided checksum or the built-in KNOWN_CHECKSUMS
# table. v8.2.0 extracted that validation into the sibling module, moving
# the ``createHash`` token out of this file and tripping the same-file
# heuristic — the call name is the evidence that survives the refactor.
re.compile(
r"\bvalidate(?:Checksum|Hash|Digest|SHA\d*|FileChecksum)\b",
re.IGNORECASE,
),
]

_JS_SOURCE_EXTENSIONS = (".ts", ".js", ".mjs", ".cjs")
Expand Down