Replace the XPCOM sandbox with an unsafe eval sandbox
This commit is contained in:
parent
1c6840f9a5
commit
5216f11885
3 changed files with 63 additions and 359 deletions
|
@ -180,11 +180,6 @@ Zotero.Translate.Sandbox = {
|
|||
// just return the item array
|
||||
if(translate._libraryID === false || translate._parentTranslator) {
|
||||
translate.newItems.push(item);
|
||||
if(translate._parentTranslator && Zotero.isFx && !Zotero.isBookmarklet) {
|
||||
// Copy object so it is accessible to parent translator
|
||||
item = translate._sandboxManager.copyObject(item);
|
||||
item.complete = oldItem.complete;
|
||||
}
|
||||
return translate._runHandler("itemDone", item, item);
|
||||
}
|
||||
|
||||
|
@ -239,31 +234,7 @@ Zotero.Translate.Sandbox = {
|
|||
}
|
||||
};
|
||||
|
||||
if (!translate._sandboxManager.sandbox.Promise) {
|
||||
Zotero.debug("Translate: Promise not available in sandbox in _itemDone()");
|
||||
run();
|
||||
return;
|
||||
}
|
||||
|
||||
return new translate._sandboxManager.sandbox.Promise(function (resolve, reject) {
|
||||
try {
|
||||
run(true).then(
|
||||
resolve,
|
||||
function (e) {
|
||||
// Fix wrapping error from sandbox when error is thrown from _saveItems()
|
||||
if (Zotero.isFx) {
|
||||
reject(translate._sandboxManager.copyObject(e));
|
||||
}
|
||||
else {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
return run(asyncTranslator);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -374,13 +345,6 @@ Zotero.Translate.Sandbox = {
|
|||
item = item.wrappedJSObject ? item.wrappedJSObject : item;
|
||||
if(arg1 == "itemDone") {
|
||||
item.complete = translate._sandboxZotero.Item.prototype.complete;
|
||||
} else if(arg1 == "translators" && Zotero.isFx && !Zotero.isBookmarklet) {
|
||||
var translators = new translate._sandboxManager.sandbox.Array();
|
||||
translators = translators.wrappedJSObject || translators;
|
||||
for (var i=0; i<item.length; i++) {
|
||||
translators.push(item[i]);
|
||||
}
|
||||
item = translators;
|
||||
}
|
||||
arg2(obj, item);
|
||||
} catch(e) {
|
||||
|
@ -446,27 +410,6 @@ Zotero.Translate.Sandbox = {
|
|||
return translation._loadTranslator(translator)
|
||||
})
|
||||
.then(function() {
|
||||
if(Zotero.isFx && !Zotero.isBookmarklet) {
|
||||
// do same origin check
|
||||
var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Components.interfaces.nsIScriptSecurityManager);
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
|
||||
var outerSandboxURI = ioService.newURI(typeof translate._sandboxLocation === "object" ?
|
||||
translate._sandboxLocation.location : translate._sandboxLocation, null, null);
|
||||
var innerSandboxURI = ioService.newURI(typeof translation._sandboxLocation === "object" ?
|
||||
translation._sandboxLocation.location : translation._sandboxLocation, null, null);
|
||||
|
||||
try {
|
||||
secMan.checkSameOriginURI(outerSandboxURI, innerSandboxURI, false);
|
||||
} catch(e) {
|
||||
throw new Error("getTranslatorObject() may not be called from web or search "+
|
||||
"translators to web or search translators from different origins.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return translation._prepareTranslation();
|
||||
})
|
||||
.then(function () {
|
||||
|
@ -489,18 +432,6 @@ Zotero.Translate.Sandbox = {
|
|||
return;
|
||||
});
|
||||
};
|
||||
|
||||
if (Zotero.isFx) {
|
||||
for(var i in safeTranslator) {
|
||||
if (typeof(safeTranslator[i]) === "function") {
|
||||
safeTranslator[i] = translate._sandboxManager._makeContentForwarder(function(func) {
|
||||
return function() {
|
||||
func.apply(safeTranslator, this.args.wrappedJSObject || this.args);
|
||||
}
|
||||
}(safeTranslator[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return safeTranslator;
|
||||
},
|
||||
|
@ -547,7 +478,7 @@ Zotero.Translate.Sandbox = {
|
|||
*/
|
||||
"selectItems":function(translate, items, callback) {
|
||||
function transferObject(obj) {
|
||||
return Zotero.isFx && !Zotero.isBookmarklet ? translate._sandboxManager.copyObject(obj) : obj;
|
||||
return obj;
|
||||
}
|
||||
|
||||
if(Zotero.Utilities.isEmpty(items)) {
|
||||
|
@ -1887,16 +1818,9 @@ Zotero.Translate.Base.prototype = {
|
|||
*/
|
||||
"_generateSandbox":function() {
|
||||
Zotero.debug("Translate: Binding sandbox to "+(typeof this._sandboxLocation == "object" ? this._sandboxLocation.document.location : this._sandboxLocation), 4);
|
||||
if (this._parentTranslator && this._parentTranslator._sandboxManager.newChild) {
|
||||
this._sandboxManager = this._parentTranslator._sandboxManager.newChild();
|
||||
} else {
|
||||
this._sandboxManager = new Zotero.Translate.SandboxManager(this._sandboxLocation);
|
||||
}
|
||||
this._sandboxManager = new Zotero.Translate.SandboxManager(this._sandboxLocation);
|
||||
const createArrays = "['creators', 'notes', 'tags', 'seeAlso', 'attachments']";
|
||||
var src = "";
|
||||
if (Zotero.isFx && !Zotero.isBookmarklet) {
|
||||
src = "var Zotero = {};";
|
||||
}
|
||||
src += "Zotero.Item = function (itemType) {"+
|
||||
"var createArrays = "+createArrays+";"+
|
||||
"this.itemType = itemType;"+
|
||||
|
@ -1918,9 +1842,6 @@ Zotero.Translate.Base.prototype = {
|
|||
|
||||
this._sandboxZotero = this._sandboxManager.sandbox.Zotero;
|
||||
|
||||
if(Zotero.isFx) {
|
||||
if(this._sandboxZotero.wrappedJSObject) this._sandboxZotero = this._sandboxZotero.wrappedJSObject;
|
||||
}
|
||||
this._sandboxZotero.Utilities.HTTP = this._sandboxZotero.Utilities;
|
||||
|
||||
this._sandboxZotero.isBookmarklet = Zotero.isBookmarklet || false;
|
||||
|
@ -2132,18 +2053,7 @@ Zotero.Translate.Web.prototype._getSandboxLocation = function() {
|
|||
* Pass document and location to detect* and do* functions
|
||||
*/
|
||||
Zotero.Translate.Web.prototype._getParameters = function() {
|
||||
if (Zotero.Translate.DOMWrapper && Zotero.Translate.DOMWrapper.isWrapped(this.document)) {
|
||||
return [
|
||||
this._sandboxManager.wrap(
|
||||
Zotero.Translate.DOMWrapper.unwrap(this.document),
|
||||
null,
|
||||
this.document.SpecialPowers_wrapperOverrides
|
||||
),
|
||||
this.location
|
||||
];
|
||||
} else {
|
||||
return [this.document, this.location];
|
||||
}
|
||||
return [this.document, this.location];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -2759,9 +2669,6 @@ Zotero.Translate.Search.prototype.complete = function(returnValue, error) {
|
|||
* Pass search item to detect* and do* functions
|
||||
*/
|
||||
Zotero.Translate.Search.prototype._getParameters = function() {
|
||||
if(Zotero.isFx) {
|
||||
return [this._sandboxManager.copyObject(this.search)];
|
||||
}
|
||||
return [this.search];
|
||||
};
|
||||
|
||||
|
@ -2926,7 +2833,7 @@ Zotero.Translate.IO.String.prototype = {
|
|||
this._xmlInvalid = true;
|
||||
throw e;
|
||||
}
|
||||
return (Zotero.isFx && !Zotero.isBookmarklet ? this._sandboxManager.wrap(xml) : xml);
|
||||
return xml;
|
||||
},
|
||||
|
||||
init: function (newMode) {
|
||||
|
|
|
@ -363,271 +363,88 @@ Zotero.Translate.DOMWrapper = new function() {
|
|||
|
||||
/**
|
||||
* @class Manages the translator sandbox
|
||||
* @param {Zotero.Translate} translate
|
||||
* @param {Translate} translate
|
||||
* @param {String|window} sandboxLocation
|
||||
*/
|
||||
Zotero.Translate.SandboxManager = function(sandboxLocation) {
|
||||
// sandboxLocation = Components.classes["@mozilla.org/systemprincipal;1"].createInstance(Components.interfaces.nsIPrincipal);
|
||||
var sandbox = this.sandbox = new Components.utils.Sandbox(
|
||||
sandboxLocation,
|
||||
{
|
||||
wantComponents: false,
|
||||
wantGlobalProperties: [
|
||||
'atob',
|
||||
'XMLHttpRequest'
|
||||
]
|
||||
this.sandbox = {
|
||||
Zotero: {},
|
||||
XPathResult: Components.interfaces.nsIDOMXPathResult,
|
||||
DOMParser: function() {
|
||||
return Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMParser);
|
||||
},
|
||||
XMLSerializer: function() {
|
||||
return Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMSerializer);
|
||||
}
|
||||
);
|
||||
this.sandbox.Zotero = {};
|
||||
|
||||
// import functions missing from global scope into Fx sandbox
|
||||
this.sandbox.XPathResult = Components.interfaces.nsIDOMXPathResult;
|
||||
if(typeof sandboxLocation === "object" && "DOMParser" in sandboxLocation) {
|
||||
this.sandbox.DOMParser = sandboxLocation.DOMParser;
|
||||
} else {
|
||||
this.sandbox.DOMParser = function() {
|
||||
var obj = new sandbox.Object();
|
||||
var wrappedObj = obj.wrappedJSObject || obj;
|
||||
wrappedObj.__exposedProps__ = {"parseFromString":"r"};
|
||||
wrappedObj.parseFromString = function(str, contentType) {
|
||||
var xhr = new sandbox.XMLHttpRequest();
|
||||
xhr.open("GET", "data:"+contentType+";charset=utf-8,"+encodeURIComponent(str), false);
|
||||
xhr.send();
|
||||
if (!xhr.responseXML) throw new Error("error parsing XML");
|
||||
return xhr.responseXML;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
this.sandbox.DOMParser.__exposedProps__ = {"prototype":"r"};
|
||||
this.sandbox.DOMParser.prototype = {};
|
||||
this.sandbox.XMLSerializer = function() {
|
||||
var s = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
|
||||
.createInstance(Components.interfaces.nsIDOMSerializer);
|
||||
var obj = new sandbox.Object();
|
||||
var wrappedObj = obj.wrappedJSObject || obj;
|
||||
wrappedObj.serializeToString = function(doc) {
|
||||
return s.serializeToString(Zotero.Translate.DOMWrapper.unwrap(doc));
|
||||
};
|
||||
return obj;
|
||||
};
|
||||
this.sandbox.XMLSerializer.__exposedProps__ = {"prototype":"r"};
|
||||
this.sandbox.XMLSerializer.prototype = {"__exposedProps__":{"serializeToString":"r"}};
|
||||
|
||||
var expr = "(function(x) { return function() { this.args = arguments; return Function.prototype.apply.call(x, this); }.bind({}); })";
|
||||
this._makeContentForwarder = Components.utils.evalInSandbox(expr, sandbox);
|
||||
|
||||
var _proxy = Components.utils.evalInSandbox('(function (target, x, overrides) {'+
|
||||
' return new Proxy(x, ProxyHandler(target, overrides));'+
|
||||
'})', sandbox);
|
||||
var wrap = this.wrap = function(target, x, overrides) {
|
||||
if (target === null || (typeof target !== "object" && typeof target !== "function")) return target;
|
||||
if (!x) x = new sandbox.Object();
|
||||
return _proxy(target, x, overrides);
|
||||
};
|
||||
var me = this;
|
||||
sandbox.ProxyHandler = this._makeContentForwarder(function() {
|
||||
var target = (this.args.wrappedJSObject || this.args)[0];
|
||||
var overrides = (this.args.wrappedJSObject || this.args)[1] || {};
|
||||
if(target instanceof Components.interfaces.nsISupports) {
|
||||
target = new XPCNativeWrapper(target);
|
||||
}
|
||||
var ret = new sandbox.Object();
|
||||
var wrappedRet = ret.wrappedJSObject || ret;
|
||||
wrappedRet.has = function(x, prop) {
|
||||
return overrides.hasOwnProperty(prop) || prop in target;
|
||||
};
|
||||
wrappedRet.get = function(x, prop, receiver) {
|
||||
if (prop === "SpecialPowers_wrappedObject") return target;
|
||||
if (prop === "SpecialPowers_wrapperOverrides") return overrides;
|
||||
if (prop === "__wrappingManager") return me;
|
||||
var y = overrides.hasOwnProperty(prop) ? overrides[prop] : target[prop];
|
||||
if (y === null || (typeof y !== "object" && typeof y !== "function")) return y;
|
||||
return wrap(y, typeof y === "function" ? function() {
|
||||
var args = Array.prototype.slice.apply(arguments);
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
if (typeof args[i] === "object" && args[i] !== null &&
|
||||
args[i].wrappedJSObject && args[i].wrappedJSObject.SpecialPowers_wrappedObject)
|
||||
args[i] = new XPCNativeWrapper(args[i].wrappedJSObject.SpecialPowers_wrappedObject);
|
||||
}
|
||||
return wrap(y.apply(target, args));
|
||||
} : new sandbox.Object());
|
||||
};
|
||||
wrappedRet.ownKeys = function(x) {
|
||||
return Components.utils.cloneInto(
|
||||
Object.getOwnPropertyNames(target)
|
||||
.concat(Object.getOwnPropertySymbols(target)),
|
||||
sandbox
|
||||
);
|
||||
};
|
||||
wrappedRet.enumerate = function(x) {
|
||||
var y = new sandbox.Array();
|
||||
for (var i in target) y.wrappedJSObject.push(i);
|
||||
return y;
|
||||
};
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Zotero.Translate.SandboxManager.prototype = {
|
||||
/**
|
||||
* Evaluates code in the sandbox
|
||||
* @param {String} code Code to evaluate
|
||||
* @param {String[]} functions Functions to import into the sandbox (rather than leaving
|
||||
* as inner functions)
|
||||
*/
|
||||
"eval":function(code, exported, path) {
|
||||
Components.utils.evalInSandbox(code, this.sandbox, "1.8", path, 1);
|
||||
eval: function(code, functions) {
|
||||
// delete functions to import
|
||||
for (var i in functions) {
|
||||
delete this.sandbox[functions[i]];
|
||||
}
|
||||
|
||||
// Prepend sandbox properties within eval environment (what a mess (1))
|
||||
for (var prop in this.sandbox) {
|
||||
code = 'var ' + prop + ' = this.sandbox.' + prop + ';' + code;
|
||||
}
|
||||
|
||||
// Import inner functions back into the sandbox
|
||||
for (var i in functions) {
|
||||
try {
|
||||
code += 'try{this.sandbox.' + functions[i] + ' = ' + functions[i] + ';}catch(e){}';
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Eval in a closure
|
||||
(function() {
|
||||
eval(code);
|
||||
}).call(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Imports an object into the sandbox
|
||||
*
|
||||
* @param {Object} object Object to be imported (under Zotero)
|
||||
* @param {*} [passTranslateAsFirstArgument] An argument to pass
|
||||
* as the first argument to the function.
|
||||
* @param {Object} [attachTo] The object to attach `object` to.
|
||||
* Defaults to this.sandbox.Zotero
|
||||
* @param {Boolean} passTranslateAsFirstArgument Whether the translate instance should be passed
|
||||
* as the first argument to the function.
|
||||
*/
|
||||
"importObject":function(object, passAsFirstArgument, attachTo) {
|
||||
importObject: function(object, passAsFirstArgument, attachTo) {
|
||||
if(!attachTo) attachTo = this.sandbox.Zotero;
|
||||
if(attachTo.wrappedJSObject) attachTo = attachTo.wrappedJSObject;
|
||||
var newExposedProps = false, sandbox = this.sandbox, me = this;
|
||||
if(!object.__exposedProps__) newExposedProps = {};
|
||||
for(var key in (newExposedProps ? object : object.__exposedProps__)) {
|
||||
let localKey = key;
|
||||
if(newExposedProps) newExposedProps[localKey] = "r";
|
||||
|
||||
var type = typeof object[localKey];
|
||||
var isFunction = type === "function";
|
||||
var isObject = typeof object[localKey] === "object";
|
||||
if(isFunction || isObject) {
|
||||
if(isFunction) {
|
||||
attachTo[localKey] = this._makeContentForwarder(function() {
|
||||
var args = Array.prototype.slice.apply(this.args.wrappedJSObject || this.args);
|
||||
for(var i = 0; i<args.length; i++) {
|
||||
// Make sure we keep XPCNativeWrappers
|
||||
if(args[i] instanceof Components.interfaces.nsISupports) {
|
||||
args[i] = new XPCNativeWrapper(args[i]);
|
||||
}
|
||||
|
||||
for(var key in (object.__exposedProps__ ? object.__exposedProps__ : object)) {
|
||||
if(Function.prototype[key]) continue;
|
||||
if(typeof object[key] === "function" || typeof object[key] === "object") {
|
||||
// magic closures
|
||||
attachTo[key] = new function() {
|
||||
var fn = object[key];
|
||||
return function() {
|
||||
var args = (passAsFirstArgument ? [passAsFirstArgument] : []);
|
||||
for(var i=0; i<arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
if(passAsFirstArgument) args.unshift(passAsFirstArgument);
|
||||
return me.copyObject(object[localKey].apply(object, args));
|
||||
});
|
||||
} else {
|
||||
attachTo[localKey] = new sandbox.Object();
|
||||
|
||||
return fn.apply(object, args);
|
||||
};
|
||||
}
|
||||
|
||||
// attach members
|
||||
if(!(object instanceof Components.interfaces.nsISupports)) {
|
||||
this.importObject(object[localKey], passAsFirstArgument, attachTo[localKey]);
|
||||
}
|
||||
this.importObject(object[key], passAsFirstArgument ? passAsFirstArgument : null, attachTo[key]);
|
||||
} else {
|
||||
attachTo[localKey] = object[localKey];
|
||||
attachTo[key] = object[key];
|
||||
}
|
||||
}
|
||||
|
||||
if(newExposedProps) {
|
||||
attachTo.__exposedProps__ = newExposedProps;
|
||||
} else {
|
||||
attachTo.__exposedProps__ = object.__exposedProps__;
|
||||
}
|
||||
},
|
||||
|
||||
"_canCopy":function(obj) {
|
||||
if(typeof obj !== "object" || obj === null) return false;
|
||||
|
||||
if ((obj.wrappedJSObject && obj.wrappedJSObject.__wrappingManager)
|
||||
|| Zotero.Translate.DOMWrapper.isWrapped(obj)
|
||||
|| "__exposedProps__" in obj
|
||||
|| !["Object", "Array", "Error"].includes(obj.constructor.name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies a JavaScript object to this sandbox
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
*/
|
||||
"copyObject":function(obj, wm) {
|
||||
if(!this._canCopy(obj)) return obj;
|
||||
if(!wm) wm = new WeakMap();
|
||||
switch (obj.constructor.name) {
|
||||
case 'Array':
|
||||
case 'Error':
|
||||
var obj2 = this.sandbox[obj.constructor.name]();
|
||||
break;
|
||||
|
||||
default:
|
||||
var obj2 = this.sandbox.Object();
|
||||
break;
|
||||
}
|
||||
var wobj2 = obj2.wrappedJSObject ? obj2.wrappedJSObject : obj2;
|
||||
for(var i in obj) {
|
||||
if(!obj.hasOwnProperty(i)) continue;
|
||||
|
||||
var prop1 = obj[i];
|
||||
if(this._canCopy(prop1)) {
|
||||
var prop2 = wm.get(prop1);
|
||||
if(prop2 === undefined) {
|
||||
prop2 = this.copyObject(prop1, wm);
|
||||
wm.set(prop1, prop2);
|
||||
}
|
||||
wobj2[i] = prop2;
|
||||
} else {
|
||||
wobj2[i] = prop1;
|
||||
}
|
||||
}
|
||||
return obj2;
|
||||
},
|
||||
|
||||
"newChild":function() {
|
||||
return new Zotero.Translate.ChildSandboxManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
Zotero.Translate.ChildSandboxManager = function(parent) {
|
||||
this._wrappedSandbox = new parent.sandbox.Object();
|
||||
this._wrappedSandbox.Zotero = new parent.sandbox.Object();
|
||||
this.sandbox = this._wrappedSandbox.wrappedJSObject || this._wrappedSandbox;
|
||||
this._parent = parent;
|
||||
}
|
||||
Zotero.Translate.ChildSandboxManager.prototype = {
|
||||
"eval":function(code, functions, path) {
|
||||
// eval in sandbox scope
|
||||
if(functions) {
|
||||
for(var i = 0; i < functions.length; i++) {
|
||||
delete this.sandbox[functions[i]];
|
||||
}
|
||||
}
|
||||
this._parent.sandbox._withSandbox = this._wrappedSandbox;
|
||||
Components.utils.evalInSandbox("with(_withSandbox){"+code+"};", this._parent.sandbox, "1.8", path, 1);
|
||||
if(functions) {
|
||||
for(var i = 0; i < functions.length; i++) {
|
||||
try {
|
||||
this._wrappedSandbox[functions[i]] = Components.utils.evalInSandbox(functions[i], this._parent.sandbox);
|
||||
} catch(e) {}
|
||||
}
|
||||
}
|
||||
this._parent.sandbox._withSandbox = undefined;
|
||||
},
|
||||
"importObject":function(object, passAsFirstArgument, attachTo) {
|
||||
if(!attachTo) attachTo = this.sandbox.Zotero;
|
||||
// Zotero.debug(object);
|
||||
// Zotero.debug(attachTo);
|
||||
this._parent.importObject(object, passAsFirstArgument, attachTo);
|
||||
// Zotero.debug(attachTo);
|
||||
},
|
||||
"copyObject":function(obj) {
|
||||
return this._parent.copyObject(obj);
|
||||
},
|
||||
"newChild":function() {
|
||||
return this._parent.newChild();
|
||||
},
|
||||
"_makeContentForwarder":function(f) {
|
||||
return this._parent._makeContentForwarder(f);
|
||||
},
|
||||
"wrap": function (target, x, overrides) {
|
||||
return this._parent.wrap(target, x, overrides);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -909,7 +726,7 @@ Zotero.Translate.IO.Read.prototype = {
|
|||
this._xmlInvalid = true;
|
||||
throw e;
|
||||
}
|
||||
return (Zotero.isFx ? this._sandboxManager.wrap(xml) : xml);
|
||||
return xml;
|
||||
},
|
||||
|
||||
init: function (newMode) {
|
||||
|
|
|
@ -216,26 +216,6 @@ Zotero.Utilities.Translate.prototype.processDocuments = async function (urls, pr
|
|||
}
|
||||
|
||||
var processDoc = function (doc) {
|
||||
if (Zotero.isFx) {
|
||||
let newLoc = doc.location;
|
||||
let url = Services.io.newURI(newLoc.href, null, null);
|
||||
return processor(
|
||||
// Rewrap document for the sandbox
|
||||
translate._sandboxManager.wrap(
|
||||
Zotero.Translate.DOMWrapper.unwrap(doc),
|
||||
null,
|
||||
// Duplicate overrides from Zotero.HTTP.wrapDocument()
|
||||
{
|
||||
documentURI: newLoc.spec,
|
||||
URL: newLoc.spec,
|
||||
location: new Zotero.HTTP.Location(url),
|
||||
defaultView: new Zotero.HTTP.Window(url)
|
||||
}
|
||||
),
|
||||
newLoc.href
|
||||
);
|
||||
}
|
||||
|
||||
return processor(doc, doc.location.href);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue