Skip to content

Do not drop the character after U+FFFE or U+FFFF in Font.prototype.encodeString#21538

Merged
timvandermeij merged 1 commit into
mozilla:masterfrom
greymoth-jp:fix/font-encodeString-fffe-fffff
Jul 5, 2026
Merged

Do not drop the character after U+FFFE or U+FFFF in Font.prototype.encodeString#21538
timvandermeij merged 1 commit into
mozilla:masterfrom
greymoth-jp:fix/font-encodeString-fffe-fffff

Conversation

@greymoth-jp

Copy link
Copy Markdown
Contributor

Font.prototype.encodeString has the same surrogate-pair guard that encodeToXmlString had before #21526: unicode > 0xd7ff && (unicode < 0xe000 || unicode > 0xfffd). That predicate is also true for U+FFFE and U+FFFF, which are single UTF-16 code units, not surrogate pairs. The extra i++ then steps over the character that follows them, so it gets silently dropped from the font-encoded output used when saving or printing a PDF.

Same fix as #21526: the correct test for a real surrogate pair is unicode > 0xffff, since codePointAt only returns a value at or above 0x10000 for an actual pair. This keeps the existing behavior for real surrogate pairs (emoji, supplementary-plane CJK, etc.) and the U+FFFD boundary, and only stops the character after U+FFFE/U+FFFF from being dropped.

Font.prototype.encodeString didn't have a direct unit test, so I added test/unit/fonts_spec.js. It calls the method on a minimal fake this (only toUnicode/cMap are read by this method), since building a full Font needs a complete properties/font-file setup that this bug doesn't depend on.

Verified locally: reverting only the fonts.js fix (keeping the new tests) turns the new test red (the encoded output is missing the trailing character), confirming the test catches the bug; with the fix it's green. A full test/unit run (skipping api_spec/pdf_spec/the two specs that need downloaded reference PDFs, unavailable in my sandbox) is unaffected: same 8 pre-existing environment-only failures and 15 pending specs as an unmodified checkout, before and after this change. eslint/prettier --check are clean on the touched files.

…codeString

encodeString has the same surrogate-pair guard that encodeToXmlString had
before mozilla#21526: `unicode > 0xd7ff && (unicode < 0xe000 || unicode > 0xfffd)`.
That predicate is also true for U+FFFE and U+FFFF, which are single UTF-16
code units, not surrogate pairs. The extra `i++` then steps over the
character that follows them, so it is silently dropped from the
font-encoded output used when saving or printing a PDF.

For example, encoding a string that is U+FFFF followed by "A", with a font
that has a glyph for both, returns an encoded result ending in "A" on this
branch but drops the "A" on master.

Same fix as mozilla#21526: the correct test for a real surrogate pair is
`unicode > 0xffff`, since codePointAt only returns a value at or above
0x10000 for an actual pair. This keeps existing behavior for real surrogate
pairs (e.g. emoji) and the U+FFFD boundary, and only stops the character
after U+FFFE/U+FFFF from being dropped.

Added test/unit/fonts_spec.js, since Font.prototype.encodeString had no
direct unit test. It calls the method on a minimal fake `this` (only
toUnicode/cMap are read), since building a full Font requires a complete
properties/font-file setup that this bug doesn't depend on.
@codecov-commenter

codecov-commenter commented Jul 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.40%. Comparing base (36835d9) to head (2bbf32d).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #21538   +/-   ##
=======================================
  Coverage   89.40%   89.40%           
=======================================
  Files         262      262           
  Lines       66739    66739           
=======================================
+ Hits        59668    59670    +2     
+ Misses       7071     7069    -2     
Flag Coverage Δ
browsertest 66.52% <100.00%> (+0.01%) ⬆️
fonttest 9.05% <0.00%> (ø)
integrationtest 68.73% <100.00%> (+<0.01%) ⬆️
unittest 57.33% <100.00%> (+0.02%) ⬆️
unittestcli 56.30% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@timvandermeij timvandermeij left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good, with passing browser tests. Thank you for your contribution!

@timvandermeij

Copy link
Copy Markdown
Collaborator

/botio browsertest

@moz-tools-bot

Copy link
Copy Markdown
Collaborator

From: Bot.io (Linux m4)


Received

Command cmd_browsertest from @timvandermeij received. Current queue size: 0

Live output at: http://54.241.84.105:8877/a905df14e884ce2/output.txt

@moz-tools-bot

Copy link
Copy Markdown
Collaborator

From: Bot.io (Windows)


Received

Command cmd_browsertest from @timvandermeij received. Current queue size: 0

Live output at: http://54.193.163.58:8877/82ba69d71c84aa9/output.txt

@moz-tools-bot

Copy link
Copy Markdown
Collaborator

From: Bot.io (Linux m4)


Failed

Full output at http://54.241.84.105:8877/a905df14e884ce2/output.txt

Total script time: 0.75 mins

  • Regression tests: FAILED

Image differences available at: http://54.241.84.105:8877/a905df14e884ce2/reftest-analyzer.html#web=eq.log

@timvandermeij

Copy link
Copy Markdown
Collaborator

/botio-linux browsertest

@moz-tools-bot

Copy link
Copy Markdown
Collaborator

From: Bot.io (Linux m4)


Received

Command cmd_browsertest from @timvandermeij received. Current queue size: 0

Live output at: http://54.241.84.105:8877/f5b121af177a719/output.txt

@moz-tools-bot

Copy link
Copy Markdown
Collaborator

From: Bot.io (Linux m4)


Failed

Full output at http://54.241.84.105:8877/f5b121af177a719/output.txt

Total script time: 19.39 mins

  • Regression tests: FAILED
  errors: 6

Image differences available at: http://54.241.84.105:8877/f5b121af177a719/reftest-analyzer.html#web=eq.log

@moz-tools-bot

Copy link
Copy Markdown
Collaborator

From: Bot.io (Windows)


Success

Full output at http://54.193.163.58:8877/82ba69d71c84aa9/output.txt

Total script time: 25.53 mins

  • Regression tests: Passed

@timvandermeij timvandermeij merged commit e148b15 into mozilla:master Jul 5, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants