Skip to content

lint-skill.sh: blanket 'read ' substring exemption masks genuine cross-fence leaks on read lines #2491

Description

@carlos-alm

Discovered while addressing Greptile's review on PR #2490 (issue #2344).

lint-skill.sh's Check 1 (cross-fence variable usage) has a reference-checking exemption (currently around the [ ! "$line" == *'read '* ]-style condition guarding the error(...) call) meant to allow patterns like VAR=$(cat file) — genuinely re-deriving a value from a persisted file rather than relying on stale shell state from an earlier bash block.

read is included in that same exemption list, but as a blanket substring check on the whole line, not tied to whether the specific variable being referenced was actually the destination of that line's read. So a line that both (a) binds some unrelated variable via read and (b) separately references a different, genuinely-stale variable from an earlier block — e.g. a here-string interpolation — gets fully exempted, silently accepting a real cross-fence bug.

Repro (pre-existing on origin/main, independent of PR #2490's fix):

Block 1:

FOO=hello

Block 2:

read -r BAR <<< "$FOO"

$FOO here is a genuine cross-fence leak (block 2 relies on block 1's shell state, which does not persist across separate ```bash fences) but lint-skill.sh reports 0 errors, because the line contains the substring read (from read -r BAR), which trips the blanket exemption meant for cat/read-from-file patterns — even though this read's own destination is BAR, not FOO.

Root cause: the exemption is a per-line substring match (*'read '*) rather than checking whether the specific referenced variable is the one actually bound by that line's read/cat.

Not fixed as part of #2344/PR #2490 — that PR's scope was the assignment-registration side (recognizing read as a binding mechanism so genuine same-block rebindings aren't flagged); this is a separate, pre-existing false-negative in the reference-checking side, discovered via Greptile's review while verifying the #2344 fix didn't introduce it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    follow-upDeferred work from PR reviews that needs tracking

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions