Skip to content

Commit 7041c62

Browse files
committed
Remove non-displayable chars from outline title (mozilla#14267)
- it aims to fix mozilla#14267; - there is nothing about chars in range [0-1F] in the specs but acrobat doesn't display them in any way.
1 parent 7d6d3fc commit 7041c62

File tree

6 files changed

+38
-3
lines changed

6 files changed

+38
-3
lines changed

src/shared/util.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -566,16 +566,20 @@ class AbortException extends BaseException {
566566
}
567567
}
568568

569-
const NullCharactersRegExp = /\x00/g;
569+
const NullCharactersRegExp = /\x00+/g;
570+
const InvisibleCharactersRegExp = /[\x01-\x1F]/g;
570571

571572
/**
572573
* @param {string} str
573574
*/
574-
function removeNullCharacters(str) {
575+
function removeNullCharacters(str, replaceInvisible = false) {
575576
if (typeof str !== "string") {
576577
warn("The argument for removeNullCharacters must be a string.");
577578
return str;
578579
}
580+
if (replaceInvisible) {
581+
str = str.replace(InvisibleCharactersRegExp, " ");
582+
}
579583
return str.replace(NullCharactersRegExp, "");
580584
}
581585

test/pdfs/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,4 @@
486486
!pr12828.pdf
487487
!secHandler.pdf
488488
!rc_annotation.pdf
489+
!issue14267.pdf

test/pdfs/issue14267.pdf

4.32 KB
Binary file not shown.

test/unit/api_spec.js

+13
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,19 @@ describe("api", function () {
11021102
await loadingTask.destroy();
11031103
});
11041104

1105+
it("gets outline with non-displayable chars", async function () {
1106+
const loadingTask = getDocument(buildGetDocumentParams("issue14267.pdf"));
1107+
const pdfDoc = await loadingTask.promise;
1108+
const outline = await pdfDoc.getOutline();
1109+
expect(Array.isArray(outline)).toEqual(true);
1110+
expect(outline.length).toEqual(1);
1111+
1112+
const outlineItem = outline[0];
1113+
expect(outlineItem.title).toEqual("hello\x11world");
1114+
1115+
await loadingTask.destroy();
1116+
});
1117+
11051118
it("gets non-existent permissions", async function () {
11061119
const permissions = await pdfDocument.getPermissions();
11071120
expect(permissions).toEqual(null);

test/unit/util_spec.js

+12
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ describe("util", function () {
185185
const str = "string\x00With\x00Null\x00Chars";
186186
expect(removeNullCharacters(str)).toEqual("stringWithNullChars");
187187
});
188+
189+
it("should modify string with non-displayable characters", function () {
190+
const str = Array.from(Array(32).keys())
191+
.map(x => String.fromCharCode(x) + "a")
192+
.join("");
193+
// \x00 is replaced by an empty string.
194+
const expected =
195+
"a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a";
196+
expect(removeNullCharacters(str, /* replaceInvisible */ true)).toEqual(
197+
expected
198+
);
199+
});
188200
});
189201

190202
describe("ReadableStream", function () {

web/base_tree_viewer.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ class BaseTreeViewer {
5959
* @private
6060
*/
6161
_normalizeTextContent(str) {
62-
return removeNullCharacters(str) || /* en dash = */ "\u2013";
62+
// Chars in range [0x01-0x1F] will be replaced with a white space
63+
// and 0x00 by "".
64+
return (
65+
removeNullCharacters(str, /* replaceInvisible */ true) ||
66+
/* en dash = */ "\u2013"
67+
);
6368
}
6469

6570
/**

0 commit comments

Comments
 (0)