Bug 1452075 - Backport some upstream pdf.js fixes.

This commit is contained in:
Ryan VanderMeulen 2018-04-13 10:46:47 -04:00 • committed by Roy Tam
commit 32c5941589
2 changed files with 60 additions and 42 deletions

View file

@ -29,7 +29,8 @@ const MOZ_CENTRAL = JSON.parse('true');
const PDFJS_EVENT_ID = 'pdf.js.message'; const PDFJS_EVENT_ID = 'pdf.js.message';
const PDF_CONTENT_TYPE = 'application/pdf'; const PDF_CONTENT_TYPE = 'application/pdf';
const PREF_PREFIX = 'pdfjs'; 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_NUMBER_OF_PREFS = 50;
const MAX_STRING_PREF_LENGTH = 128; const MAX_STRING_PREF_LENGTH = 128;
@ -110,11 +111,15 @@ function log(aMsg) {
dump(msg + '\n'); dump(msg + '\n');
} }
function getDOMWindow(aChannel) { function getDOMWindow(aChannel, aPrincipal) {
var requestor = aChannel.notificationCallbacks ? var requestor = aChannel.notificationCallbacks ?
aChannel.notificationCallbacks : aChannel.notificationCallbacks :
aChannel.loadGroup.notificationCallbacks; aChannel.loadGroup.notificationCallbacks;
var win = requestor.getInterface(Components.interfaces.nsIDOMWindow); 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; return win;
} }
@ -632,7 +637,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
loaded: loaded, loaded: loaded,
total: total, total: total,
chunk: self.dataListener.readData() chunk: self.dataListener.readData()
}, '*'); }, PDF_VIEWER_ORIGIN);
}; };
this.dataListener.oncomplete = function () { this.dataListener.oncomplete = function () {
self.dataListener = null; self.dataListener = null;
@ -646,7 +651,7 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
pdfUrl: this.pdfUrl, pdfUrl: this.pdfUrl,
length: this.contentLength, length: this.contentLength,
data: data data: data
}, '*'); }, PDF_VIEWER_ORIGIN);
return true; return true;
}; };
@ -668,13 +673,13 @@ var RangedChromeActions = (function RangedChromeActionsClosure() {
pdfjsLoadAction: 'range', pdfjsLoadAction: 'range',
begin: args.begin, begin: args.begin,
chunk: args.chunk chunk: args.chunk
}, '*'); }, PDF_VIEWER_ORIGIN);
}, },
onProgress: function RangedChromeActions_onProgress(evt) { onProgress: function RangedChromeActions_onProgress(evt) {
domWindow.postMessage({ domWindow.postMessage({
pdfjsLoadAction: 'rangeProgress', pdfjsLoadAction: 'rangeProgress',
loaded: evt.loaded, loaded: evt.loaded,
}, '*'); }, PDF_VIEWER_ORIGIN);
} }
}); });
}; };
@ -723,7 +728,7 @@ var StandardChromeActions = (function StandardChromeActionsClosure() {
pdfjsLoadAction: 'progress', pdfjsLoadAction: 'progress',
loaded: loaded, loaded: loaded,
total: total total: total
}, '*'); }, PDF_VIEWER_ORIGIN);
}; };
this.dataListener.oncomplete = this.dataListener.oncomplete =
@ -732,7 +737,7 @@ var StandardChromeActions = (function StandardChromeActionsClosure() {
pdfjsLoadAction: 'complete', pdfjsLoadAction: 'complete',
data: data, data: data,
errorCode: errorCode errorCode: errorCode
}, '*'); }, PDF_VIEWER_ORIGIN);
self.dataListener = null; self.dataListener = null;
self.originalRequest = null; self.originalRequest = null;
@ -977,10 +982,14 @@ PdfStreamConverter.prototype = {
listener.onDataAvailable(aRequest, aContext, inputStream, listener.onDataAvailable(aRequest, aContext, inputStream,
offset, count); offset, count);
}, },
onStopRequest: function(request, context, statusCode) { onStopRequest(request, context, statusCode) {
// We get the DOM window here instead of before the request since it var domWindow = getDOMWindow(channel, resourcePrincipal);
// may have changed during a redirect. if (!Components.isSuccessCode(statusCode) || !domWindow) {
var domWindow = getDOMWindow(channel); // 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; var actions;
if (rangeRequest || streamRequest) { if (rangeRequest || streamRequest) {
actions = new RangedChromeActions( actions = new RangedChromeActions(
@ -991,7 +1000,7 @@ PdfStreamConverter.prototype = {
domWindow, contentDispositionFilename, aRequest, dataListener); domWindow, contentDispositionFilename, aRequest, dataListener);
} }
var requestListener = new RequestListener(actions); var requestListener = new RequestListener(actions);
domWindow.addEventListener(PDFJS_EVENT_ID, function(event) { domWindow.document.addEventListener(PDFJS_EVENT_ID, function(event) {
requestListener.receive(event); requestListener.receive(event);
}, false, true); }, false, true);
if (actions.supportsIntegratedFind()) { if (actions.supportsIntegratedFind()) {

View file

@ -41653,6 +41653,22 @@
var isStream = corePrimitives.isStream; var isStream = corePrimitives.isStream;
var PostScriptLexer = corePsParser.PostScriptLexer; var PostScriptLexer = corePsParser.PostScriptLexer;
var PostScriptParser = corePsParser.PostScriptParser; 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 PDFFunction = function PDFFunctionClosure() {
var CONSTRUCT_SAMPLED = 0; var CONSTRUCT_SAMPLED = 0;
var CONSTRUCT_INTERPOLATED = 2; var CONSTRUCT_INTERPOLATED = 2;
@ -41752,8 +41768,8 @@
} }
return out; return out;
} }
var domain = dict.getArray('Domain'); var domain = toNumberArray(dict.getArray('Domain'));
var range = dict.getArray('Range'); var range = toNumberArray(dict.getArray('Range'));
if (!domain || !range) { if (!domain || !range) {
error('No domain or range'); error('No domain or range');
} }
@ -41761,7 +41777,7 @@
var outputSize = range.length / 2; var outputSize = range.length / 2;
domain = toMultiArray(domain); domain = toMultiArray(domain);
range = toMultiArray(range); range = toMultiArray(range);
var size = dict.get('Size'); var size = toNumberArray(dict.get('Size'));
var bps = dict.get('BitsPerSample'); var bps = dict.get('BitsPerSample');
var order = dict.get('Order') || 1; var order = dict.get('Order') || 1;
if (order !== 1) { if (order !== 1) {
@ -41769,16 +41785,16 @@
// As in poppler, ignoring order, linear interpolation may work as good // As in poppler, ignoring order, linear interpolation may work as good
info('No support for cubic spline interpolation: ' + order); info('No support for cubic spline interpolation: ' + order);
} }
var encode = dict.getArray('Encode'); var encode = toNumberArray(dict.getArray('Encode'));
if (!encode) { if (!encode) {
encode = []; encode = [];
for (var i = 0; i < inputSize; ++i) { for (var i = 0; i < inputSize; ++i) {
encode.push(0); encode.push([0, size[i] - 1]);
encode.push(size[i] - 1);
} }
} else {
encode = toMultiArray(encode);
} }
encode = toMultiArray(encode); var decode = toNumberArray(dict.getArray('Decode'));
var decode = dict.getArray('Decode');
if (!decode) { if (!decode) {
decode = range; decode = range;
} else { } else {
@ -41873,12 +41889,9 @@
}; };
}, },
constructInterpolated: function PDFFunction_constructInterpolated(str, dict) { constructInterpolated: function PDFFunction_constructInterpolated(str, dict) {
var c0 = dict.getArray('C0') || [0]; var c0 = toNumberArray(dict.getArray('C0')) || [0];
var c1 = dict.getArray('C1') || [1]; var c1 = toNumberArray(dict.getArray('C1')) || [1];
var n = dict.get('N'); var n = dict.get('N');
if (!isArray(c0) || !isArray(c1)) {
error('Illegal dictionary for interpolated function');
}
var length = c0.length; var length = c0.length;
var diff = []; var diff = [];
for (var i = 0; i < length; ++i) { for (var i = 0; i < length; ++i) {
@ -41904,7 +41917,7 @@
}; };
}, },
constructStiched: function PDFFunction_constructStiched(fn, dict, xref) { constructStiched: function PDFFunction_constructStiched(fn, dict, xref) {
var domain = dict.getArray('Domain'); var domain = toNumberArray(dict.getArray('Domain'));
if (!domain) { if (!domain) {
error('No domain'); error('No domain');
} }
@ -41915,10 +41928,10 @@
var fnRefs = dict.get('Functions'); var fnRefs = dict.get('Functions');
var fns = []; var fns = [];
for (var i = 0, ii = fnRefs.length; i < ii; ++i) { 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.getArray('Bounds'); var bounds = toNumberArray(dict.getArray('Bounds'));
var encode = dict.getArray('Encode'); var encode = toNumberArray(dict.getArray('Encode'));
return [ return [
CONSTRUCT_STICHED, CONSTRUCT_STICHED,
domain, domain,
@ -41931,12 +41944,8 @@
var domain = IR[1]; var domain = IR[1];
var bounds = IR[2]; var bounds = IR[2];
var encode = IR[3]; var encode = IR[3];
var fnsIR = IR[4]; var fns = IR[4];
var fns = [];
var tmpBuf = new Float32Array(1); 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) { return function constructStichedFromIRResult(src, srcOffset, dest, destOffset) {
var clip = function constructStichedFromIRClip(v, min, max) { var clip = function constructStichedFromIRClip(v, min, max) {
if (v > max) { if (v > max) {
@ -41973,8 +41982,8 @@
}; };
}, },
constructPostScript: function PDFFunction_constructPostScript(fn, dict, xref) { constructPostScript: function PDFFunction_constructPostScript(fn, dict, xref) {
var domain = dict.getArray('Domain'); var domain = toNumberArray(dict.getArray('Domain'));
var range = dict.getArray('Range'); var range = toNumberArray(dict.getArray('Range'));
if (!domain) { if (!domain) {
error('No domain.'); error('No domain.');
} }
@ -42933,8 +42942,8 @@
case 'AlternateCS': case 'AlternateCS':
var numComps = IR[1]; var numComps = IR[1];
var alt = IR[2]; 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': case 'LabCS':
whitePoint = IR[1]; whitePoint = IR[1];
blackPoint = IR[2]; blackPoint = IR[2];
@ -43072,12 +43081,12 @@
numComps = name.length; numComps = name.length;
} }
alt = ColorSpace.parseToIR(cs[2], xref, res); 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 [ return [
'AlternateCS', 'AlternateCS',
numComps, numComps,
alt, alt,
tintFnIR tintFn
]; ];
case 'Lab': case 'Lab':
params = xref.fetchIfRef(cs[1]); params = xref.fetchIfRef(cs[1]);