]> git.parisson.com Git - pdf.js.git/commitdiff
Prevent the deprecated 'dotsection' command in Type1C to hit the sanitizer
authorVivien Nicolas <21@vingtetun.org>
Sun, 11 Sep 2011 13:23:35 +0000 (15:23 +0200)
committerVivien Nicolas <21@vingtetun.org>
Sun, 11 Sep 2011 13:23:35 +0000 (15:23 +0200)
fonts.js
utils/cffStandardStrings.js
utils/fonts_utils.js

index cc353c03b3d5cca1ea2a0f13628fa0f57269b95f..e10007c9400c1c6a13fbc919e040c38a35663bca 100755 (executable)
--- a/fonts.js
+++ b/fonts.js
@@ -2251,7 +2251,7 @@ var Type2CFF = (function() {
 
       var strings = this.getStrings(stringIndex);
 
-      var baseDict = this.parseDict(dictIndex.get(0));
+      var baseDict = this.parseDict(dictIndex.get(0).data);
       var topDict = this.getTopDict(baseDict, strings);
 
       var bytes = this.bytes;
@@ -2276,6 +2276,33 @@ var Type2CFF = (function() {
       if (hasSupplement)
         bytes[topDict.Encoding] = 0;
 
+      // The CFF specification state that the 'dotsection' command
+      // (12, 0) is deprecated and treated as a no-op, but all Type2
+      // charstrings processors should support them. Unfortunately
+      // the font sanitizer don't. As a workaround the sequence (12, 0)
+      // is replaced by a useless (0, hmoveto).
+      var count = charStrings.length;
+      for (var i = 0; i < count; i++) {
+        var charstring = charStrings.get(i);
+
+        var start = charstring.start;
+        var data = charstring.data;
+        var length = data.length;
+        for (var j = 0; j <= length; j) {
+          var value = data[j++];
+          if (value == 12 && data[j++] == 0) {
+              bytes[start + j - 2] = 139;
+              bytes[start + j - 1] = 22;
+          } else if (value === 28) {
+            j += 2;
+          } else if (value >= 247 && value <= 254) {
+            j++;
+          } else if (value == 255) {
+            j += 4;
+          }
+        }
+      }
+
       // charstrings contains info about glyphs (one element per glyph
       // containing mappings for {unicode, width})
       var charstrings = this.getCharStrings(charset, charStrings,
@@ -2566,7 +2593,7 @@ var Type2CFF = (function() {
         } else if (value <= 254) {
           return -((value - 251) * 256) - dict[pos++] - 108;
         } else {
-          error('Incorrect byte');
+          error('255 is not a valid DICT command');
         }
         return -1;
       };
@@ -2644,7 +2671,11 @@ var Type2CFF = (function() {
 
           var start = offsets[index];
           var end = offsets[index + 1];
-          return bytes.subarray(start, end);
+          return {
+            start: start,
+            end: end,
+            data: bytes.subarray(start, end)
+          }
         },
         length: count,
         endPos: end
index 09c408ee7b0019288899d8881a6cae34249af2ab..7919b0f178b7c991786cf6566263693fe0846ae5 100644 (file)
@@ -560,7 +560,7 @@ var CFFDictDataMap = {
     '18': {
       name: 'ExpansionFactor'
     },
-    '9': {
+    '19': {
       name: 'initialRandomSeed'
     },
     '20': {
index 7665906a14d0a50b21bb0e702bebfdd2dc183c0d..2c05a64badc365b11776408c14b7f927f07c0539 100644 (file)
@@ -20,17 +20,27 @@ function readCharset(aStream, aCharstrings) {
   var charset = {};
 
   var format = aStream.getByte();
+  var count = aCharstrings.length - 1;
   if (format == 0) {
     charset['.notdef'] = readCharstringEncoding(aCharstrings[0]);
 
-    var count = aCharstrings.length - 1;
     for (var i = 1; i < count + 1; i++) {
       var sid = aStream.getByte() << 8 | aStream.getByte();
       charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[i]);
       //log(CFFStrings[sid] + "::" + charset[CFFStrings[sid]]);
     }
   } else if (format == 1) {
-    error('Charset Range are not supported');
+    for (var i = 1; i < count + 1; i++) {
+      var first = aStream.getByte();
+      first = (first << 8) | aStream.getByte();
+      var numLeft = aStream.getByte();
+      for (var j = 0; j <= numLeft; j++) {
+        var sid = first++;
+        if (CFFStrings[sid] == 'three')
+          log(aCharstrings[j]);
+        charset[CFFStrings[sid]] = readCharstringEncoding(aCharstrings[j]);
+      }
+    }
   } else {
     error('Invalid charset format');
   }
@@ -44,6 +54,9 @@ function readCharset(aStream, aCharstrings) {
  * chapter 3.1.
  */
 function readCharstringEncoding(aString) {
+  if (!aString)
+    return "";
+
   var charstringTokens = [];
 
   var count = aString.length;
@@ -71,9 +84,9 @@ function readCharstringEncoding(aString) {
     } else if (value < 247) {
       token = parseInt(value) - 139;
     } else if (value < 251) {
-      token = ((value - 247) * 256) + aString[i++] + 108;
+      token = (value - 247) * 256 + aString[i++] + 108;
     } else if (value < 255) {
-      token = -((value - 251) * 256) - aString[i++] - 108;
+      token = -(value - 251) * 256 - aString[i++] - 108;
     } else {// value == 255
       token = aString[i++] << 24 | aString[i++] << 16 |
               aString[i++] << 8 | aString[i];
@@ -146,9 +159,9 @@ function readFontDictData(aString, aMap) {
     } else if (value <= 246) {
       token = parseInt(value) - 139;
     } else if (value <= 250) {
-      token = ((value - 247) * 256) + aString[i++] + 108;
+      token = (value - 247) * 256 + aString[i++] + 108;
     } else if (value <= 254) {
-      token = -((value - 251) * 256) - aString[i++] - 108;
+      token = -(value - 251) * 256 - aString[i++] - 108;
     } else if (value == 255) {
       error('255 is not a valid DICT command');
     }
@@ -199,7 +212,7 @@ function readFontIndexData(aStream, aIsByte) {
   for (var i = 0; i < count + 1; i++)
     offsets.push(getNextOffset());
 
-  log('Found ' + count + ' objects at offsets :' +
+  dump('Found ' + count + ' objects at offsets :' +
       offsets + ' (offsize: ' + offsize + ')');
 
   // Now extract the objects
@@ -285,23 +298,20 @@ var Type2Parser = function(aFilePath) {
     font.set('hdrSize', aStream.getByte());
     font.set('offsize', aStream.getByte());
 
-    // Move the cursor after the header
-    aStream.skip(font.get('hdrSize') - aStream.pos);
-
     // Read the NAME Index
     dump('Reading Index: Names');
     font.set('Names', readFontIndexData(aStream));
-    log('Names: ' + font.get('Names'));
+    dump('Names: ' + font.get('Names'));
 
     // Read the Top Dict Index
     dump('Reading Index: TopDict');
     var topDict = readFontIndexData(aStream, true);
-    log('TopDict: ' + topDict);
+    dump('TopDict: ' + topDict);
 
     // Read the String Index
     dump('Reading Index: Strings');
     var strings = readFontIndexData(aStream);
-    log('strings: ' + strings);
+    dump('strings: ' + strings);
 
     // Fill up the Strings dictionary with the new unique strings
     for (var i = 0; i < strings.length; i++)
@@ -321,7 +331,7 @@ var Type2Parser = function(aFilePath) {
 
     // Reading Private Dict
     var priv = font.get('Private');
-    log('Reading Private Dict (offset: ' + priv.offset +
+    dump('Reading Private Dict (offset: ' + priv.offset +
         ' size: ' + priv.size + ')');
     aStream.pos = priv.offset;