Skip to content

fix: t:utf8toUnicode drops the last hex digit of code points above U+FFFF - #3685

Open
fzipi wants to merge 1 commit into
owasp-modsecurity:v2/masterfrom
fzipi:v2/issue-3684-utf8tounicode-truncation
Open

fzipi wants to merge 1 commit into
owasp-modsecurity:v2/masterfrom
fzipi:v2/issue-3684-utf8tounicode-truncation

Conversation

@fzipi

@fzipi fzipi commented Oct 13, 2026

Copy link
Copy Markdown
Collaborator

Proposed changes

Fixes #3684. Related to #1211 (the 4-vs-6 digit output ambiguity, which this PR does not change).

Since the refactor in #3284 (first released in 2.9.9) utf8_unicode_inplace_ex() always advanced the output pointer by six bytes after sprintf("%%u%04x"), so any code point above U+FFFF (five hex digits) lost its last digit to the next write or to the terminating NUL: U+1F600 came out as %u1f60. The pointer now advances by what sprintf() actually wrote.

Two adjacent checks in the same function are fixed as well:

  • bytes_left was never decremented, so the "enough bytes left" guards compared against the total input length instead of the remaining length, and a truncated sequence at the end of the value was examined past input_len (bounded in practice by the NUL that terminates variable values, but wrong).
  • An 0xF4 lead byte with a second byte >= 0x90 (U+110000 and above, outside Unicode) was accepted as a valid four-byte sequence; it is now passed through like any other invalid sequence.

Output is otherwise unchanged, including the pre-existing handling of a NUL byte (%u00xx from #3284) and of the BMP.

Tests

tests/tfn/utf8toUnicode.t had no four-byte input at all. Four cases are added: supplementary-plane characters, a four-byte character followed by ASCII, a sequence above U+10FFFF, and a truncated sequence at the end of the input. Against the unmodified v2/master source the first three fail (Passed: 8; Failed: 3); with this patch all 11 pass and make test is green (macOS, Apache 2.4 from Homebrew, PCRE2 10.49). The function was also exercised standalone under AddressSanitizer with the same inputs.

🤖 Generated with Claude Code

…FFFF

Since the refactor in owasp-modsecurity#3284 (2.9.9) the output pointer always advanced
by six bytes after sprintf("%%u%04x"), so a code point that needs five
hex digits (anything above U+FFFF) lost its last digit to the next write
or to the terminating NUL: U+1F600 came out as "%u1f60". Advance by the
number of bytes sprintf actually wrote.

While there, fix two adjacent checks in the same function: bytes_left
was never decremented, so the "enough bytes left" guards compared the
total length instead of the remaining length and a truncated sequence at
the end of the value was examined past input_len; and an 0xF4 lead byte
with a second byte >= 0x90 (U+110000 and above, outside Unicode) was
accepted as a valid four-byte sequence.

Add four-byte, above-U+10FFFF and truncated-sequence cases to the
utf8toUnicode unit tests, which had no four-byte input at all.

Fixes owasp-modsecurity#3684

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cq9GqRpB4wzTFnEUvQaUJg
@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 977e9388-ec34-4195-8b15-de63a4db138b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

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

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.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
D Maintainability Rating on New Code (required ≥ A)
D Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Comment thread apache2/msc_util.c Outdated

This branch has not been deployed

No deployments
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.

2 participants