Skip to content

Track libinjection 4.0.1 - #7

Merged
ndreno merged 1 commit into
mainfrom
feat/libinjection-v4.0.1
Nov 3, 2026
Merged

ndreno merged 1 commit into
mainfrom
feat/libinjection-v4.0.1

Conversation

@ndreno

@ndreno ndreno commented Nov 3, 2026 •

Copy link
Copy Markdown

Moves the libinjection-c submodule from 85e252a (2025-02-28, the commit pinned in the initial port) to v4.0.1, and ports the detection changes in between.

Why

The pin was 87 upstream commits behind. CI checks out the pinned commit, so the differential test and the fuzz campaign were comparing the port against February 2025 C code. Upstream issue 90 (an over-read in html_decode_char_at) turned out to be already fixed in 4.0.0.

What changed upstream, and what the port does

Upstream change (85e252a..v4.0.1) Port
parse_number: 1.e / 10.E with no exponent digits assigns no token (was a bareword) Ported in sqli/tokenizer.rs
Fold: LIKE ( is a function only when it does not follow a number, string, bareword, variable or ) (upstream PR 94) Ported in sqli/mod.rs
h5_skip_white reads bytes unsigned, so 0xFF is no longer CHAR_EOF (upstream PR 93) Ported in xss/html5.rs (Option<u8>, None = EOF)
BLACKATTREVENT: 145 names added, 11 removed, re-sorted Regenerated from v4.0.1 source, same order (432 entries)
html_decode_char_at: len < 3 || (hex && len < 4) guard (the issue 90 fix) Restructured to mirror it. No verdict change: Rust slices never read past the value
is_black_attr: on* compare capped at min(len - 2, strlen(name)) Mirrored with an explicit min. No verdict change, same reason
injection_result_t / LIBINJECTION_RESULT_ERROR, asserts replaced by error returns Not mirrored: C returns ERROR only for NULL pointers and broken parser invariants, which Rust types rule out
sqlparse_data.json regenerated Whitespace only (keywords, charmap and fingerprints identical, same order), so no generated-data change

Tests

  • Upstream's own test files caught the SQLi changes before porting: test-tokens-numbers-exp-001/009-012, test-folding-099/100/119 failed, and pass after.
  • Nothing upstream covers the 0xFF change in a form the Rust suite reads (data/xss-github-92.txt has %FF, read literally). Added a tokenizer test mirroring upstream's test_error_handling.c; it fails with the pre-port html5.rs.
  • test_fuzz_differential_crash_472cde1c and test_fuzz_differential_8ce9746b asserted the old C verdict (Safe) for inputs with 0xFF. C 4.0.1 flags both; expectations updated, and both inputs are now also checked against the live C in comparison-bin.
  • nul_as_whitespace_in_html5_matches_the_c_library: its fuzz input now reaches a backtick comment after the 0xFF, so its verdict no longer depends on NUL handling. Added <a x=y\0onclick=alert(1)>, which fails when NUL is removed from the whitespace helpers, and kept the fuzz input with C's 4.0.1 verdict.
  • Locally: workspace tests pass (79), clippy passes, and the full differential reports 0 SQLi and 0 XSS divergences over 163,275 inputs.

Also

  • FFI harness: dropped the hard-coded -DLIBINJECTION_VERSION="3.10.0" (4.0.1 defines its own). The zero padding stays.
  • .github/dependabot.yml: weekly gitsubmodule updates, so upstream changes open a PR that the differential job runs against. Dependabot tracks upstream main, not release tags.
  • Two new clippy warnings, both on lines that follow the C structure: nonminimal_bool on !(have_e && !have_exp) and a range suggestion on the 0x0B | 0x0C | 0x0D case.

Note for consumers: detection changes in this version. More XSS is flagged (new event names, attributes after a 0xFF byte), and 1.e-style SQLi is now flagged.

The libinjection-c submodule had been pinned at 85e252a (2025-02-28) since the
initial port, 87 upstream commits behind v4.0.1. The differential test and the
fuzz campaign compared the port against that old C code, and libinjection
issue 90 reported an over-read that 4.0.0 had already fixed.

Port the detection changes since the pin:
- parse_number: "1.e" with no exponent digits assigns no token (was a bareword)
- fold: "LIKE (" is a function only when it does not follow an operand
- h5_skip_white: reads bytes unsigned, so 0xFF is no longer CHAR_EOF
- BLACKATTREVENT: regenerated from v4.0.1 (432 entries, C order)
- html_decode_char_at and the on* comparison mirror 4.0.1's length guards
  (no verdict change: the port never read past the slice)

The 4.0 error-code API (LIBINJECTION_RESULT_ERROR) is not mirrored: C returns
it only for NULL pointers and broken parser invariants, which Rust types rule
out.

Tests: two XSS fuzz tests asserted the old C verdict for 0xFF inputs; C 4.0.1
flags both, and they are now also checked against C in comparison-bin. The
NUL-as-whitespace differential used an input whose verdict no longer depends
on NUL; it now uses one that fails when NUL handling is removed, and keeps the
fuzz input. Add a 0xFF tokenizer test mirroring upstream's
test_error_handling.c.

Harness: drop the hard-coded LIBINJECTION_VERSION="3.10.0" (4.0.1 defines its
own). Add Dependabot for the submodule.

Corpus: 0 SQLi and 0 XSS divergences from C over 163,275 inputs.
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

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

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

@ndreno
ndreno marked this pull request as ready for review November 3, 2026 17:46
@ndreno
ndreno merged commit e52531b into main Nov 3, 2026
5 checks passed
@ndreno ndreno mentioned this pull request Nov 3, 2026
ndreno added a commit that referenced this pull request Nov 3, 2026
Bump the version to 0.1.2 and cut the changelog: the libinjection 4.0.1
move (#7), the low-byte entity comparison in htmlencode_startswith (87c1e8c,
which had no changelog entry), and Dependabot. The entries that shipped in
0.1.1 move under a 0.1.1 heading.
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