镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Strip a leading byte order mark once, not twice, for an encoding with a preamble [patch] - #147

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/strip-one-bom-145
Nov 10, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/strip-one-bom-145

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #145

What was wrong

AsyncProcessStreamReader builds its readers with detectEncodingFromByteOrderMarks: false and then removes one leading U+FEFF itself in StripLeadingByteOrderMark. But StreamReader skips the encoding's own preamble whatever that flag says. So for an encoding with a preamble, which includes Encoding.UTF8 (the OutputHandler default) and Encoding.Unicode, the reader dropped the BOM and the manual strip then dropped a real U+FEFF after it. EF BB BF EF BB BF 41 came out as A through Encoding.UTF8 but as A through new UTF8Encoding(false).

What changed

The fix uses the first option the issue suggests. The manual strip now runs only when outputHandler.Encoding.GetPreamble() is empty, which is the only case where the reader leaves the BOM in place. Either way, exactly one BOM is removed. The doc comment on StripLeadingByteOrderMark and the field's comment explain why.

Tests

Two new data-driven tests cover Encoding.UTF8, new UTF8Encoding(false), Encoding.Unicode and new UnicodeEncoding(false, false):

  • OnlyTheByteOrderMarkIsStrippedWhenARealU_FEFFFollowsIt: BOM + U+FEFF + A delivers FEFF 0041 for every encoding. It asserts on code points, so the kept U+FEFF is visible in a failure. That is the issue's "both deliver A", read literally: the BOM goes and the real U+FEFF stays.
  • ALoneByteOrderMarkIsStrippedWhicheverEncodingReadsIt: a single BOM + hello delivers hello for every encoding. This guards against overcorrecting into stripping nothing.

Before the fix, the doubled-BOM test failed for Encoding.UTF8 and Encoding.Unicode, the two encodings with a preamble, and passed for the other two. After the fix, the full suite passes on net10.0 / Linux: 98 passed, 0 failed, 2 elevation tests skipped as usual. The existing single-BOM test from #76 still passes.


Generated by Claude Code

… a preamble [patch]

StreamReader skips the encoding's own preamble whatever detectEncodingFromByteOrderMarks
says, and AsyncProcessStreamReader then dropped a leading U+FEFF from the first chunk as well.
For Encoding.UTF8 (OutputHandler's default), Encoding.Unicode and the other encodings with a
preamble, output starting with a BOM followed by a real U+FEFF lost both, so the same bytes
decoded differently through Encoding.UTF8 and new UTF8Encoding(false).

The manual strip now runs only for an encoding with no preamble, where the reader leaves the
BOM in place.

Fixes #145

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW45a4XVwC8wG7P95kY
@sonarqubecloud

sonarqubecloud Bot commented Nov 8, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants