Skip to content

Instantly share code, notes, and snippets.

@mikedeboer
Created July 17, 2019 10:04
Show Gist options
  • Save mikedeboer/c517509c52a474394840b9c295f3cf92 to your computer and use it in GitHub Desktop.
Save mikedeboer/c517509c52a474394840b9c295f3cf92 to your computer and use it in GitHub Desktop.
Mozilla-central patch that adds very basic scripting support to PDF.js, using Gecko sandboxing and eval.
# HG changeset patch
# User Mike de Boer <mdeboer@mozilla.com>
# Date 1562077334 -7200
# Tue Jul 02 16:22:14 2019 +0200
# Node ID 4b826bf58084a766832c54658b7b63f2748a503e
# Parent 8fd4efa75b558406390c316a7e4d1fc288715866
WIP to add scripting support to PDF.js
diff --git a/browser/base/content/test/static/browser_all_files_referenced.js b/browser/base/content/test/static/browser_all_files_referenced.js
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -93,16 +93,17 @@ var whitelist = [
// extensions/pref/autoconfig/src/nsReadConfig.cpp
{ file: "resource://gre/defaults/autoconfig/prefcalls.js" },
// modules/libpref/Preferences.cpp
{ file: "resource://gre/greprefs.js" },
// browser/extensions/pdfjs/content/web/viewer.js
{ file: "resource://pdf.js/build/pdf.worker.js" },
+ { file: "resource://pdf.js/build/pdf.scripting_api.js" },
// layout/mathml/nsMathMLChar.cpp
{ file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties" },
{ file: "resource://gre/res/fonts/mathfontUnicode.properties" },
// Needed by HiddenFrame.jsm, but can't be packaged test-only
{ file: "chrome://global/content/win.xul" },
diff --git a/browser/extensions/pdfjs/README.mozilla b/browser/extensions/pdfjs/README.mozilla
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -1,5 +1,5 @@
This is the PDF.js project output, https://github.com/mozilla/pdf.js
-Current extension version is: 2.3.27
+Current extension version is: 2.3.32
-Taken from upstream commit: 13ebfec9
+Taken from upstream commit: a5516bb4
diff --git a/browser/extensions/pdfjs/content/PdfJsDefaultPreferences.jsm b/browser/extensions/pdfjs/content/PdfJsDefaultPreferences.jsm
--- a/browser/extensions/pdfjs/content/PdfJsDefaultPreferences.jsm
+++ b/browser/extensions/pdfjs/content/PdfJsDefaultPreferences.jsm
@@ -20,16 +20,17 @@
//
"use strict";
var EXPORTED_SYMBOLS = ["PdfJsDefaultPreferences"];
var PdfJsDefaultPreferences = Object.freeze({
"cursorToolOnLoad": 0,
"defaultZoomValue": "",
"disablePageLabels": false,
+ "disableScripting": false,
"enablePrintAutoRotate": false,
"enableWebGL": false,
"eventBusDispatchToDOM": false,
"externalLinkTarget": 0,
"historyUpdateUrl": false,
"pdfBugEnabled": false,
"renderer": "canvas",
"renderInteractiveForms": false,
diff --git a/browser/extensions/pdfjs/content/PdfJsScripting.jsm b/browser/extensions/pdfjs/content/PdfJsScripting.jsm
new file mode 100644
--- /dev/null
+++ b/browser/extensions/pdfjs/content/PdfJsScripting.jsm
@@ -0,0 +1,122 @@
+/* Copyright 2013 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["PdfJsScripting"];
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+ChromeUtils.defineModuleGetter(
+ this,
+ "PromiseUtils",
+ "resource://gre/modules/PromiseUtils.jsm"
+);
+
+var gSandboxes = new Map();
+var gLastSandboxID = 0;
+var gCachedScript, gCurrentWindow;
+
+const PdfJsScripting = {
+ set window(win) {
+ if (gLastSandboxID) {
+ for (let [, context] of gSandboxes) {
+ if (context.sandbox) {
+ Cu.nukeSandbox(context.sandbox);
+ }
+ }
+ gSandboxes.clear();
+ gLastSandboxID = 0;
+ }
+ gCurrentWindow = win;
+ },
+
+ get cachedApiScript() {
+ if (gCachedScript) {
+ if (gCachedScript instanceof Promise) {
+ return gCachedScript;
+ }
+ return Promise.resolve(gCachedScript);
+ }
+
+ let deferred = PromiseUtils.defer();
+ ChromeUtils.compileScript("resource://pdf.js/build/pdf.scripting_api.js", {
+ hasReturnValue: true,
+ }).then(script => {
+ gCachedScript = script;
+ deferred.resolve(script);
+ });
+ return (gCachedScript = deferred.promise);
+ },
+
+ createSandbox(initialState) {
+ const contentPrincipal = gCurrentWindow.document.nodePrincipal;
+ const ssm = Services.scriptSecurityManager;
+
+ let principal;
+ if (contentPrincipal.isSystemPrincipal) {
+ principal = ssm.createNullPrincipal(contentPrincipal.originAttributes);
+ } else {
+ principal = [contentPrincipal];
+ }
+
+ let context = {
+ ID: ++gLastSandboxID,
+ ready: false,
+ evalQueue: new Set(),
+ sandbox: Cu.Sandbox(principal, {
+ sandboxName: "Script registered by PDF.js",
+ sandboxPrototype: gCurrentWindow,
+ sameZoneAs: gCurrentWindow,
+ wantXrays: true,
+ wantExportHelpers: true,
+ originAttributes: contentPrincipal.originAttributes,
+ }),
+ };
+
+ this.cachedApiScript.then(script => {
+ context.ready = true;
+
+ script.executeInGlobal(context.sandbox);
+ Cu.evalInSandbox(
+ `
+ var {app, console, global} = pdfjsScriptingAPI.Scripting
+ .getAPI('${JSON.stringify(initialState)}');
+ `,
+ context.sandbox
+ );
+
+ for (let item of context.evalQueue) {
+ this.evalInSandbox(item, context.ID);
+ }
+ context.evalQueue.clear();
+ });
+
+ gSandboxes.set(context.ID, context);
+ return context.ID;
+ },
+
+ evalInSandbox(script, sandboxID) {
+ let context = gSandboxes.get(sandboxID);
+ if (!context) {
+ return null;
+ }
+ if (!context.ready) {
+ context.evalQueue.add(script);
+ return null;
+ }
+ return Cu.evalInSandbox(script, context.sandbox, "latest");
+ },
+};
diff --git a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -54,16 +54,22 @@ ChromeUtils.defineModuleGetter(
);
ChromeUtils.defineModuleGetter(
this,
"PdfjsContentUtils",
"resource://pdf.js/PdfjsContentUtils.jsm"
);
+ChromeUtils.defineModuleGetter(
+ this,
+ "PdfJsScripting",
+ "resource://pdf.js/PdfJsScripting.jsm"
+);
+
XPCOMUtils.defineLazyGlobalGetters(this, ["XMLHttpRequest"]);
var Svc = {};
XPCOMUtils.defineLazyServiceGetter(
Svc,
"mime",
"@mozilla.org/mime;1",
"nsIMIMEService"
@@ -237,16 +243,17 @@ class ChromeActions {
this.contentDispositionFilename = contentDispositionFilename;
this.telemetryState = {
documentInfo: false,
firstPageInfo: false,
streamTypesUsed: [],
fontTypesUsed: [],
startAt: Date.now(),
};
+ PdfJsScripting.window = domWindow;
}
isInPrivateBrowsing() {
return PrivateBrowsingUtils.isContentWindowPrivate(this.domWindow);
}
getWindowOriginAttributes() {
try {
@@ -604,16 +611,24 @@ class ChromeActions {
}
}
let result = JSON.stringify(currentPrefs);
if (sendResponse) {
sendResponse(result);
}
return result;
}
+
+ createSandbox({ proto, api }) {
+ return PdfJsScripting.createSandbox(proto, api);
+ }
+
+ evalInSandbox({ script, sandboxID }) {
+ return PdfJsScripting.evalInSandbox(script, sandboxID);
+ }
}
/**
* This is for range requests.
*/
class RangedChromeActions extends ChromeActions {
constructor(
domWindow,
diff --git a/browser/extensions/pdfjs/content/build/pdf.js b/browser/extensions/pdfjs/content/build/pdf.js
--- a/browser/extensions/pdfjs/content/build/pdf.js
+++ b/browser/extensions/pdfjs/content/build/pdf.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { //
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __w_pdfjs_require__) {
"use strict";
-var pdfjsVersion = '2.3.27';
-var pdfjsBuild = '13ebfec9';
+var pdfjsVersion = '2.3.32';
+var pdfjsBuild = 'a5516bb4';
var pdfjsSharedUtil = __w_pdfjs_require__(1);
var pdfjsDisplayAPI = __w_pdfjs_require__(6);
var pdfjsDisplayTextLayer = __w_pdfjs_require__(18);
var pdfjsDisplayAnnotationLayer = __w_pdfjs_require__(19);
@@ -1299,17 +1299,17 @@ function _fetchDocument(worker, source,
if (pdfDataRangeTransport) {
source.length = pdfDataRangeTransport.length;
source.initialData = pdfDataRangeTransport.initialData;
source.progressiveDone = pdfDataRangeTransport.progressiveDone;
}
return worker.messageHandler.sendWithPromise('GetDocRequest', {
docId,
- apiVersion: '2.3.27',
+ apiVersion: '2.3.32',
source: {
data: source.data,
url: source.url,
password: source.password,
disableAutoFetch: source.disableAutoFetch,
rangeChunkSize: source.rangeChunkSize,
length: source.length
},
@@ -3095,19 +3095,19 @@ const InternalRenderTask = function Inte
}
}
}
return InternalRenderTask;
}();
-const version = '2.3.27';
+const version = '2.3.32';
exports.version = version;
-const build = '13ebfec9';
+const build = 'a5516bb4';
exports.build = build;
/***/ }),
/* 7 */
/***/ (function(module, exports, __w_pdfjs_require__) {
"use strict";
@@ -9217,24 +9217,25 @@ class TextWidgetAnnotationElement extend
element.classList.add('comb');
element.style.letterSpacing = 'calc(' + combWidth + 'px - 1ch)';
}
} else {
element = document.createElement('div');
element.textContent = this.data.fieldValue;
element.style.verticalAlign = 'middle';
element.style.display = 'table-cell';
- let font = null;
-
- if (this.data.fontRefName && this.page.commonObjs.has(this.data.fontRefName)) {
- font = this.page.commonObjs.get(this.data.fontRefName);
- }
-
- this._setTextStyle(element, font);
- }
+ }
+
+ let font = null;
+
+ if (this.data.fontRefName && this.page.commonObjs.has(this.data.fontRefName)) {
+ font = this.page.commonObjs.get(this.data.fontRefName);
+ }
+
+ this._setTextStyle(element, font);
if (this.data.textAlignment !== null) {
element.style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
}
this.container.appendChild(element);
return this.container;
}
diff --git a/browser/extensions/pdfjs/content/build/pdf.scripting_api.js b/browser/extensions/pdfjs/content/build/pdf.scripting_api.js
new file mode 100644
--- /dev/null
+++ b/browser/extensions/pdfjs/content/build/pdf.scripting_api.js
@@ -0,0 +1,219 @@
+/**
+ * @licstart The following is the entire license notice for the
+ * Javascript code in this page
+ *
+ * Copyright 2019 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @licend The above is the entire license notice for the
+ * Javascript code in this page
+ */
+
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory();
+ else if(typeof define === 'function' && define.amd)
+ define("pdfjs-dist/build/pdf.scripting_api", [], factory);
+ else if(typeof exports === 'object')
+ exports["pdfjs-dist/build/pdf.scripting_api"] = factory();
+ else
+ root["pdfjs-dist/build/pdf.scripting_api"] = root.pdfjsScriptingAPI = factory();
+})(this, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __w_pdfjs_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __w_pdfjs_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __w_pdfjs_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __w_pdfjs_require__.c = installedModules;
+/******/
+/******/ // define getter function for harmony exports
+/******/ __w_pdfjs_require__.d = function(exports, name, getter) {
+/******/ if(!__w_pdfjs_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ }
+/******/ };
+/******/
+/******/ // define __esModule on exports
+/******/ __w_pdfjs_require__.r = function(exports) {
+/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ }
+/******/ Object.defineProperty(exports, '__esModule', { value: true });
+/******/ };
+/******/
+/******/ // create a fake namespace object
+/******/ // mode & 1: value is a module id, require it
+/******/ // mode & 2: merge all properties of value into the ns
+/******/ // mode & 4: return value when already ns object
+/******/ // mode & 8|1: behave like require
+/******/ __w_pdfjs_require__.t = function(value, mode) {
+/******/ if(mode & 1) value = __w_pdfjs_require__(value);
+/******/ if(mode & 8) return value;
+/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ var ns = Object.create(null);
+/******/ __w_pdfjs_require__.r(ns);
+/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __w_pdfjs_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ return ns;
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __w_pdfjs_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __w_pdfjs_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __w_pdfjs_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __w_pdfjs_require__.p = "";
+/******/
+/******/
+/******/ // Load entry module and return exports
+/******/ return __w_pdfjs_require__(__w_pdfjs_require__.s = 0);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports, __w_pdfjs_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.Scripting = void 0;
+
+var _App = __w_pdfjs_require__(1);
+
+var _Console = __w_pdfjs_require__(2);
+
+const Scripting = {
+ getAPI(runtime, console) {
+ return {
+ app: new _App.App(runtime),
+ console: new _Console.Console(console),
+ global: {}
+ };
+ }
+
+};
+exports.Scripting = Scripting;
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __w_pdfjs_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.App = void 0;
+
+class App {
+ constructor(runtime) {
+ this._runtime = runtime;
+ }
+
+ get viewerType() {
+ return 'Reader';
+ }
+
+ get viewerVariation() {
+ return 'Reader';
+ }
+
+ get viewerVersion() {
+ return 10.0;
+ }
+
+ alert(msg) {
+ window.alert(msg);
+ }
+
+}
+
+exports.App = App;
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports, __w_pdfjs_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.Console = void 0;
+
+class Console {
+ constructor(consoleAPI) {
+ this._consoleAPI = consoleAPI || window.console;
+ }
+
+ clear() {
+ this._consoleAPI.clear();
+ }
+
+ hide() {}
+
+ println(msg) {
+ this._consoleAPI.log('PDF.js Console:: ' + msg);
+ }
+
+ show() {}
+
+}
+
+exports.Console = Console;
+
+/***/ })
+/******/ ]);
+});
\ No newline at end of file
diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js
--- a/browser/extensions/pdfjs/content/build/pdf.worker.js
+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
@@ -118,18 +118,18 @@ return /******/ (function(modules) { //
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __w_pdfjs_require__) {
"use strict";
-const pdfjsVersion = '2.3.27';
-const pdfjsBuild = '13ebfec9';
+const pdfjsVersion = '2.3.32';
+const pdfjsBuild = 'a5516bb4';
const pdfjsCoreWorker = __w_pdfjs_require__(1);
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
/***/ }),
/* 1 */
/***/ (function(module, exports, __w_pdfjs_require__) {
@@ -235,17 +235,17 @@ var WorkerMessageHandler = {
createDocumentHandler(docParams, port) {
var pdfManager;
var terminated = false;
var cancelXHRs = null;
var WorkerTasks = [];
const verbosity = (0, _util.getVerbosityLevel)();
let apiVersion = docParams.apiVersion;
- let workerVersion = '2.3.27';
+ let workerVersion = '2.3.32';
if (apiVersion !== workerVersion) {
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
}
var docId = docParams.docId;
var docBaseUrl = docParams.docBaseUrl;
var workerHandlerName = docParams.docId + '_worker';
@@ -2352,16 +2352,24 @@ class ChunkedStream {
peekBytes(length, forceClamped = false) {
const bytes = this.getBytes(length, forceClamped);
this.pos -= bytes.length;
return bytes;
}
getByteRange(begin, end) {
+ if (begin < 0) {
+ begin = 0;
+ }
+
+ if (end > this.end) {
+ end = this.end;
+ }
+
this.ensureRange(begin, end);
return this.bytes.subarray(begin, end);
}
skip(n) {
if (!n) {
n = 1;
}
@@ -3435,31 +3443,27 @@ class PDFDocument {
get fingerprint() {
let hash;
const idArray = this.xref.trailer.get('ID');
if (Array.isArray(idArray) && idArray[0] && (0, _util.isString)(idArray[0]) && idArray[0] !== EMPTY_FINGERPRINT) {
hash = (0, _util.stringToBytes)(idArray[0]);
} else {
- if (this.stream.ensureRange) {
- this.stream.ensureRange(0, Math.min(FINGERPRINT_FIRST_BYTES, this.stream.end));
- }
-
- hash = (0, _crypto.calculateMD5)(this.stream.bytes.subarray(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES);
- }
-
- let fingerprint = '';
+ hash = (0, _crypto.calculateMD5)(this.stream.getByteRange(0, FINGERPRINT_FIRST_BYTES), 0, FINGERPRINT_FIRST_BYTES);
+ }
+
+ const fingerprintBuf = [];
for (let i = 0, ii = hash.length; i < ii; i++) {
const hex = hash[i].toString(16);
- fingerprint += hex.length === 1 ? '0' + hex : hex;
- }
-
- return (0, _util.shadow)(this, 'fingerprint', fingerprint);
+ fingerprintBuf.push(hex.padStart(2, '0'));
+ }
+
+ return (0, _util.shadow)(this, 'fingerprint', fingerprintBuf.join(''));
}
_getLinearizationPage(pageIndex) {
const {
catalog,
linearization
} = this;
(0, _util.assert)(linearization && linearization.pageFirst === pageIndex);
@@ -7149,16 +7153,28 @@ var Stream = function StreamClosure() {
},
peekBytes(length, forceClamped = false) {
var bytes = this.getBytes(length, forceClamped);
this.pos -= bytes.length;
return bytes;
},
+ getByteRange(begin, end) {
+ if (begin < 0) {
+ begin = 0;
+ }
+
+ if (end > this.end) {
+ end = this.end;
+ }
+
+ return this.bytes.subarray(begin, end);
+ },
+
skip: function Stream_skip(n) {
if (!n) {
n = 1;
}
this.pos += n;
},
reset: function Stream_reset() {
@@ -7309,16 +7325,21 @@ var DecodeStream = function DecodeStream
var end = start + length;
while (this.bufferLength <= end && !this.eof) {
this.readBlock();
}
return new Stream(this.buffer, start, length, dict);
},
+
+ getByteRange(begin, end) {
+ (0, _util.unreachable)('Should not call DecodeStream.getByteRange');
+ },
+
skip: function DecodeStream_skip(n) {
if (!n) {
n = 1;
}
this.pos += n;
},
reset: function DecodeStream_reset() {
@@ -18386,16 +18407,21 @@ class Annotation {
setAppearance(dict) {
this.appearance = null;
let appearanceStates = dict.get('AP');
if (!(0, _primitives.isDict)(appearanceStates)) {
return;
}
+ if (this.defaultAppearance) {
+ this.appearance = new _stream.Stream((0, _util.stringToBytes)(this.defaultAppearance));
+ return;
+ }
+
let normalAppearanceState = appearanceStates.get('N');
if ((0, _primitives.isStream)(normalAppearanceState)) {
this.appearance = normalAppearanceState;
return;
}
if (!(0, _primitives.isDict)(normalAppearanceState)) {
diff --git a/browser/extensions/pdfjs/content/web/viewer.js b/browser/extensions/pdfjs/content/web/viewer.js
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -1010,16 +1010,17 @@ let PDFViewerApplication = {
this.loadingBar.hide();
this.disableAutoFetchLoadingBarTimeout = null;
}, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT);
}
}
},
load(pdfDocument) {
+ dump('Taking this load path at all??\n');
this.pdfDocument = pdfDocument;
pdfDocument.getDownloadInfo().then(() => {
this.downloadComplete = true;
this.loadingBar.hide();
firstPagePromise.then(() => {
this.eventBus.dispatch('documentloaded', {
source: this
});
@@ -1157,46 +1158,52 @@ let PDFViewerApplication = {
return;
}
pdfViewer.setPageLabels(labels);
pdfThumbnailViewer.setPageLabels(labels);
this.toolbar.setPagesCount(pdfDocument.numPages, true);
this.toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);
});
+ dump('Waiting for all pages to be there...\n');
pagesPromise.then(() => {
- if (!this.supportsPrinting) {
- return;
- }
-
+ dump('Fetching scripts...\n');
pdfDocument.getJavaScript().then(javaScript => {
if (!javaScript) {
+ dump('No scripts found!!\n');
return;
}
- javaScript.some(js => {
- if (!js) {
- return false;
- }
-
- console.warn('Warning: JavaScript is not supported');
- this.fallback(_pdfjsLib.UNSUPPORTED_FEATURES.javaScript);
- return true;
- });
- let regex = /\bprint\s*\(/;
+ let scripting = this.externalServices.scripting;
+ dump('SCRIPTING ENABLED?? ' + _app_options.AppOptions.get('disableScripting') + ' ' + scripting + '\n');
+
+ if (_app_options.AppOptions.get('disableScripting') || !scripting) {
+ javaScript.some(js => {
+ if (!js) {
+ return false;
+ }
+
+ console.warn('Warning: JavaScript is not supported');
+ this.fallback(_pdfjsLib.UNSUPPORTED_FEATURES.javaScript);
+ return true;
+ });
+ return;
+ }
+
+ let sandbox = scripting.createSandbox({});
for (let i = 0, ii = javaScript.length; i < ii; i++) {
let js = javaScript[i];
- if (js && regex.test(js)) {
- setTimeout(function () {
- window.print();
- });
- return;
+ if (!js || !js.trim()) {
+ continue;
}
+
+ dump('EVAL IN SANDBOX::: ' + js + '\n');
+ scripting.evalInSandbox(js, sandbox);
}
});
});
Promise.all([onePageRendered, _ui_utils.animationStarted]).then(() => {
pdfDocument.getOutline().then(outline => {
this.pdfOutlineViewer.render({
outline
});
@@ -3185,16 +3192,20 @@ const defaultOptions = {
disableHistory: {
value: false,
kind: OptionKind.VIEWER
},
disablePageLabels: {
value: false,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE
},
+ disableScripting: {
+ value: false,
+ kind: OptionKind.VIEWER + OptionKind.PREFERENCE
+ },
enablePrintAutoRotate: {
value: false,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE
},
enableWebGL: {
value: false,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE
},
@@ -11381,16 +11392,32 @@ class FirefoxComDataRangeTransport exten
}
abort() {
FirefoxCom.requestSync('abortLoading', null);
}
}
+const FirefoxScripting = {
+ createSandbox(proto, api) {
+ return FirefoxCom.requestSync('createSandbox', {
+ proto,
+ api
+ });
+ },
+
+ evalInSandbox(script, sandboxID) {
+ return FirefoxCom.requestSync('evalInSandbox', {
+ script,
+ sandboxID
+ });
+ }
+
+};
_app.PDFViewerApplication.externalServices = {
updateFindControlState(data) {
FirefoxCom.request('updateFindControlState', data);
},
updateFindMatchesCount(data) {
FirefoxCom.request('updateFindMatchesCount', data);
},
@@ -11468,16 +11495,20 @@ class FirefoxComDataRangeTransport exten
return new FirefoxPreferences();
},
createL10n(options) {
let mozL10n = document.mozL10n;
return new MozL10n(mozL10n);
},
+ get scripting() {
+ return FirefoxScripting;
+ },
+
get supportsIntegratedFind() {
let support = FirefoxCom.requestSync('supportsIntegratedFind');
return (0, _pdfjsLib.shadow)(this, 'supportsIntegratedFind', support);
},
get supportsDocumentFonts() {
let support = FirefoxCom.requestSync('supportsDocumentFonts');
return (0, _pdfjsLib.shadow)(this, 'supportsDocumentFonts', support);
@@ -11642,16 +11673,17 @@ exports.BasePreferences = void 0;
let defaultPreferences = null;
function getDefaultPreferences() {
if (!defaultPreferences) {
defaultPreferences = Promise.resolve({
"cursorToolOnLoad": 0,
"defaultZoomValue": "",
"disablePageLabels": false,
+ "disableScripting": false,
"enablePrintAutoRotate": false,
"enableWebGL": false,
"eventBusDispatchToDOM": false,
"externalLinkTarget": 0,
"historyUpdateUrl": false,
"pdfBugEnabled": false,
"renderer": "canvas",
"renderInteractiveForms": false,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment