fix(messagescan): guard inspects scan-helper call arguments

What this does

Hardens the internal/messagescan guard so it catches a registry-supplied value rendered into a failure message through redact.ScanContent alone.

Problem

isRegistryExpr classified an *ast.CallExpr by the call's own selector name. Only the string(x) conversion recursed into the call's arguments. So redact.ScanContent(herr.ContentType) was judged on ScanContent — not a registry selector — and read as clean; the argument herr.ContentType was never inspected.

The consequence: a bare-scan render site that interpolates a registry value through ScanContent on its own passes the guard. !283 closed every such site in pkg/conformance/{oci,maven,npm}, and the guard is what should stop the next one — but it could not see it. TestCase.Message is public API that a library consumer reads directly, so this is defence in depth.

Reported by @mkhalifa3 in !283 (merged) (note_3829912751).

Fix

Look through a scan-helper call to its arguments, the same way the walk already looks through a string() conversion. A new explicit scanHelpers list names redact's lower-level passes — ScanContent and RedactURLUserinfo — each of which returns a string derived from its argument but is not the message scrub, so a registry value handed to one directly still renders unscrubbed. The list is explicit for the same reason scrubWrappers is: a pass that renders its argument belongs there deliberately, because a call the walk cannot classify reads as clean.

The exclusion the issue calls for is preserved: a call that renders its own result rather than an argument (len(resp.Body) is an int, not the body) is not a scan helper, so it is judged on its own selector name and its arguments are not walked.

Blast radius: none

Running the hardened guard against the tree is green — !283 already routed every bare-scan render site in the three modules through scrubForMessage, so no render site needed changing in this MR. This is guard-logic only; no production code changes.

Testing

  • go test ./internal/messagescan/... passes.
  • Added TestIsRegistryExpr, a table test pinning the classifier: a registry value inside ScanContent / RedactURLUserinfo / string() is caught; scrubForMessage(...), len(resp.Body), and a non-registry selector are not.
  • Manually injected a temporary fmt.Sprintf(..., redact.ScanContent( herr.ContentType)) into the maven module and confirmed the guard fails on it, then that len(resp.Body) leaves it green.

Closes #81 (closed)

Edited by Jeston Singh

Merge request reports

Loading
Loading