diff --git a/gnu/local.mk b/gnu/local.mk index ec11b26632..5be445f908 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -785,6 +785,7 @@ dist_patch_DATA = \ %D%/packages/patches/hurd-fix-eth-multiplexer-dependency.patch \ %D%/packages/patches/hydra-disable-darcs-test.patch \ %D%/packages/patches/icecat-avoid-bundled-libraries.patch \ + %D%/packages/patches/icecat-bug-1452075.patch \ %D%/packages/patches/icecat-use-system-graphite2.patch \ %D%/packages/patches/icecat-use-system-harfbuzz.patch \ %D%/packages/patches/id3lib-CVE-2007-4460.patch \ diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm index 1d053152d7..d7f80014be 100644 --- a/gnu/packages/gnuzilla.scm +++ b/gnu/packages/gnuzilla.scm @@ -467,7 +467,14 @@ security standards.") (mozilla-patch "icecat-bug-1388020.patch" "ad9a885b0df4" "1hrk1q9mk59jww55g4lqmaflznk87x3vvjn2mxfgfbbjs8l1cyz4") (mozilla-patch "icecat-bug-1452416.patch" "f89ab96a2532" "1dqchxdyznhgyxhfq0hm0vg1p597hjqflfzigc7j3s5vxf9rg2nv") (mozilla-patch "icecat-bug-1451376.patch" "af885a1bd293" "1wfpqhm2dp4fsx6zbrncngsqz7g2x09b625zcighixrbpvybyww3") - (mozilla-patch "icecat-bug-1444668.patch" "666fc84ec72d" "0lml2wqd4yqidhi364x8r90f78397k2y0kq5z5bv8l8j4bhcnb9v"))) + (mozilla-patch "icecat-bug-1444668.patch" "666fc84ec72d" "0lml2wqd4yqidhi364x8r90f78397k2y0kq5z5bv8l8j4bhcnb9v") + (search-patch "icecat-bug-1452075.patch") + (mozilla-patch "icecat-bug-1393367.patch" "1ab40761a856" "1kgwypy7k5b33jwkni4025za4kcnv5m6klsx4wsswlixmljmkbc7") + (mozilla-patch "icecat-bug-1453339.patch" "0edb8dca7087" "0b30pipqryh311sc97rcmwnx9n8qdlbbz90b2hkybjnprmbhfxrm") + (mozilla-patch "icecat-bug-1452202.patch" "134c728799c1" "16hbwx6fx1hrddsyjjbd3z954ql3pg348xs13h9riyblq8crzmam") + (mozilla-patch "icecat-bug-1411415.patch" "14eab155eaa8" "0wr4xgblxzk4c2gvlnpl7ic1196mrhry1hgwdl1jivq0ji5cbvbd") + (mozilla-patch "icecat-bug-1452619.patch" "2b75d55ccf0e" "1g87aybw6ggv6hyk385bplv0lx63n020gwyq0d6d4pqld48hsm1i") + (mozilla-patch "icecat-bug-1453127.patch" "89857f35df29" "0gzi47svrw5ajdlm3i12193psm702zx70x5h1rwp4gb7gxh4m4d9"))) (modules '((guix build utils))) (snippet '(begin diff --git a/gnu/packages/patches/icecat-bug-1452075.patch b/gnu/packages/patches/icecat-bug-1452075.patch new file mode 100644 index 0000000000..b776640133 --- /dev/null +++ b/gnu/packages/patches/icecat-bug-1452075.patch @@ -0,0 +1,441 @@ +Based on +Adapted to apply cleanly to GNU IceCat. + +# HG changeset patch +# User Ryan VanderMeulen +# Date 1523630807 14400 +# Node ID 608e76ec5ba25cec2271d2b400c7bce2d4c5ef79 +# Parent 10b7f43b536f93151201d44d304c991aa9af5d0c +Bug 1452075 - Backport some upstream pdf.js fixes to ESR52. r=bdahl, r=yury, a=RyanVM + +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 +@@ -24,17 +24,18 @@ const Cc = Components.classes; + const Ci = Components.interfaces; + const Cr = Components.results; + const Cu = Components.utils; + // True only if this is the version of pdf.js that is included with icecat. + 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; + + Cu.import('resource://gre/modules/XPCOMUtils.jsm'); + Cu.import('resource://gre/modules/Services.jsm'); + Cu.import('resource://gre/modules/NetUtil.jsm'); + + XPCOMUtils.defineLazyModuleGetter(this, 'NetworkManager', +@@ -105,21 +106,25 @@ function log(aMsg) { + if (!getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false)) { + return; + } + var msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg); + Services.console.logStringMessage(msg); + 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; + } + + function getLocalizedStrings(path) { + var stringBundle = Cc['@mozilla.org/intl/stringbundle;1']. + getService(Ci.nsIStringBundleService). + createBundle('chrome://pdf.js/locale/' + path); + +@@ -627,31 +632,31 @@ var RangedChromeActions = (function Rang + data = this.dataListener.readData(); + + this.dataListener.onprogress = function (loaded, total) { + self.domWindow.postMessage({ + pdfjsLoadAction: 'progressiveRead', + loaded: loaded, + total: total, + chunk: self.dataListener.readData() +- }, '*'); ++ }, PDF_VIEWER_ORIGIN); + }; + this.dataListener.oncomplete = function () { + self.dataListener = null; + }; + } + + this.domWindow.postMessage({ + pdfjsLoadAction: 'supportsRangedLoading', + rangeEnabled: this.rangeEnabled, + streamingEnabled: this.streamingEnabled, + pdfUrl: this.pdfUrl, + length: this.contentLength, + data: data +- }, '*'); ++ }, PDF_VIEWER_ORIGIN); + + return true; + }; + + proto.requestDataRange = function RangedChromeActions_requestDataRange(args) { + if (!this.rangeEnabled) { + return; + } +@@ -663,23 +668,23 @@ var RangedChromeActions = (function Rang + // errors from chrome code for non-range requests, so this doesn't + // seem high-pri + this.networkManager.requestRange(begin, end, { + onDone: function RangedChromeActions_onDone(args) { + domWindow.postMessage({ + 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); + } + }); + }; + + proto.abortLoading = function RangedChromeActions_abortLoading() { + this.networkManager.abortAllRequests(); + if (this.originalRequest) { + this.originalRequest.cancel(Cr.NS_BINDING_ABORTED); +@@ -718,26 +723,26 @@ var StandardChromeActions = (function St + var self = this; + + this.dataListener.onprogress = function ChromeActions_dataListenerProgress( + loaded, total) { + self.domWindow.postMessage({ + pdfjsLoadAction: 'progress', + loaded: loaded, + total: total +- }, '*'); ++ }, PDF_VIEWER_ORIGIN); + }; + + this.dataListener.oncomplete = + function StandardChromeActions_dataListenerComplete(data, errorCode) { + self.domWindow.postMessage({ + pdfjsLoadAction: 'complete', + data: data, + errorCode: errorCode +- }, '*'); ++ }, PDF_VIEWER_ORIGIN); + + self.dataListener = null; + self.originalRequest = null; + }; + + return true; + }; + +@@ -972,31 +977,35 @@ PdfStreamConverter.prototype = { + var proxy = { + onStartRequest: function(request, context) { + listener.onStartRequest(aRequest, aContext); + }, + onDataAvailable: function(request, context, inputStream, offset, count) { + listener.onDataAvailable(aRequest, aContext, 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( + domWindow, contentDispositionFilename, aRequest, + rangeRequest, streamRequest, dataListener); + } else { + actions = new StandardChromeActions( + 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()) { + var findEventManager = new FindEventManager(domWindow); + findEventManager.bind(); + } + listener.onStopRequest(aRequest, aContext, statusCode); + +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 +@@ -41648,16 +41648,32 @@ + var error = sharedUtil.error; + var info = sharedUtil.info; + var isArray = sharedUtil.isArray; + var isBool = sharedUtil.isBool; + var isDict = corePrimitives.isDict; + var isStream = corePrimitives.isStream; + var PostScriptLexer = corePsParser.PostScriptLexer; + var PostScriptParser = corePsParser.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 PDFFunction = function PDFFunctionClosure() { + var CONSTRUCT_SAMPLED = 0; + var CONSTRUCT_INTERPOLATED = 2; + var CONSTRUCT_STICHED = 3; + var CONSTRUCT_POSTSCRIPT = 4; + return { + getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps, str) { + var i, ii; +@@ -41747,43 +41763,43 @@ + out[index] = [ + arr[i], + arr[i + 1] + ]; + ++index; + } + return out; + } +- var domain = dict.getArray('Domain'); +- var range = dict.getArray('Range'); ++ var domain = toNumberArray(dict.getArray('Domain')); ++ var range = toNumberArray(dict.getArray('Range')); + if (!domain || !range) { + error('No domain or range'); + } + var inputSize = domain.length / 2; + var outputSize = range.length / 2; + 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) { + // No description how cubic spline interpolation works in PDF32000:2008 + // As in poppler, ignoring order, linear interpolation may work as good + info('No support for cubic spline interpolation: ' + order); + } +- var encode = dict.getArray('Encode'); ++ var encode = toNumberArray(dict.getArray('Encode')); + if (!encode) { + encode = []; + for (var i = 0; i < inputSize; ++i) { +- encode.push(0); +- encode.push(size[i] - 1); +- } +- } +- encode = toMultiArray(encode); +- var decode = dict.getArray('Decode'); ++ encode.push([0, size[i] - 1]); ++ } ++ } else { ++ encode = toMultiArray(encode); ++ } ++ var decode = toNumberArray(dict.getArray('Decode')); + if (!decode) { + decode = range; + } else { + decode = toMultiArray(decode); + } + var samples = this.getSampleArray(size, outputSize, bps, str); + return [ + CONSTRUCT_SAMPLED, +@@ -41868,22 +41884,19 @@ + // Decode_2j, Decode_2j+1) + rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]); + // y_j = min(max(r_j, range_2j), range_2j+1) + dest[destOffset + j] = Math.min(Math.max(rj, range[j][0]), range[j][1]); + } + }; + }, + constructInterpolated: function PDFFunction_constructInterpolated(str, dict) { +- var c0 = dict.getArray('C0') || [0]; +- var c1 = dict.getArray('C1') || [1]; ++ var c0 = toNumberArray(dict.getArray('C0')) || [0]; ++ var c1 = toNumberArray(dict.getArray('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) { + diff.push(c1[i] - c0[i]); + } + return [ + CONSTRUCT_INTERPOLATED, + c0, +@@ -41899,49 +41912,45 @@ + return function constructInterpolatedFromIRResult(src, srcOffset, dest, destOffset) { + var x = n === 1 ? src[srcOffset] : Math.pow(src[srcOffset], n); + for (var j = 0; j < length; ++j) { + dest[destOffset + j] = c0[j] + x * diff[j]; + } + }; + }, + constructStiched: function PDFFunction_constructStiched(fn, dict, xref) { +- var domain = dict.getArray('Domain'); ++ var domain = toNumberArray(dict.getArray('Domain')); + if (!domain) { + error('No domain'); + } + var inputSize = domain.length / 2; + if (inputSize !== 1) { + error('Bad domain for stiched function'); + } + 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]))); +- } +- var bounds = dict.getArray('Bounds'); +- var encode = dict.getArray('Encode'); ++ fns.push(PDFFunction.parse(xref, xref.fetchIfRef(fnRefs[i]))); ++ } ++ var bounds = toNumberArray(dict.getArray('Bounds')); ++ var encode = toNumberArray(dict.getArray('Encode')); + return [ + CONSTRUCT_STICHED, + domain, + bounds, + encode, + fns + ]; + }, + constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) { + 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) { + if (v > max) { + v = max; + } else if (v < min) { + v = min; + } + return v; +@@ -41968,18 +41977,18 @@ + // Prevent the value from becoming NaN as a result + // of division by zero (fixes issue6113.pdf). + tmpBuf[0] = dmin === dmax ? rmin : rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); + // call the appropriate function + fns[i](tmpBuf, 0, dest, destOffset); + }; + }, + constructPostScript: function PDFFunction_constructPostScript(fn, dict, xref) { +- var domain = dict.getArray('Domain'); +- var range = dict.getArray('Range'); ++ var domain = toNumberArray(dict.getArray('Domain')); ++ var range = toNumberArray(dict.getArray('Range')); + if (!domain) { + error('No domain.'); + } + if (!range) { + error('No range.'); + } + var lexer = new PostScriptLexer(fn); + var parser = new PostScriptParser(lexer); +@@ -42928,18 +42937,18 @@ + case 'IndexedCS': + var baseIndexedCS = IR[1]; + var hiVal = IR[2]; + var lookup = IR[3]; + return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup); + case 'AlternateCS': + var numComps = IR[1]; + var alt = IR[2]; +- var tintFnIR = IR[3]; +- return new AlternateCS(numComps, ColorSpace.fromIR(alt), PDFFunction.fromIR(tintFnIR)); ++ var tintFn = IR[3]; ++ return new AlternateCS(numComps, ColorSpace.fromIR(alt), tintFn); + case 'LabCS': + whitePoint = IR[1]; + blackPoint = IR[2]; + var range = IR[3]; + return new LabCS(whitePoint, blackPoint, range); + default: + error('Unknown name ' + name); + } +@@ -43067,22 +43076,22 @@ + var name = xref.fetchIfRef(cs[1]); + numComps = 1; + if (isName(name)) { + numComps = 1; + } else if (isArray(name)) { + numComps = name.length; + } + alt = ColorSpace.parseToIR(cs[2], xref, res); +- var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3])); ++ var tintFn = PDFFunction.parse(xref, xref.fetchIfRef(cs[3])); + return [ + 'AlternateCS', + numComps, + alt, +- tintFnIR ++ tintFn + ]; + case 'Lab': + params = xref.fetchIfRef(cs[1]); + whitePoint = params.getArray('WhitePoint'); + blackPoint = params.getArray('BlackPoint'); + var range = params.getArray('Range'); + return [ + 'LabCS', +@@ -52483,9 +52492,9 @@ + initializeWorker(); + } + exports.setPDFNetworkStreamClass = setPDFNetworkStreamClass; + exports.WorkerTask = WorkerTask; + exports.WorkerMessageHandler = WorkerMessageHandler; + })); + }.call(pdfjsLibs)); + exports.WorkerMessageHandler = pdfjsLibs.pdfjsCoreWorker.WorkerMessageHandler; +-})); +\ No newline at end of file ++})); +