diff --git a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm index bc3b9300a..f279fc812 100644 --- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm +++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm @@ -29,7 +29,8 @@ const MOZ_CENTRAL = JSON.parse('true'); const PDFJS_EVENT_ID = 'pdf.js.message'; const PDF_CONTENT_TYPE = 'application/pdf'; const PREF_PREFIX = 'pdfjs'; -const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html'; +const PDF_VIEWER_ORIGIN = "resource://pdf.js"; +const PDF_VIEWER_WEB_PAGE = "resource://pdf.js/web/viewer.html"; const MAX_NUMBER_OF_PREFS = 50; const MAX_STRING_PREF_LENGTH = 128; @@ -111,11 +112,15 @@ function log(aMsg) { dump(msg + '\n'); } -function getDOMWindow(aChannel) { +function getDOMWindow(aChannel, aPrincipal) { var requestor = aChannel.notificationCallbacks ? aChannel.notificationCallbacks : aChannel.loadGroup.notificationCallbacks; var win = requestor.getInterface(Components.interfaces.nsIDOMWindow); + // Ensure the window wasn't navigated to something that is not PDF.js. + if (!win.document.nodePrincipal.equals(aPrincipal)) { + return null; + } return win; } @@ -637,7 +642,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { loaded: loaded, total: total, chunk: self.dataListener.readData() - }, '*'); + }, PDF_VIEWER_ORIGIN); }; this.dataListener.oncomplete = function () { self.dataListener = null; @@ -651,7 +656,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { pdfUrl: this.pdfUrl, length: this.contentLength, data: data - }, '*'); + }, PDF_VIEWER_ORIGIN); return true; }; @@ -673,13 +678,13 @@ var RangedChromeActions = (function RangedChromeActionsClosure() { pdfjsLoadAction: 'range', begin: args.begin, chunk: args.chunk - }, '*'); + }, PDF_VIEWER_ORIGIN); }, onProgress: function RangedChromeActions_onProgress(evt) { domWindow.postMessage({ pdfjsLoadAction: 'rangeProgress', loaded: evt.loaded, - }, '*'); + }, PDF_VIEWER_ORIGIN); } }); }; @@ -728,7 +733,7 @@ var StandardChromeActions = (function StandardChromeActionsClosure() { pdfjsLoadAction: 'progress', loaded: loaded, total: total - }, '*'); + }, PDF_VIEWER_ORIGIN); }; this.dataListener.oncomplete = @@ -737,7 +742,7 @@ var StandardChromeActions = (function StandardChromeActionsClosure() { pdfjsLoadAction: 'complete', data: data, errorCode: errorCode - }, '*'); + }, PDF_VIEWER_ORIGIN); self.dataListener = null; self.originalRequest = null; @@ -981,10 +986,14 @@ PdfStreamConverter.prototype = { onDataAvailable: function(request, context, inputStream, offset, count) { listener.onDataAvailable(aRequest, context, inputStream, offset, count); }, - onStopRequest: function(request, context, statusCode) { - // We get the DOM window here instead of before the request since it - // may have changed during a redirect. - var domWindow = getDOMWindow(channel); + onStopRequest(request, context, statusCode) { + var domWindow = getDOMWindow(channel, resourcePrincipal); + if (!Components.isSuccessCode(statusCode) || !domWindow) { + // The request may have been aborted and the document may have been + // replaced with something that is not PDF.js, abort attaching. + listener.onStopRequest(aRequest, context, statusCode); + return; + } var actions; if (rangeRequest || streamRequest) { actions = new RangedChromeActions( @@ -995,7 +1004,7 @@ PdfStreamConverter.prototype = { domWindow, contentDispositionFilename, aRequest, dataListener); } var requestListener = new RequestListener(actions); - domWindow.addEventListener(PDFJS_EVENT_ID, function(event) { + domWindow.document.addEventListener(PDFJS_EVENT_ID, function(event) { requestListener.receive(event); }, false, true); if (actions.supportsIntegratedFind()) { diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js index 44203ff78..7f8de8621 100644 --- a/browser/extensions/pdfjs/content/build/pdf.worker.js +++ b/browser/extensions/pdfjs/content/build/pdf.worker.js @@ -5216,8 +5216,8 @@ var PDFFunction = (function PDFFunctionClosure() { } return out; } - var domain = dict.get('Domain'); - var range = dict.get('Range'); + var domain = toNumberArray(dict.get('Domain')); + var range = toNumberArray(dict.get('Range')); if (!domain || !range) { error('No domain or range'); @@ -5229,7 +5229,7 @@ var PDFFunction = (function PDFFunctionClosure() { domain = toMultiArray(domain); range = toMultiArray(range); - var size = dict.get('Size'); + var size = toNumberArray(dict.get('Size')); var bps = dict.get('BitsPerSample'); var order = dict.get('Order') || 1; if (order !== 1) { @@ -5238,17 +5238,16 @@ var PDFFunction = (function PDFFunctionClosure() { info('No support for cubic spline interpolation: ' + order); } - var encode = dict.get('Encode'); + var encode = toNumberArray(dict.get('Encode')); if (!encode) { encode = []; for (var i = 0; i < inputSize; ++i) { - encode.push(0); - encode.push(size[i] - 1); + encode.push([0, size[i] - 1]); } + } else { + encode = toMultiArray(encode); } - encode = toMultiArray(encode); - - var decode = dict.get('Decode'); + var decode = toNumberArray(dict.get('Decode')); if (!decode) { decode = range; } else { @@ -5350,14 +5349,10 @@ var PDFFunction = (function PDFFunctionClosure() { constructInterpolated: function PDFFunction_constructInterpolated(str, dict) { - var c0 = dict.get('C0') || [0]; - var c1 = dict.get('C1') || [1]; + var c0 = toNumberArray(dict.get('C0')) || [0]; + var c1 = toNumberArray(dict.get('C1')) || [1]; var n = dict.get('N'); - if (!isArray(c0) || !isArray(c1)) { - error('Illegal dictionary for interpolated function'); - } - var length = c0.length; var diff = []; for (var i = 0; i < length; ++i) { @@ -5400,11 +5395,11 @@ var PDFFunction = (function PDFFunctionClosure() { var fnRefs = dict.get('Functions'); var fns = []; for (var i = 0, ii = fnRefs.length; i < ii; ++i) { - fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i]))); + fns.push(PDFFunction.parse(xref, xref.fetchIfRef(fnRefs[i]))); } - var bounds = dict.get('Bounds'); - var encode = dict.get('Encode'); + var bounds = toNumberArray(dict.get('Bounds')); + var encode = toNumberArray(dict.get('Encode')); return [CONSTRUCT_STICHED, domain, bounds, encode, fns]; }, @@ -5413,14 +5408,8 @@ var PDFFunction = (function PDFFunctionClosure() { var domain = IR[1]; var bounds = IR[2]; var encode = IR[3]; - var fnsIR = IR[4]; - var fns = []; + var fns = IR[4]; var tmpBuf = new Float32Array(1); - - for (var i = 0, ii = fnsIR.length; i < ii; i++) { - fns.push(PDFFunction.fromIR(fnsIR[i])); - } - return function constructStichedFromIRResult(src, srcOffset, dest, destOffset) { var clip = function constructStichedFromIRClip(v, min, max) { @@ -5466,8 +5455,8 @@ var PDFFunction = (function PDFFunctionClosure() { constructPostScript: function PDFFunction_constructPostScript(fn, dict, xref) { - var domain = dict.get('Domain'); - var range = dict.get('Range'); + var domain = toNumberArray(dict.get('Domain')); + var range = toNumberArray(dict.get('Range')); if (!domain) { error('No domain.'); @@ -6417,10 +6406,9 @@ var ColorSpace = (function ColorSpaceClosure() { case 'AlternateCS': var numComps = IR[1]; var alt = IR[2]; - var tintFnIR = IR[3]; + var tintFn = IR[3]; - return new AlternateCS(numComps, ColorSpace.fromIR(alt), - PDFFunction.fromIR(tintFnIR)); + return new AlternateCS(numComps, ColorSpace.fromIR(alt), tintFn); case 'LabCS': whitePoint = IR[1].WhitePoint; blackPoint = IR[1].BlackPoint; @@ -6534,8 +6522,8 @@ var ColorSpace = (function ColorSpaceClosure() { numComps = name.length; } alt = ColorSpace.parseToIR(cs[2], xref, res); - var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3])); - return ['AlternateCS', numComps, alt, tintFnIR]; + var tintFn = PDFFunction.parse(xref, xref.fetchIfRef(cs[3])); + return ['AlternateCS', numComps, alt, tintFn]; case 'Lab': params = xref.fetchIfRef(cs[1]).getAll(); return ['LabCS', params]; @@ -31320,7 +31308,22 @@ var PostScriptParser = (function PostScriptParserClosure() { }; return PostScriptParser; })(); - +function toNumberArray(arr) { + if (!Array.isArray(arr)) { + return null; + } + var length = arr.length; + for (var i = 0; i < length; i++) { + if (typeof arr[i] !== 'number') { + var result = new Array(length); + for (var j = 0; j < length; j++) { + result[j] = +arr[j]; + } + return result; + } + } + return arr; +} var PostScriptTokenTypes = { LBRACE: 0, RBRACE: 1,