fix(file-ops): base64-encode binary sample to avoid UTF-8 truncation false positive - #80864
Closed
8696 wants to merge 1 commit into
Closed
fix(file-ops): base64-encode binary sample to avoid UTF-8 truncation false positive#808648696 wants to merge 1 commit into
8696 wants to merge 1 commit into
Conversation
…false positive `_is_likely_binary` samples the first 1000 bytes via `head -c 1000`. On files with high-density multi-byte UTF-8 (e.g. CJK text), the byte boundary cut splits a character mid-sequence. The terminal env decodes stdout with `errors="replace"`, turning the orphaned lead byte into U+FFFD. The old detector treated any U+FFFD in the sample as proof of a non-UTF-8 file and returned `is_binary=True` -- blocking legitimate text files from being read. Root cause: the sampling layer (`head -c` at byte level) and the detection layer (`_is_likely_binary` at character level) are connected by `errors="replace"` decoding, which destroys the distinction between truncation-induced U+FFFD and genuine non-UTF-8 bytes. Fix: - Pipe the sample through `base64` so raw bytes survive the terminal env lossless. b64decode on the Python side recovers exact bytes. - Rewrite `_is_likely_binary` to accept `bytes` instead of `str`: try strict UTF-8 decode, peeling 1-3 trailing bytes to handle truncation at a multi-byte boundary. If strict decode fails after peeling, the file is genuinely non-UTF-8 -> binary. If it succeeds, fall back to the non-printable ratio heuristic for NUL-heavy content. - No new dependencies (`base64` is stdlib; the `base64` shell command is coreutils, same package as `head` already in use). - No changes to any environment backend (local/ssh/docker/modal/etc.) or the `execute()`/`_run_bash()`/`_wait_for_process()` pipeline. Tests updated to match the new `bytes` signature and the `| base64` sample command.
Collaborator
Contributor
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.
Problem
_is_likely_binarysamples the first 1000 bytes viahead -c 1000. On files with high-density multi-byte UTF-8 (e.g. CJK text), the byte-boundary cut splits a character mid-sequence. The terminal env decodes stdout witherrors="replace", turning the orphaned lead byte into U+FFFD. The old detector treated any U+FFFD in the sample as proof of a non-UTF-8 file and returnedis_binary=True— blocking legitimate text files from being read.This is reproducible: a ~3.8 KB UTF-8 Chinese text file whose 1000th byte falls on a 3-byte character lead byte (0xe8) is consistently misidentified as binary.
Root Cause
The sampling layer (
head -cat byte level) and the detection layer (_is_likely_binaryat character level) are connected byerrors="replace"decoding, which destroys the distinction between truncation-induced U+FFFD and genuine non-UTF-8 bytes.Fix
base64so raw bytes survive the terminal env lossless.base64.b64decode()on the Python side recovers exact bytes._is_likely_binaryto acceptbytesinstead ofstr:Scope
base64is Python stdlib; thebase64shell command is coreutils (same package asheadalready in use).execute()/_run_bash()/_wait_for_process()pipeline.tools/file_operations.py), 1 test file updated to match the newbytessignature and| base64sample command.Verification
The previously misidentified file now correctly reads as text: