Skip to content

Preserve U+FEFF when Wtf8Decoder reads payload text - #65460

Open
Josué Barros (joshbarros) wants to merge 2 commits into
microsoft:mainfrom
joshbarros:fix/65458-wtf8-ignore-bom
Open

Josué Barros (joshbarros) wants to merge 2 commits into
microsoft:mainfrom
joshbarros:fix/65458-wtf8-ignore-bom

Conversation

@joshbarros

Copy link
Copy Markdown

Fixes #65458

Wtf8Decoder extends TextDecoder without ignoreBOM: true. TextDecoder removes U+FEFF from the start of a decode. This decoder also splits a buffer on a lone surrogate and decodes the following bytes as a new segment, so the same character is removed there.

A string or template value that starts with U+FEFF, or that has U+FEFF immediately after a lone surrogate, comes back from the API without that character. A U+FEFF in the middle of a segment stays. The input in the report has no file-level BOM. The Go filesystem reader already strips a UTF-8 BOM from source text before the compiler sees the file. This default restores the character inside payload text.

The WASM file decoder already constructed Wtf8Decoder with { ignoreBOM: true }. The constructor now defaults ignoreBOM to true. An explicit ignoreBOM: false still opts out.

The new test in packages/typescript/test/wtf8.test.ts covers a leading U+FEFF, a value that is only U+FEFF, U+FEFF after a lone surrogate, a middle U+FEFF, and the template value from the report.

node --conditions=@typescript/source --test ./test/wtf8.test.ts passed, 8 tests.

I also ran the report's async API script on typescript@7.1.0-dev.20261112.1. Before the change the code points were leading ["78"], only [], afterSurrogate ["d800"], middle ["61","feff","62"], template ["74","61","69","6c"]. With this constructor on that package's decoder, they are leading ["feff","78"], only ["feff"], afterSurrogate ["d800","feff"], middle ["61","feff","62"], template ["feff","74","61","69","6c"]. Node 22.19 cannot parse using in the local API sources, so that run used the published package. npx hereby test, npx hereby lint, and npx hereby check:format were not run. The issue has no Backlog milestone.

Drafted with assistance from Grok. I reviewed the diff and ran those tests.

TextDecoder drops a leading U+FEFF. Wtf8Decoder decodes each segment on
its own, so the character was lost at the start of a string, a template,
and the span after a lone surrogate. The constructor now defaults
ignoreBOM to true. Passing false still opts out.
Copilot AI balanced review requested due to automatic review settings November 12, 2026 22:22
@github-project-automation github-project-automation Bot moved this to Not started in PR Backlog Nov 12, 2026
@typescript-automation typescript-automation Bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Nov 12, 2026
@typescript-automation

Copy link
Copy Markdown
Contributor

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the change preserving U+FEFF during native TypeScript text decoding.

No open issues 🎉

What changed in this PR

Fixes #65458 by preserving U+FEFF in text decoded by the native TypeScript API, including literal values that begin with it or contain it immediately after a lone surrogate.

Changes:

  • Defaults Wtf8Decoder to ignoreBOM: true, while preserving explicit ignoreBOM: false behavior.
  • Adds regression coverage for leading, standalone, post-surrogate, middle, and template-text U+FEFF values.
File Description
packages/​typescript/​test/​wtf8.test.ts Adds U+FEFF preservation regression cases.
packages/​typescript/​src/​api/​node/​wtf8.ts Adds a constructor that preserves U+FEFF by default.

Review effort: Balanced

Review feedback: the decoder should always set ignoreBOM to true, so the
constructor no longer accepts decoder options. transport.ts no longer
passes the redundant option.
@joshbarros

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@joshbarros

Copy link
Copy Markdown
Author

This PR references #65458 (Fixes #65458 in the description), so it already has a linked issue.

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

For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

Native API: Wtf8Decoder drops U+FEFF from string literals and template text

3 participants