2020-11-09 22:45:02 +09:00
|
|
|
/* Copyright 2020 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.
|
|
|
|
*/
|
|
|
|
|
2020-12-04 20:34:09 +09:00
|
|
|
import ModuleLoader from "../external/quickjs/quickjs-eval.js";
|
|
|
|
|
|
|
|
/* eslint-disable-next-line no-unused-vars */
|
|
|
|
const pdfjsVersion = PDFJSDev.eval("BUNDLE_VERSION");
|
|
|
|
/* eslint-disable-next-line no-unused-vars */
|
|
|
|
const pdfjsBuild = PDFJSDev.eval("BUNDLE_BUILD");
|
2020-11-09 22:45:02 +09:00
|
|
|
|
2020-12-06 00:35:49 +09:00
|
|
|
const TESTING =
|
|
|
|
typeof PDFJSDev === "undefined" || PDFJSDev.test("!PRODUCTION || TESTING");
|
|
|
|
|
2020-11-09 22:45:02 +09:00
|
|
|
class Sandbox {
|
2020-12-06 00:35:49 +09:00
|
|
|
constructor(module) {
|
2020-11-09 22:45:02 +09:00
|
|
|
this._evalInSandbox = module.cwrap("evalInSandbox", null, [
|
|
|
|
"string",
|
|
|
|
"int",
|
|
|
|
]);
|
|
|
|
this._dispatchEventName = null;
|
|
|
|
this._module = module;
|
|
|
|
this._alertOnError = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
create(data) {
|
|
|
|
const sandboxData = JSON.stringify(data);
|
|
|
|
const extra = [
|
|
|
|
"send",
|
|
|
|
"setTimeout",
|
|
|
|
"clearTimeout",
|
|
|
|
"setInterval",
|
|
|
|
"clearInterval",
|
|
|
|
"crackURL",
|
|
|
|
];
|
|
|
|
const extraStr = extra.join(",");
|
|
|
|
let code = [
|
|
|
|
"exports = Object.create(null);",
|
|
|
|
"module = Object.create(null);",
|
|
|
|
// Next line is replaced by code from initialization.js
|
|
|
|
// when we create the bundle for the sandbox.
|
2020-12-04 21:03:24 +09:00
|
|
|
PDFJSDev.eval("PDF_SCRIPTING_JS_SOURCE"),
|
2020-11-09 22:45:02 +09:00
|
|
|
`data = ${sandboxData};`,
|
|
|
|
`module.exports.initSandbox({ data, extra: {${extraStr}}, out: this});`,
|
|
|
|
"delete exports;",
|
|
|
|
"delete module;",
|
|
|
|
"delete data;",
|
|
|
|
];
|
2020-12-06 00:35:49 +09:00
|
|
|
if (!TESTING) {
|
2020-11-09 22:45:02 +09:00
|
|
|
code = code.concat(extra.map(name => `delete ${name};`));
|
|
|
|
code.push("delete debugMe;");
|
|
|
|
}
|
|
|
|
this._evalInSandbox(code.join("\n"), this._alertOnError);
|
|
|
|
this._dispatchEventName = data.dispatchEventName;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatchEvent(event) {
|
|
|
|
if (this._dispatchEventName === null) {
|
|
|
|
throw new Error("Sandbox must have been initialized");
|
|
|
|
}
|
|
|
|
event = JSON.stringify(event);
|
|
|
|
this._evalInSandbox(
|
|
|
|
`app["${this._dispatchEventName}"](${event});`,
|
|
|
|
this._alertOnError
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
dumpMemoryUse() {
|
|
|
|
this._module.ccall("dumpMemoryUse", null, []);
|
|
|
|
}
|
|
|
|
|
|
|
|
nukeSandbox() {
|
|
|
|
this._dispatchEventName = null;
|
|
|
|
this._module.ccall("nukeSandbox", null, []);
|
|
|
|
this._module = null;
|
|
|
|
this._evalInSandbox = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
evalForTesting(code, key) {
|
2020-12-06 00:35:49 +09:00
|
|
|
if (TESTING) {
|
2020-11-09 22:45:02 +09:00
|
|
|
this._evalInSandbox(
|
2020-11-16 22:27:27 +09:00
|
|
|
`try {
|
|
|
|
send({ id: "${key}", result: ${code} });
|
|
|
|
} catch (error) {
|
|
|
|
send({ id: "${key}", result: error.message });
|
|
|
|
}`,
|
2020-11-09 22:45:02 +09:00
|
|
|
this._alertOnError
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-06 00:35:49 +09:00
|
|
|
function QuickJSSandbox() {
|
2020-11-09 22:45:02 +09:00
|
|
|
return ModuleLoader().then(module => {
|
2020-12-06 00:35:49 +09:00
|
|
|
return new Sandbox(module);
|
2020-11-09 22:45:02 +09:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export { QuickJSSandbox };
|