Skip to content

Splice line continuations before scanning, and self-test the guard - #154

Merged
kwsantiago merged 1 commit into
mainfrom
fix-guard-splice
Aug 2, 2026
Merged

Splice line continuations before scanning, and self-test the guard#154
kwsantiago merged 1 commit into
mainfrom
fix-guard-splice

Conversation

@kwsantiago

@kwsantiago kwsantiago commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

A backslash-newline inside an identifier walked straight past the scanner. Splices continuations before matching, and adds scripts/test-rng-hygiene.sh so the rules are asserted rather than assumed.

The bypass

void f(void){ adc_oneshot\
_new_unit(); }

That is legal C. Translation phase 2 removes the backslash-newline before tokenization, so the compiler sees adc_oneshot_new_unit() while the guard, matching per physical line, sees adc_oneshot\ and _new_unit(); and matches neither.

Verified against a positive control that does fail:

probe before after
esp_wifi_start(); (control) caught caught
identifier split by a continuation passed caught
identifier split across three lines passed caught

Why this rule in particular

It defeats rule 5, the one forbidding anything that contends for the SAR ADC. That rule is the enforcement behind the v0.2.1 entropy fix: bootloader_random_enable() shares the SAR ADC, so a driver taking it back silently returns the device to the pseudo-random state that shipped in v0.1.0 through v0.2.0, with every health indicator still green. The whole point of that release was that the failure is invisible from the output, which is why the guard has to be the thing that catches it.

Macro aliasing was tested too and is not a bypass: #define WIFI_UP esp_wifi_start puts the banned token on the #define line, which the scanner catches. Only the splice got through.

Findings still point at the right line

Splicing shifts FNR, so the finding is reported against startline, the first physical line of the spliced group. Confirmed: the two-line probe reports :2 where the identifier begins, the three-line probe reports :1.

The self-test

Ported from the pattern added in keep-node, including the two things that made it trustworthy there:

  • every reject case requires the guard to name the probe file, so a guard aborting for an unrelated reason is reported as WRONG REASON instead of being credited as a detection
  • the harness aborts if fewer than 10 files stage, so "scanned almost nothing" cannot look like a pass

Ten cases: seven rejections including both splice forms, bootloader_random_disable, a raw draw outside main/hw_entropy.c, libc PRNG and I2S contention; three acceptances covering ordinary code, a banned token in a comment, and one inside #if 0.

Probes stage into a throwaway GIT_INDEX_FILE, so the real index is untouched. The file does exist on disk while the guard runs, because the scanner reads bytes, and is removed on every path including the EXIT trap.

Test plan

  • Both splice forms now caught; clean tree still passes
  • Self-test 10/10 on the fixed guard
  • Regression control: against the pre-fix guard it reports 2 BYPASS and exits 1, so it detects the defect rather than passing regardless
  • Line numbers verified to point at the first physical line of a spliced group
  • bash -n clean on both scripts, workflow parses, dependency-pin guard still passes
  • CI

Not claimed: this closes a known evasion, it does not make a line-oriented scanner undefeatable. What changed is that this route is closed and every known route is now asserted on each run.

Summary by CodeRabbit

  • Bug Fixes

    • Improved RNG hygiene diagnostics for code split across continued lines, reporting the starting line accurately.
  • Tests

    • Added comprehensive self-tests covering prohibited randomness patterns, comments, disabled code, and valid code.
  • Chores

    • Integrated RNG hygiene self-tests into the automated validation workflow.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The RNG hygiene guard now joins continued lines before scanning and reports their starting line. A Bash self-test covers rejection and acceptance cases. CI runs the self-test before the existing hygiene check.

Changes

RNG Hygiene Validation

Layer / File(s) Summary
Logical-line preprocessing
scripts/check-rng-hygiene.sh
The guard splices backslash-continued lines and preserves the first physical line for diagnostics.
Guard self-test harness
scripts/test-rng-hygiene.sh
The harness stages temporary probes in an isolated Git index and tests banned patterns, comments, inactive code, diagnostics, cleanup, and aggregate status.
CI self-test integration
.github/workflows/rng-hygiene.yml
The workflow runs the self-test before the existing fallback check.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Poem

A rabbit checks each random trace,
With probes lined up in a tidy space.
Split lines join, then warnings call,
CI guards the garden wall.
“All clear!” the small ears say.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two primary changes: line-continuation splicing and a self-test for the RNG hygiene guard.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-guard-splice

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
scripts/test-rng-hygiene.sh (1)

81-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the exact reported line, not just the filename.

run_probe for probe_splice.c and probe_splice3.c only checks that the guard's output names the file. It does not check that the guard reports the first physical line, which is the specific behavior this PR fixes (startline in check-rng-hygiene.sh). A guard that regresses to reporting the last physical line of a spliced identifier would still pass these two cases.

Add an assertion that checks for the exact file:line: prefix in the fail branch for these two probes.

♻️ Proposed tightening (illustrative; adapt to run_probe's structure)
 run_probe main/probe_splice.c 'void f(void){ adc_oneshot\
 _new_unit(); }
 ' fail "identifier split by a line continuation"
+# Also verify the report points at the first physical line (line 1), not the
+# continuation line, e.g. by checking $out for "main/probe_splice.c:1:".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/test-rng-hygiene.sh` around lines 81 - 88, Update the fail-case
assertions for the probe_splice.c and probe_splice3.c run_probe calls in the
test script to require the guard output’s exact file:line: prefix for the first
physical line of each spliced identifier, rather than only matching the
filename. Preserve the existing failure expectations and use run_probe’s
established output-matching mechanism.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@scripts/test-rng-hygiene.sh`:
- Around line 81-88: Update the fail-case assertions for the probe_splice.c and
probe_splice3.c run_probe calls in the test script to require the guard output’s
exact file:line: prefix for the first physical line of each spliced identifier,
rather than only matching the filename. Preserve the existing failure
expectations and use run_probe’s established output-matching mechanism.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a98b793-2f8d-4d72-9a67-a377091a479f

📥 Commits

Reviewing files that changed from the base of the PR and between 699d74c and 71acc1b.

📒 Files selected for processing (3)
  • .github/workflows/rng-hygiene.yml
  • scripts/check-rng-hygiene.sh
  • scripts/test-rng-hygiene.sh

@kwsantiago
kwsantiago merged commit 3548ee6 into main Aug 2, 2026
12 checks passed
@kwsantiago
kwsantiago deleted the fix-guard-splice branch August 2, 2026 17:42
@coderabbitai coderabbitai Bot mentioned this pull request Aug 2, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant