From 7050a54a4e885d610c56a8a9c2d31f23973f1905 Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Fri, 8 Mar 2013 11:07:36 -0800 Subject: [PATCH] Use empty private dictionaries instead of removing them. --- src/fonts.js | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/fonts.js b/src/fonts.js index 5fbac58b1..b0b996c42 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -6140,10 +6140,19 @@ var CFFParser = (function CFFParserClosure() { } return { charStrings: charStrings, seacs: seacs }; }, + emptyPrivateDictionary: + function CFFParser_emptyPrivateDictionary(parentDict) { + var privateDict = this.createDict(CFFPrivateDict, [], + parentDict.strings); + parentDict.setByKey(18, [0, 0]); + parentDict.privateDict = privateDict; + }, parsePrivateDict: function CFFParser_parsePrivateDict(parentDict) { // no private dict, do nothing - if (!parentDict.hasName('Private')) + if (!parentDict.hasName('Private')) { + this.emptyPrivateDictionary(parentDict); return; + } var privateOffset = parentDict.getByName('Private'); // make sure the params are formatted correctly if (!isArray(privateOffset) || privateOffset.length !== 2) { @@ -6154,7 +6163,7 @@ var CFFParser = (function CFFParserClosure() { var offset = privateOffset[1]; // remove empty dicts or ones that refer to invalid location if (size === 0 || offset >= this.bytes.length) { - parentDict.removeByName('Private'); + this.emptyPrivateDictionary(parentDict); return; } @@ -6172,7 +6181,7 @@ var CFFParser = (function CFFParserClosure() { var relativeOffset = offset + subrsOffset; // Validate the offset. if (subrsOffset === 0 || relativeOffset >= this.bytes.length) { - privateDict.removeByName('Subrs'); + this.emptyPrivateDictionary(parentDict); return; } var subrsIndex = this.parseIndex(relativeOffset); @@ -6853,15 +6862,23 @@ var CFFCompiler = (function CFFCompilerClosure() { output) { for (var i = 0, ii = dicts.length; i < ii; ++i) { var fontDict = dicts[i]; - if (!fontDict.privateDict || !fontDict.hasName('Private')) - continue; + assert(fontDict.privateDict && fontDict.hasName('Private'), + 'There must be an private dictionary.'); var privateDict = fontDict.privateDict; var privateDictTracker = new CFFOffsetTracker(); var privateDictData = this.compileDict(privateDict, privateDictTracker); - privateDictTracker.offset(output.length); + var outputLength = output.length; + privateDictTracker.offset(outputLength); + if (!privateDictData.length) { + // The private dictionary was empty, set the output length to zero to + // ensure the offset length isn't out of bounds in the eyes of the + // sanitizer. + outputLength = 0; + } + trackers[i].setEntryLocation('Private', - [privateDictData.length, output.length], + [privateDictData.length, outputLength], output); output.add(privateDictData);