mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-07-06 15:15:47 +02:00
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 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 #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.
45 lines
1.7 KiB
JavaScript
45 lines
1.7 KiB
JavaScript
/* Copyright 2026 Mozilla Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { Font } from "../../src/core/fonts.js";
|
|
import { IdentityToUnicodeMap } from "../../src/core/to_unicode_map.js";
|
|
|
|
describe("Font", () => {
|
|
describe("encodeString", () => {
|
|
// `encodeString` only reads `this.toUnicode` and `this.cMap`, so a
|
|
// full `Font` (which needs a complete properties/font-file setup) isn't
|
|
// necessary to exercise it in isolation.
|
|
function encodeString(str, { cMap = null } = {}) {
|
|
const fakeFont = {
|
|
toUnicode: new IdentityToUnicodeMap(0, 0x10ffff),
|
|
cMap,
|
|
};
|
|
return Font.prototype.encodeString.call(fakeFont, str);
|
|
}
|
|
|
|
it("should keep the character after U+FFFE or U+FFFF", () => {
|
|
expect(encodeString("A")).toEqual(["\xffA"]);
|
|
expect(encodeString("B")).toEqual(["\xfeB"]);
|
|
});
|
|
|
|
it("should still treat a real surrogate pair as one code point", () => {
|
|
// U+1F602 ("😂") is genuinely represented by a surrogate pair; the
|
|
// character after it must still be kept, and the pair itself must
|
|
// not be split into its two unpaired halves.
|
|
expect(encodeString("😂C")).toEqual(["\x02C"]);
|
|
});
|
|
});
|
|
});
|