From 4946bced254fee180ae4e9b43f23edd5cf107395 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Wed, 9 Sep 2020 18:39:14 +0200 Subject: [PATCH] PDF names need to be escaped when saving --- src/core/core_utils.js | 26 ++++++++++++++++++++++++++ src/core/writer.js | 3 ++- test/unit/core_utils_spec.js | 13 +++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/core/core_utils.js b/src/core/core_utils.js index 71c992d3fb68c8..c1091cfe27559c 100644 --- a/src/core/core_utils.js +++ b/src/core/core_utils.js @@ -165,7 +165,33 @@ function isWhiteSpace(ch) { return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a; } +function escapePDFName(str) { + const buffer = []; + let start = 0; + for (let i = 0, ii = str.length; i < ii; i++) { + const char = str.charCodeAt(i); + if (char < 0x21 || char > 0x7e || char === 0x23) { + if (start < i) { + buffer.push(str.substring(start, i)); + } + buffer.push(`#${char.toString(16)}`); + start = i + 1; + } + } + + if (buffer.length === 0) { + return str; + } + + if (start < str.length) { + buffer.push(str.substring(start, str.length)); + } + + return buffer.join(""); +} + export { + escapePDFName, getLookupTableFactory, MissingDataException, XRefEntryException, diff --git a/src/core/writer.js b/src/core/writer.js index 19442f5ea4933b..93eed4dd1108ae 100644 --- a/src/core/writer.js +++ b/src/core/writer.js @@ -23,6 +23,7 @@ import { import { Dict, isDict, isName, isRef, isStream, Name } from "./primitives.js"; import { SimpleDOMNode, SimpleXMLParser } from "../shared/xml_parser.js"; import { calculateMD5 } from "./crypto.js"; +import { escapePDFName } from "./core_utils.js"; function writeDict(dict, buffer, transform) { buffer.push("<<"); @@ -77,7 +78,7 @@ function numberToString(value) { function writeValue(value, buffer, transform) { if (isName(value)) { - buffer.push(`/${value.name}`); + buffer.push(`/${escapePDFName(value.name)}`); } else if (isRef(value)) { buffer.push(`${value.num} ${value.gen} R`); } else if (Array.isArray(value)) { diff --git a/test/unit/core_utils_spec.js b/test/unit/core_utils_spec.js index 315ab28aaa5f88..7c4162490cefb7 100644 --- a/test/unit/core_utils_spec.js +++ b/test/unit/core_utils_spec.js @@ -15,6 +15,7 @@ import { Dict, Ref } from "../../src/core/primitives.js"; import { + escapePDFName, getInheritableProperty, isWhiteSpace, log2, @@ -211,4 +212,16 @@ describe("core_utils", function () { expect(isWhiteSpace(undefined)).toEqual(false); }); }); + + describe("escapePDFName", function () { + it("should escape PDF name", function () { + expect(escapePDFName("hello")).toEqual("hello"); + expect(escapePDFName("\xfehello")).toEqual("#fehello"); + expect(escapePDFName("he\xfell\xffo")).toEqual("he#fell#ffo"); + expect(escapePDFName("\xfehe\xfell\xffo\xff")).toEqual( + "#fehe#fell#ffo#ff" + ); + expect(escapePDFName("#h#e#l#l#o")).toEqual("#23h#23e#23l#23l#23o"); + }); + }); });