Skip to content

fix: prevent out-of-bounds read in UNICHAR::UTF8ToUTF32 - #4609

Open
SomSamantray wants to merge 4 commits into
tesseract-ocr:mainfrom
SomSamantray:fix/utf8to32-oob-read
Open

fix: prevent out-of-bounds read in UNICHAR::UTF8ToUTF32#4609
SomSamantray wants to merge 4 commits into
tesseract-ocr:mainfrom
SomSamantray:fix/utf8to32-oob-read

Conversation

@SomSamantray

Copy link
Copy Markdown

UNICHAR::UTF8ToUTF32 no longer reads past the end of a string that ends with a truncated multibyte UTF-8 prefix. Previously, a string like "\xE8\0" made the iterator advance past the NUL terminator and read one byte out of bounds (a stack/global buffer overflow depending on where the input lives). Such input now returns an empty vector, matching the documented "empty on invalid UTF-8" contract.

The fix clamps the per-character step to the number of bytes remaining before the end of the string, rejecting a truncated trailing sequence before any dereference.

Validation

  • Added UnicharTest.TruncatedUtf8 covering 2/3/4-byte truncated prefixes, a mid-string truncated prefix, and an illegal leading continuation byte.
  • The new test triggers the out-of-bounds read on unfixed code under AddressSanitizer (global-buffer-overflow in utf8_step) and passes after the fix.
  • unichar_test passes 3/3 in both ASan and non-ASan builds; related normstrngs_test (17 pass) and unicharset_test (4 pass) are unaffected under ASan.

Fixes #4495

Adds UnicharTest.TruncatedUtf8 covering 2/3/4-byte truncated prefixes,
a mid-string truncated prefix, and an illegal leading continuation byte.
The test triggers the out-of-bounds read in UNICHAR::UTF8ToUTF32 on
unfixed code (issue tesseract-ocr#4495).
utf8_step() reports the full multibyte width from the leading byte
alone, so a truncated prefix (e.g. "\xE8\0") made the iterator read
one byte past the end of the string. Clamp the per-character step to
the remaining bytes and return an empty vector for truncated input.

Fixes tesseract-ocr#4495.
Reword the comment to describe the rejection behavior accurately
(reject a truncated trailing sequence) rather than "clamping", per
code review feedback.
@codacy-production

codacy-production Bot commented Aug 20, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Comment thread unittest/unichar_test.cc
@stweil

stweil commented Aug 25, 2026

Copy link
Copy Markdown
Member

Please mention if you used an AI assistant in the commit messages. See Git history for examples how to do this.

@SomSamantray

Copy link
Copy Markdown
Author

Please mention if you used an AI assistant in the commit messages.

Already addressed in commit 4f3590e (test: explain truncated UTF-8 terminators (AI-assisted)).

Copilot AI 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.

Pull request overview

Prevents out-of-bounds reads when converting truncated UTF-8 sequences.

Changes:

  • Rejects multibyte sequences exceeding the remaining input length.
  • Adds regression tests for truncated and illegal UTF-8 prefixes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/ccutil/unichar.cpp Adds bounds validation before decoding.
unittest/unichar_test.cc Adds regression coverage for malformed UTF-8.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

Out-of-bounds read in UNICHAR::UTF8ToUTF32

3 participants