Skip to content

Commit eccdfce

Browse files
committed
JS -- Add a sandbox based on quickjs
* 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
1 parent a06f487 commit eccdfce

14 files changed

+886
-243
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ external/webL10n/
77
external/cmapscompress/
88
external/builder/fixtures/
99
external/builder/fixtures_esprima/
10+
external/quickjs/quickjs-eval.js
1011
src/shared/cffStandardStrings.js
1112
src/shared/fonts_utils.js
1213
test/tmp/

external/quickjs/quickjs-eval.js

+42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gulpfile.js

+199-43
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var stream = require("stream");
3333
var exec = require("child_process").exec;
3434
var spawn = require("child_process").spawn;
3535
var spawnSync = require("child_process").spawnSync;
36+
var stripComments = require("gulp-strip-comments");
3637
var streamqueue = require("streamqueue");
3738
var merge = require("merge-stream");
3839
var zip = require("gulp-zip");
@@ -105,6 +106,7 @@ const DEFINES = Object.freeze({
105106
COMPONENTS: false,
106107
LIB: false,
107108
IMAGE_DECODERS: false,
109+
NO_SOURCE_MAP: false,
108110
});
109111

110112
function transform(charEncoding, transformFunction) {
@@ -182,7 +184,8 @@ function createWebpackConfig(defines, output) {
182184
var enableSourceMaps =
183185
!bundleDefines.MOZCENTRAL &&
184186
!bundleDefines.CHROME &&
185-
!bundleDefines.TESTING;
187+
!bundleDefines.TESTING &&
188+
!bundleDefines.NO_SOURCE_MAP;
186189
var skipBabel = bundleDefines.SKIP_BABEL;
187190

188191
// `core-js` (see https://github.com/zloirock/core-js/issues/514),
@@ -343,6 +346,53 @@ function createScriptingBundle(defines) {
343346
.pipe(replaceJSRootName(scriptingAMDName, "pdfjsScripting"));
344347
}
345348

349+
function createSandboxBundle(defines, code) {
350+
var sandboxAMDName = "pdfjs-dist/build/pdf.sandbox";
351+
var sandboxOutputName = "pdf.sandbox.js";
352+
var sandboxFileConfig = createWebpackConfig(defines, {
353+
filename: sandboxOutputName,
354+
library: sandboxAMDName,
355+
libraryTarget: "umd",
356+
umdNamedDefine: true,
357+
});
358+
359+
// The code is the one from the bundle pdf.scripting.js
360+
// so in order to have it in a string (which will be eval-ed
361+
// in the sandbox) we must escape some chars.
362+
// This way we've all the code (initialization+sandbox) in
363+
// the same bundle.
364+
code = code.replace(/["\\\n\t]/g, match => {
365+
if (match === "\n") {
366+
return "\\n";
367+
}
368+
if (match === "\t") {
369+
return "\\t";
370+
}
371+
return `\\${match}`;
372+
});
373+
return (
374+
gulp
375+
.src("./src/scripting_api/quickjs-sandbox.js")
376+
.pipe(webpack2Stream(sandboxFileConfig))
377+
.pipe(replaceWebpackRequire())
378+
.pipe(replaceJSRootName(sandboxAMDName, "pdfjsSandbox"))
379+
// put the code in a string to be eval-ed in the sandbox
380+
.pipe(replace("/* INITIALIZATION_CODE */", `${code}`))
381+
);
382+
}
383+
384+
function buildSandbox(defines, dir) {
385+
const scriptingDefines = builder.merge(defines, { NO_SOURCE_MAP: true });
386+
return createScriptingBundle(scriptingDefines)
387+
.pipe(stripComments())
388+
.pipe(gulp.dest(dir + "build"))
389+
.on("data", file => {
390+
const content = file.contents.toString();
391+
createSandboxBundle(defines, content).pipe(gulp.dest(dir + "build"));
392+
fs.unlinkSync(dir + "build/pdf.scripting.js");
393+
});
394+
}
395+
346396
function createWorkerBundle(defines) {
347397
var workerAMDName = "pdfjs-dist/build/pdf.worker";
348398
var workerOutputName = "pdf.worker.js";
@@ -494,6 +544,25 @@ function makeRef(done, bot) {
494544
});
495545
}
496546

547+
gulp.task("sandbox", function (done) {
548+
const defines = builder.merge(DEFINES, { GENERIC: true });
549+
buildSandbox(defines, GENERIC_DIR);
550+
done();
551+
});
552+
553+
gulp.task("watch-sandbox", function (done) {
554+
const defines = builder.merge(DEFINES, { GENERIC: true });
555+
buildSandbox(defines, GENERIC_DIR);
556+
const watcher = gulp.watch([
557+
"src/scripting_api/*.js",
558+
"external/quickjs/*.js",
559+
]);
560+
watcher.on("change", function () {
561+
buildSandbox(defines, GENERIC_DIR);
562+
});
563+
done();
564+
});
565+
497566
gulp.task("default", function (done) {
498567
console.log("Available tasks:");
499568
var tasks = Object.keys(gulp.registry().tasks());
@@ -762,26 +831,47 @@ function buildGeneric(defines, dir) {
762831
// HTML5 browsers, which implement modern ECMAScript features.
763832
gulp.task(
764833
"generic",
765-
gulp.series("buildnumber", "default_preferences", "locale", function () {
766-
console.log();
767-
console.log("### Creating generic viewer");
768-
var defines = builder.merge(DEFINES, { GENERIC: true });
834+
gulp.series(
835+
"buildnumber",
836+
"default_preferences",
837+
"locale",
838+
function () {
839+
console.log();
840+
console.log("### Creating generic viewer");
841+
var defines = builder.merge(DEFINES, { GENERIC: true });
769842

770-
return buildGeneric(defines, GENERIC_DIR);
771-
})
843+
return buildGeneric(defines, GENERIC_DIR);
844+
},
845+
"sandbox"
846+
)
772847
);
773848

774849
// Builds the generic production viewer that should be compatible with most
775850
// older HTML5 browsers.
776851
gulp.task(
777852
"generic-es5",
778-
gulp.series("buildnumber", "default_preferences", "locale", function () {
779-
console.log();
780-
console.log("### Creating generic (ES5) viewer");
781-
var defines = builder.merge(DEFINES, { GENERIC: true, SKIP_BABEL: false });
853+
gulp.series(
854+
"buildnumber",
855+
"default_preferences",
856+
"locale",
857+
function () {
858+
console.log();
859+
console.log("### Creating generic (ES5) viewer");
860+
var defines = builder.merge(DEFINES, {
861+
GENERIC: true,
862+
SKIP_BABEL: false,
863+
});
782864

783-
return buildGeneric(defines, GENERIC_ES5_DIR);
784-
})
865+
return buildGeneric(defines, GENERIC_ES5_DIR);
866+
},
867+
function () {
868+
const defines = builder.merge(DEFINES, {
869+
GENERIC: true,
870+
SKIP_BABEL: false,
871+
});
872+
return buildSandbox(defines, GENERIC_ES5_DIR);
873+
}
874+
)
785875
);
786876

787877
function buildComponents(defines, dir) {
@@ -908,33 +998,61 @@ function buildMinified(defines, dir) {
908998

909999
gulp.task(
9101000
"minified-pre",
911-
gulp.series("buildnumber", "default_preferences", "locale", function () {
912-
console.log();
913-
console.log("### Creating minified viewer");
914-
var defines = builder.merge(DEFINES, { MINIFIED: true, GENERIC: true });
1001+
gulp.series(
1002+
"buildnumber",
1003+
"default_preferences",
1004+
"locale",
1005+
function () {
1006+
console.log();
1007+
console.log("### Creating minified viewer");
1008+
var defines = builder.merge(DEFINES, { MINIFIED: true, GENERIC: true });
9151009

916-
return buildMinified(defines, MINIFIED_DIR);
917-
})
1010+
return buildSandbox(defines, MINIFIED_DIR);
1011+
},
1012+
function () {
1013+
var defines = builder.merge(DEFINES, { MINIFIED: true, GENERIC: true });
1014+
1015+
return buildMinified(defines, MINIFIED_DIR);
1016+
}
1017+
)
9181018
);
9191019

9201020
gulp.task(
9211021
"minified-es5-pre",
922-
gulp.series("buildnumber", "default_preferences", "locale", function () {
923-
console.log();
924-
console.log("### Creating minified (ES5) viewer");
925-
var defines = builder.merge(DEFINES, {
926-
MINIFIED: true,
927-
GENERIC: true,
928-
SKIP_BABEL: false,
929-
});
1022+
gulp.series(
1023+
"buildnumber",
1024+
"default_preferences",
1025+
"locale",
1026+
function () {
1027+
console.log();
1028+
console.log("### Creating minified (ES5) viewer");
1029+
var defines = builder.merge(DEFINES, {
1030+
MINIFIED: true,
1031+
GENERIC: true,
1032+
SKIP_BABEL: false,
1033+
});
9301034

931-
return buildMinified(defines, MINIFIED_ES5_DIR);
932-
})
1035+
return buildSandbox(defines, MINIFIED_ES5_DIR);
1036+
},
1037+
1038+
function () {
1039+
var defines = builder.merge(DEFINES, {
1040+
MINIFIED: true,
1041+
GENERIC: true,
1042+
SKIP_BABEL: false,
1043+
});
1044+
1045+
return buildMinified(defines, MINIFIED_ES5_DIR);
1046+
}
1047+
)
9331048
);
9341049

9351050
async function parseMinified(dir) {
9361051
var pdfFile = fs.readFileSync(dir + "/build/pdf.js").toString();
9371052
var pdfWorkerFile = fs.readFileSync(dir + "/build/pdf.worker.js").toString();
1053+
var pdfSandboxFile = fs
1054+
.readFileSync(dir + "/build/pdf.sandbox.js")
1055+
.toString();
9381056
var pdfImageDecodersFile = fs
9391057
.readFileSync(dir + "/image_decoders/pdf.image_decoders.js")
9401058
.toString();
@@ -968,6 +1086,10 @@ async function parseMinified(dir) {
9681086
dir + "/build/pdf.worker.min.js",
9691087
(await Terser.minify(pdfWorkerFile, options)).code
9701088
);
1089+
fs.writeFileSync(
1090+
dir + "/build/pdf.sandbox.min.js",
1091+
(await Terser.minify(pdfSandboxFile, options)).code
1092+
);
9711093
fs.writeFileSync(
9721094
dir + "image_decoders/pdf.image_decoders.min.js",
9731095
(await Terser.minify(pdfImageDecodersFile, options)).code
@@ -980,9 +1102,14 @@ async function parseMinified(dir) {
9801102
fs.unlinkSync(dir + "/web/debugger.js");
9811103
fs.unlinkSync(dir + "/build/pdf.js");
9821104
fs.unlinkSync(dir + "/build/pdf.worker.js");
1105+
fs.unlinkSync(dir + "/build/pdf.sandbox.js");
9831106

9841107
fs.renameSync(dir + "/build/pdf.min.js", dir + "/build/pdf.js");
9851108
fs.renameSync(dir + "/build/pdf.worker.min.js", dir + "/build/pdf.worker.js");
1109+
fs.renameSync(
1110+
dir + "/build/pdf.sandbox.min.js",
1111+
dir + "/build/pdf.sandbox.js"
1112+
);
9861113
fs.renameSync(
9871114
dir + "/image_decoders/pdf.image_decoders.min.js",
9881115
dir + "/image_decoders/pdf.image_decoders.js"
@@ -1176,7 +1303,14 @@ gulp.task(
11761303
})
11771304
);
11781305

1179-
gulp.task("chromium", gulp.series("chromium-pre"));
1306+
gulp.task(
1307+
"chromium",
1308+
gulp.series("chromium-pre", function () {
1309+
var defines = builder.merge(DEFINES, { CHROME: true, SKIP_BABEL: false });
1310+
var CHROME_BUILD_CONTENT_DIR = BUILD_DIR + "/chromium/content/";
1311+
return buildSandbox(defines, CHROME_BUILD_CONTENT_DIR);
1312+
})
1313+
);
11801314

11811315
gulp.task("jsdoc", function (done) {
11821316
console.log();
@@ -1276,7 +1410,7 @@ function buildLib(defines, dir) {
12761410
return merge([
12771411
gulp.src(
12781412
[
1279-
"src/{core,display,scripting_api,shared}/*.js",
1413+
"src/{core,display,shared}/*.js",
12801414
"!src/shared/{cffStandardStrings,fonts_utils}.js",
12811415
"src/{pdf,pdf.worker}.js",
12821416
],
@@ -1294,24 +1428,46 @@ function buildLib(defines, dir) {
12941428

12951429
gulp.task(
12961430
"lib",
1297-
gulp.series("buildnumber", "default_preferences", function () {
1298-
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
1431+
gulp.series(
1432+
"buildnumber",
1433+
"default_preferences",
1434+
function () {
1435+
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
12991436

1300-
return buildLib(defines, "build/lib/");
1301-
})
1437+
return buildLib(defines, "build/lib/");
1438+
},
1439+
function () {
1440+
var defines = builder.merge(DEFINES, { GENERIC: true, LIB: true });
1441+
1442+
return buildSandbox(defines, "build/lib/");
1443+
}
1444+
)
13021445
);
13031446

13041447
gulp.task(
13051448
"lib-es5",
1306-
gulp.series("buildnumber", "default_preferences", function () {
1307-
var defines = builder.merge(DEFINES, {
1308-
GENERIC: true,
1309-
LIB: true,
1310-
SKIP_BABEL: false,
1311-
});
1449+
gulp.series(
1450+
"buildnumber",
1451+
"default_preferences",
1452+
function () {
1453+
var defines = builder.merge(DEFINES, {
1454+
GENERIC: true,
1455+
LIB: true,
1456+
SKIP_BABEL: false,
1457+
});
13121458

1313-
return buildLib(defines, "build/lib-es5/");
1314-
})
1459+
return buildLib(defines, "build/lib-es5/");
1460+
},
1461+
function () {
1462+
var defines = builder.merge(DEFINES, {
1463+
GENERIC: true,
1464+
LIB: true,
1465+
SKIP_BABEL: false,
1466+
});
1467+
1468+
return buildSandbox(defines, "build/lib-es5/");
1469+
}
1470+
)
13151471
);
13161472

13171473
function compressPublish(targetName, dir) {

0 commit comments

Comments
 (0)