Skip to content

Commit

Permalink
JS -- Add a sandbox based on quickjs
Browse files Browse the repository at this point in the history
 * quickjs-eval.js has been generated using https://github.com/mozilla/pdf.js.quickjs/
 * lazy load of sandbox code
 * Rewrite tests to use the sandbox
 * Add a task `watch-sandbox` which update bundle pdf.sandbox.js on change in the sandbox code
  • Loading branch information
calixteman committed Nov 16, 2020
1 parent 83658c9 commit dd18825
Show file tree
Hide file tree
Showing 14 changed files with 758 additions and 86 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ external/webL10n/
external/cmapscompress/
external/builder/fixtures/
external/builder/fixtures_esprima/
external/quickjs/quickjs-eval.js
src/shared/cffStandardStrings.js
src/shared/fonts_utils.js
test/tmp/
Expand Down
42 changes: 42 additions & 0 deletions external/quickjs/quickjs-eval.js

Large diffs are not rendered by default.

165 changes: 139 additions & 26 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
var autoprefixer = require("autoprefixer");
var calc = require("postcss-calc");
var cssvariables = require("postcss-css-variables");
var del = require("del");
var fs = require("fs");
var gulp = require("gulp");
var postcss = require("gulp-postcss");
Expand All @@ -33,6 +34,7 @@ var stream = require("stream");
var exec = require("child_process").exec;
var spawn = require("child_process").spawn;
var spawnSync = require("child_process").spawnSync;
var stripComments = require("gulp-strip-comments");
var streamqueue = require("streamqueue");
var merge = require("merge-stream");
var zip = require("gulp-zip");
Expand Down Expand Up @@ -105,6 +107,7 @@ const DEFINES = Object.freeze({
COMPONENTS: false,
LIB: false,
IMAGE_DECODERS: false,
NO_SOURCE_MAP: false,
});

function transform(charEncoding, transformFunction) {
Expand Down Expand Up @@ -182,7 +185,8 @@ function createWebpackConfig(defines, output) {
var enableSourceMaps =
!bundleDefines.MOZCENTRAL &&
!bundleDefines.CHROME &&
!bundleDefines.TESTING;
!bundleDefines.TESTING &&
!bundleDefines.NO_SOURCE_MAP;
var skipBabel = bundleDefines.SKIP_BABEL;

// `core-js` (see https://github.com/zloirock/core-js/issues/514),
Expand Down Expand Up @@ -342,6 +346,53 @@ function createScriptingBundle(defines) {
.pipe(replaceJSRootName(scriptingAMDName, "pdfjsScripting"));
}

function createSandboxBundle(defines, code) {
var sandboxAMDName = "pdfjs-dist/build/pdf.sandbox";
var sandboxOutputName = "pdf.sandbox.js";
var sandboxFileConfig = createWebpackConfig(defines, {
filename: sandboxOutputName,
library: sandboxAMDName,
libraryTarget: "umd",
umdNamedDefine: true,
});

// The code is the one from the bundle pdf.scripting.js
// so in order to have it in a string (which will be eval-ed
// in the sandbox) we must escape some chars.
// This way we've all the code (initialization+sandbox) in
// the same bundle.
code = code.replace(/["\\\n\t]/g, match => {
if (match === "\n") {
return "\\n";
}
if (match === "\t") {
return "\\t";
}
return `\\${match}`;
});
return (
gulp
.src("./src/scripting_api/quickjs-sandbox.js")
.pipe(webpack2Stream(sandboxFileConfig))
.pipe(replaceWebpackRequire())
.pipe(replaceJSRootName(sandboxAMDName, "pdfjsSandbox"))
// put the code in a string to be eval-ed in the sandbox
.pipe(replace("/* INITIALIZATION_CODE */", `${code}`))
);
}

function buildSandbox(defines, dir) {
const scriptingDefines = builder.merge(defines, { NO_SOURCE_MAP: true });
return createScriptingBundle(scriptingDefines)
.pipe(stripComments())
.pipe(gulp.dest(dir + "build"))
.on("data", file => {
const content = file.contents.toString();
createSandboxBundle(defines, content).pipe(gulp.dest(dir + "build"));
del([dir + "build/pdf.scripting.js"]);
});
}

function createWorkerBundle(defines) {
var workerAMDName = "pdfjs-dist/build/pdf.worker";
var workerOutputName = "pdf.worker.js";
Expand Down Expand Up @@ -493,6 +544,25 @@ function makeRef(done, bot) {
});
}

gulp.task("sandbox", function (done) {
const defines = builder.merge(DEFINES, { GENERIC: true });
buildSandbox(defines, GENERIC_DIR);
done();
});

gulp.task("watch-sandbox", function (done) {
const defines = builder.merge(DEFINES, { GENERIC: true });
buildSandbox(defines, GENERIC_DIR);
const watcher = gulp.watch([
"src/scripting_api/*.js",
"external/quickjs/*.js",
]);
watcher.on("change", function () {
buildSandbox(defines, GENERIC_DIR);
});
done();
});

gulp.task("default", function (done) {
console.log("Available tasks:");
var tasks = Object.keys(gulp.registry().tasks());
Expand Down Expand Up @@ -760,26 +830,47 @@ function buildGeneric(defines, dir) {
// HTML5 browsers, which implement modern ECMAScript features.
gulp.task(
"generic",
gulp.series("buildnumber", "default_preferences", "locale", function () {
console.log();
console.log("### Creating generic viewer");
var defines = builder.merge(DEFINES, { GENERIC: true });
gulp.series(
"buildnumber",
"default_preferences",
"locale",
function () {
console.log();
console.log("### Creating generic viewer");
var defines = builder.merge(DEFINES, { GENERIC: true });

return buildGeneric(defines, GENERIC_DIR);
})
return buildGeneric(defines, GENERIC_DIR);
},
"sandbox"
)
);

// Builds the generic production viewer that should be compatible with most
// older HTML5 browsers.
gulp.task(
"generic-es5",
gulp.series("buildnumber", "default_preferences", "locale", function () {
console.log();
console.log("### Creating generic (ES5) viewer");
var defines = builder.merge(DEFINES, { GENERIC: true, SKIP_BABEL: false });
gulp.series(
"buildnumber",
"default_preferences",
"locale",
function () {
console.log();
console.log("### Creating generic (ES5) viewer");
var defines = builder.merge(DEFINES, {
GENERIC: true,
SKIP_BABEL: false,
});

return buildGeneric(defines, GENERIC_ES5_DIR);
})
return buildGeneric(defines, GENERIC_ES5_DIR);
},
function () {
const defines = builder.merge(DEFINES, {
GENERIC: true,
SKIP_BABEL: false,
});
return buildSandbox(defines, GENERIC_ES5_DIR);
}
)
);

function buildComponents(defines, dir) {
Expand Down Expand Up @@ -1273,7 +1364,7 @@ function buildLib(defines, dir) {
return merge([
gulp.src(
[
"src/{core,display,scripting_api,shared}/*.js",
"src/{core,display,shared}/*.js",
"!src/shared/{cffStandardStrings,fonts_utils}.js",
"src/{pdf,pdf.worker}.js",
],
Expand All @@ -1291,24 +1382,46 @@ function buildLib(defines, dir) {

gulp.task(
"lib",
gulp.series("buildnumber", "default_preferences", function () {
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
gulp.series(
"buildnumber",
"default_preferences",
function () {
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });

return buildLib(defines, "build/lib/");
})
return buildLib(defines, "build/lib/");
},
function () {
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });

return buildSandbox(defines, "build/lib/");
}
)
);

gulp.task(
"lib-es5",
gulp.series("buildnumber", "default_preferences", function () {
var defines = builder.merge(DEFINES, {
GENERIC: true,
LIB: true,
SKIP_BABEL: false,
});
gulp.series(
"buildnumber",
"default_preferences",
function () {
var defines = builder.merge(DEFINES, {
GENERIC: true,
LIB: true,
SKIP_BABEL: false,
});

return buildLib(defines, "build/lib-es5/");
})
return buildLib(defines, "build/lib-es5/");
},
function () {
var defines = builder.merge(DEFINES, {
GENERIC: true,
LIB: true,
SKIP_BABEL: false,
});

return buildSandbox(defines, "build/lib-es5/");
}
)
);

function compressPublish(targetName, dir) {
Expand Down
Loading

0 comments on commit dd18825

Please sign in to comment.