[Pkg-javascript-commits] [pdf.js] 111/157: Detect scripted auto-print requests

David Prévot taffit at moszumanska.debian.org
Tue Aug 11 06:46:45 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository pdf.js.

commit c676ecb5a0f54677b9f3340c3ef2cf42225453bb
Author: Rob Wu <rob at robwu.nl>
Date:   Mon Jul 20 18:25:02 2015 +0200

    Detect scripted auto-print requests
    
    Fixes #6106
    
    To avoid future regressions, two new unit tests were added:
    1. A new PDF based on the report from #6106, which contains an
       OpenAction of type JavaScript and a string "this.print({...}".
    2. An existing PDF from https://bugzil.la/1001080 (from #4698).
    
    Although it does not matter, since we don't execute the JavaScript code,
    I have also changed "print(true)" to "print({})" since the print method
    takes an object (not a boolean). See "Printing PDF documents", page 62:
    http://adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/js_developer_guide.pdf
---
 src/core/obj.js          |  48 ++++++++++++++++----------------
 test/pdfs/.gitignore     |   2 ++
 test/pdfs/bug1001080.pdf | Bin 0 -> 12423 bytes
 test/pdfs/issue6106.pdf  |  70 +++++++++++++++++++++++++++++++++++++++++++++++
 test/unit/api_spec.js    |  26 ++++++++++++++++++
 web/viewer.js            |   2 +-
 6 files changed, 124 insertions(+), 24 deletions(-)

diff --git a/src/core/obj.js b/src/core/obj.js
index f38effe..a8bd5d3 100644
--- a/src/core/obj.js
+++ b/src/core/obj.js
@@ -534,6 +534,19 @@ var Catalog = (function CatalogClosure() {
       var obj = this.catDict.get('Names');
 
       var javaScript = [];
+      function appendIfJavaScriptDict(jsDict) {
+        var type = jsDict.get('S');
+        if (!isName(type) || type.name !== 'JavaScript') {
+          return;
+        }
+        var js = jsDict.get('JS');
+        if (isStream(js)) {
+          js = bytesToString(js.getBytes());
+        } else if (!isString(js)) {
+          return;
+        }
+        javaScript.push(stringToPDFString(js));
+      }
       if (obj && obj.has('JavaScript')) {
         var nameTree = new NameTree(obj.getRaw('JavaScript'), xref);
         var names = nameTree.getAll();
@@ -544,36 +557,25 @@ var Catalog = (function CatalogClosure() {
           // We don't really use the JavaScript right now. This code is
           // defensive so we don't cause errors on document load.
           var jsDict = names[name];
-          if (!isDict(jsDict)) {
-            continue;
-          }
-          var type = jsDict.get('S');
-          if (!isName(type) || type.name !== 'JavaScript') {
-            continue;
+          if (isDict(jsDict)) {
+            appendIfJavaScriptDict(jsDict);
           }
-          var js = jsDict.get('JS');
-          if (!isString(js) && !isStream(js)) {
-            continue;
-          }
-          if (isStream(js)) {
-            js = bytesToString(js.getBytes());
-          }
-          javaScript.push(stringToPDFString(js));
         }
       }
 
       // Append OpenAction actions to javaScript array
       var openactionDict = this.catDict.get('OpenAction');
-      if (isDict(openactionDict)) {
-        var objType = openactionDict.get('Type');
+      if (isDict(openactionDict, 'Action')) {
         var actionType = openactionDict.get('S');
-        var action = openactionDict.get('N');
-        var isPrintAction = (isName(objType) && objType.name === 'Action' &&
-                            isName(actionType) && actionType.name === 'Named' &&
-                            isName(action) && action.name === 'Print');
-
-        if (isPrintAction) {
-          javaScript.push('print(true);');
+        if (isName(actionType) && actionType.name === 'Named') {
+          // The named Print action is not a part of the PDF 1.7 specification,
+          // but is supported by many PDF readers/writers (including Adobe's).
+          var action = openactionDict.get('N');
+          if (isName(action) && action.name === 'Print') {
+            javaScript.push('print({});');
+          }
+        } else {
+          appendIfJavaScriptDict(openactionDict);
         }
       }
 
diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore
index a79dc29..a186388 100644
--- a/test/pdfs/.gitignore
+++ b/test/pdfs/.gitignore
@@ -146,4 +146,6 @@
 !issue6068.pdf
 !issue6081.pdf
 !issue6069.pdf
+!issue6106.pdf
+!bug1001080.pdf
 !issue6108.pdf
diff --git a/test/pdfs/bug1001080.pdf b/test/pdfs/bug1001080.pdf
new file mode 100644
index 0000000..0f60ca9
Binary files /dev/null and b/test/pdfs/bug1001080.pdf differ
diff --git a/test/pdfs/issue6106.pdf b/test/pdfs/issue6106.pdf
new file mode 100644
index 0000000..21b5452
--- /dev/null
+++ b/test/pdfs/issue6106.pdf
@@ -0,0 +1,70 @@
+%PDF-1.4
+% To manually verify that PDF.js works as expected, open this PDF file with
+% PDF.js and check whether the browser attempts to print the PDF.
+1 0 obj
+<<
+/Type /Catalog
+/Pages 2 0 R
+/OpenAction 3 0 R
+>>
+endobj
+2 0 obj
+<<
+/Type /Pages
+/Count 1
+/Kids [4 0 R]
+>>
+endobj
+3 0 obj
+<<
+/Type /Action
+/S /JavaScript
+% This is a verbatim copy from a PDF generated by Google Drive (20 July 2015)
+/JS (this.print\({bUI:true,bSilent:false,bShrinkToFit:true}\);)
+>>
+endobj
+4 0 obj
+<<
+/Parent 2 0 R
+/Contents 6 0 R
+/Type /Page
+/Resources 5 0 R
+/MediaBox [0 0 400 200]
+>>
+endobj
+5 0 obj
+<<
+/Font
+  <<
+  /F1
+    <<
+    /Type /Font
+    /Subtype /Type1
+    /BaseFont /Arial
+    >>
+  >>
+>>
+endobj
+6 0 obj
+<</Length 58>>
+stream
+BT/F1 20 Tf 70 88 Td(Should trigger a print action.) Tj ET
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000151 00000 n 
+0000000218 00000 n 
+0000000275 00000 n 
+0000000467 00000 n 
+0000000571 00000 n 
+0000000685 00000 n 
+trailer
+<<
+/Root 1 0 R
+/Size 7
+>>
+startxref
+791
+%%EOF
diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js
index 895039b..4747342 100644
--- a/test/unit/api_spec.js
+++ b/test/unit/api_spec.js
@@ -147,6 +147,32 @@ describe('api', function() {
         expect(data).toEqual([]);
       });
     });
+    // Keep this in sync with the pattern in viewer.js. The pattern is used to
+    // detect whether or not to automatically start printing.
+    var viewerPrintRegExp = /\bprint\s*\(/;
+    it('gets javascript with printing instructions (Print action)', function() {
+      // PDF document with "Print" Named action in OpenAction
+      var pdfUrl = combineUrl(window.location.href, '../pdfs/bug1001080.pdf');
+      var promise = PDFJS.getDocument(pdfUrl).then(function(doc) {
+        return doc.getJavaScript();
+      });
+      waitsForPromiseResolved(promise, function (data) {
+        expect(data).toEqual(['print({});']);
+        expect(data[0]).toMatch(viewerPrintRegExp);
+      });
+    });
+    it('gets javascript with printing instructions (JS action)', function() {
+      // PDF document with "JavaScript" action in OpenAction
+      var pdfUrl = combineUrl(window.location.href, '../pdfs/issue6106.pdf');
+      var promise = PDFJS.getDocument(pdfUrl).then(function(doc) {
+        return doc.getJavaScript();
+      });
+      waitsForPromiseResolved(promise, function (data) {
+        expect(data).toEqual(
+          ['this.print({bUI:true,bSilent:false,bShrinkToFit:true});']);
+        expect(data[0]).toMatch(viewerPrintRegExp);
+      });
+    });
     it('gets outline', function() {
       var promise = doc.getOutline();
       waitsForPromiseResolved(promise, function(outline) {
diff --git a/web/viewer.js b/web/viewer.js
index 758281f..4e4607e 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -820,7 +820,7 @@ var PDFViewerApplication = {
             self.fallback(PDFJS.UNSUPPORTED_FEATURES.javaScript);
           }
           // Hack to support auto printing.
-          var regex = /\bprint\s*\(/g;
+          var regex = /\bprint\s*\(/;
           for (var i = 0, ii = javaScript.length; i < ii; i++) {
             var js = javaScript[i];
             if (js && regex.test(js)) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git



More information about the Pkg-javascript-commits mailing list