fix: avoid splitting UTF-8 characters during charset detection - #2466
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The implementation is bounded, preserves existing fallback behavior, and has comprehensive focused tests.
Pull request overview
Prevents charset detection from misclassifying valid UTF-8 when the 64 KiB sample splits a multibyte character.
Changes:
- Completes trailing UTF-8 characters with bounded lookahead.
- Adds boundary, invalid-input, stream-position, and explicit-charset tests.
File summaries
| File | Description |
|---|---|
packages/markitdown/src/markitdown/_markitdown.py |
Safely completes UTF-8 charset samples. |
packages/markitdown/tests/test_charset_sample.py |
Covers sampling behavior and regressions. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Charset detection samples the first 64 KiB of text input. If that boundary falls inside a multibyte UTF-8 character, the truncated sample can be mistaken for another encoding. Applying that guess to the full document can silently corrupt valid text—for example, turning résumé into rĂ©sumĂ© —or cause conversion to fail.
This change completes a trailing UTF-8 character before passing the sample to charset_normalizer :
• Use a strict incremental decoder to distinguish a split character from invalid UTF-8.
• Read at most three additional bytes, stopping as soon as the character is complete.
• Preserve the original sample if the prefix or continuation is invalid, or EOF prevents completion.
The existing charset detector still selects the encoding; the fix does not force UTF-8, discard bytes, or override an explicitly supplied charset. Stream-position restoration remains unchanged.
This is a narrow mitigation for sample-boundary splitting. It does not address other encoding-detection limitations, such as non-ASCII content appearing entirely beyond an ASCII-only sample.