@dacely/toildefender 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -48
- package/docs/all-modes-output.demo.js +603 -545
- package/esutils.js +11 -1
- package/obfuscator.js +194 -23
- package/package.json +3 -26
- package/processors/deadCode.js +5 -1
- package/processors/flattener.js +56 -32
- package/processors/identifiers.js +9 -15
- package/processors/methods.js +109 -7
- package/processors/normalizer.js +977 -26
- package/processors/numericVm.js +46 -4
- package/processors/scopes.js +25 -0
- package/processors/uglifier.js +199 -2
- package/processors/variables.js +86 -2
- package/traverser.js +8 -2
package/esutils.js
CHANGED
|
@@ -32,12 +32,22 @@ module.exports = function (logger) {
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
this.canInsertIntoScope = function (scope) {
|
|
36
|
+
if (!scope || !scope.block) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (scope.block.body && (scope.block.body.type == "Program" || scope.block.body.type == "BlockStatement")) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return scope.block.type == "Program" || scope.block.type == "BlockStatement";
|
|
43
|
+
};
|
|
44
|
+
|
|
35
45
|
this.insertIntoScope = function (scope, node, idx) {
|
|
36
46
|
assert.ok(estest.isNode(node));
|
|
37
47
|
|
|
38
48
|
idx = idx || 0;
|
|
39
49
|
|
|
40
|
-
if (scope.block.body.type == "Program" || scope.block.body.type == "BlockStatement") {
|
|
50
|
+
if (scope.block.body && (scope.block.body.type == "Program" || scope.block.body.type == "BlockStatement")) {
|
|
41
51
|
scope.block.body.body.splice(idx, 0, node);
|
|
42
52
|
|
|
43
53
|
Object.defineProperty(node, "veilmark$parent", {
|
package/obfuscator.js
CHANGED
|
@@ -6,14 +6,15 @@ var fs = require("fs");
|
|
|
6
6
|
var assert = require("assert");
|
|
7
7
|
|
|
8
8
|
var _ = require("lodash");
|
|
9
|
-
|
|
10
|
-
var modernBabel = (() => {
|
|
9
|
+
function requireOptional(name) {
|
|
11
10
|
try {
|
|
12
|
-
return require(
|
|
11
|
+
return require(name);
|
|
13
12
|
} catch (e) {
|
|
14
13
|
return null;
|
|
15
14
|
}
|
|
16
|
-
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
var modernParser = requireOptional("@babel/parser");
|
|
17
18
|
var escodegen = require("escodegen");
|
|
18
19
|
var escope = require("escope");
|
|
19
20
|
var esprima = require("esprima");
|
|
@@ -39,8 +40,11 @@ var prNumericVm = require("./processors/numericVm");
|
|
|
39
40
|
var prHealth = require("./processors/health");
|
|
40
41
|
|
|
41
42
|
var defaultOptions = {
|
|
42
|
-
babel:
|
|
43
|
+
babel: false,
|
|
43
44
|
babelTarget: "ie 11",
|
|
45
|
+
babelPreserveAsync: true,
|
|
46
|
+
runtimeHelpers: true,
|
|
47
|
+
simplify: true,
|
|
44
48
|
features: {
|
|
45
49
|
dead_code: true,
|
|
46
50
|
scope: true,
|
|
@@ -163,7 +167,8 @@ exports.features = _.fromPairs(
|
|
|
163
167
|
* @param {Object} options - Configuration.
|
|
164
168
|
* @param {string} options.code - Code of entry point file to be obfuscated.
|
|
165
169
|
* @param {Object.<string, string>} options.modulesCode - Code of all of options.code's depedencies.
|
|
166
|
-
* @param {boolean} [options.babel =
|
|
170
|
+
* @param {boolean} [options.babel = false] - Whether to run the optional Babel transform before obfuscating.
|
|
171
|
+
* @param {boolean} [options.babelPreserveAsync = true] - Whether Babel should leave async/generator syntax for async-aware flattening instead of emitting regenerator helpers.
|
|
167
172
|
* @param {Object.<string, boolean>} [options.features = All enabled] - Feature configuration.
|
|
168
173
|
* @param {logAdapterCallback} [options.logAdapter = Console] - Logging adapter.
|
|
169
174
|
* @param {string} [options.logLevel = "warn"] - Minimum level of shown log messages.
|
|
@@ -248,7 +253,26 @@ exports.do = function (options) {
|
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
function transformModernSyntax(code, label) {
|
|
256
|
+
var modernBabel = requireOptional("@babel/core");
|
|
251
257
|
if (modernBabel) {
|
|
258
|
+
var presetEnvPath;
|
|
259
|
+
try {
|
|
260
|
+
presetEnvPath = require.resolve("@babel/preset-env");
|
|
261
|
+
} catch (e) {
|
|
262
|
+
throw new Error("Babel transform requested, but @babel/preset-env is not installed");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
var presetOptions = {
|
|
266
|
+
modules: "commonjs",
|
|
267
|
+
targets: options.babelTarget,
|
|
268
|
+
useBuiltIns: false
|
|
269
|
+
};
|
|
270
|
+
if (options.babelPreserveAsync !== false) {
|
|
271
|
+
presetOptions.exclude = [
|
|
272
|
+
"@babel/plugin-transform-async-to-generator",
|
|
273
|
+
"@babel/plugin-transform-regenerator"
|
|
274
|
+
];
|
|
275
|
+
}
|
|
252
276
|
var result = modernBabel.transformSync(code, {
|
|
253
277
|
babelrc: false,
|
|
254
278
|
comments: false,
|
|
@@ -257,18 +281,19 @@ exports.do = function (options) {
|
|
|
257
281
|
sourceType: "unambiguous",
|
|
258
282
|
presets: [
|
|
259
283
|
[
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
modules: "commonjs",
|
|
263
|
-
targets: options.babelTarget,
|
|
264
|
-
useBuiltIns: false
|
|
265
|
-
}
|
|
284
|
+
presetEnvPath,
|
|
285
|
+
presetOptions
|
|
266
286
|
]
|
|
267
287
|
]
|
|
268
288
|
});
|
|
269
289
|
return result && result.code || code;
|
|
270
290
|
}
|
|
271
291
|
|
|
292
|
+
var legacyBabel = requireOptional("babel-core");
|
|
293
|
+
if (!legacyBabel) {
|
|
294
|
+
throw new Error("Babel transform requested, but neither @babel/core nor babel-core is installed");
|
|
295
|
+
}
|
|
296
|
+
|
|
272
297
|
var babelOptions = {
|
|
273
298
|
"plugins": [
|
|
274
299
|
"babel-plugin-transform-es2015-arrow-functions",
|
|
@@ -294,6 +319,67 @@ exports.do = function (options) {
|
|
|
294
319
|
};
|
|
295
320
|
return legacyBabel.transform(code, babelOptions).code;
|
|
296
321
|
}
|
|
322
|
+
|
|
323
|
+
function parseSource(code, options) {
|
|
324
|
+
try {
|
|
325
|
+
return esprima.parse(code, options);
|
|
326
|
+
} catch (esprimaError) {
|
|
327
|
+
if (!modernParser) {
|
|
328
|
+
throw esprimaError;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
var parsed = modernParser.parse(code, {
|
|
332
|
+
sourceType: "unambiguous",
|
|
333
|
+
plugins: [
|
|
334
|
+
"estree",
|
|
335
|
+
"classProperties",
|
|
336
|
+
"classPrivateProperties",
|
|
337
|
+
"classPrivateMethods",
|
|
338
|
+
"optionalChaining",
|
|
339
|
+
"nullishCoalescingOperator",
|
|
340
|
+
"objectRestSpread"
|
|
341
|
+
]
|
|
342
|
+
});
|
|
343
|
+
return {
|
|
344
|
+
type: "Program",
|
|
345
|
+
body: parsed.program.body,
|
|
346
|
+
sourceType: parsed.program.sourceType
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function containsNodeType(root, names) {
|
|
352
|
+
var found = false;
|
|
353
|
+
var lookup = {};
|
|
354
|
+
names.forEach(name => {
|
|
355
|
+
lookup[name] = true;
|
|
356
|
+
});
|
|
357
|
+
traverser.traverseEx(root, [], function (node) {
|
|
358
|
+
if (lookup[node.type]) {
|
|
359
|
+
found = true;
|
|
360
|
+
this.abort();
|
|
361
|
+
}
|
|
362
|
+
return node;
|
|
363
|
+
});
|
|
364
|
+
return found;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function hasMangleUnsupportedSyntax(root) {
|
|
368
|
+
return containsNodeType(root, [ "Super" ]);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function dispatcherForMethod(method) {
|
|
372
|
+
if (method.async === true && method.generator === true) {
|
|
373
|
+
return "main$asyncGenerator";
|
|
374
|
+
}
|
|
375
|
+
if (method.async === true) {
|
|
376
|
+
return "main$async";
|
|
377
|
+
}
|
|
378
|
+
if (method.generator === true) {
|
|
379
|
+
return "main$generator";
|
|
380
|
+
}
|
|
381
|
+
return "main";
|
|
382
|
+
}
|
|
297
383
|
|
|
298
384
|
options = _.merge({}, defaultOptions, options); // first argument gets mutated
|
|
299
385
|
if (options.protections.virtualMachine.enabled) {
|
|
@@ -328,6 +414,7 @@ exports.do = function (options) {
|
|
|
328
414
|
};
|
|
329
415
|
|
|
330
416
|
var logger = new Logger(options.logAdapter);
|
|
417
|
+
var customBindAdded = false;
|
|
331
418
|
|
|
332
419
|
var start = Date.now();
|
|
333
420
|
|
|
@@ -349,9 +436,17 @@ exports.do = function (options) {
|
|
|
349
436
|
|
|
350
437
|
// Parse code
|
|
351
438
|
var ast, modulesAST;
|
|
439
|
+
function addCustomBindOnce() {
|
|
440
|
+
if (!customBindAdded) {
|
|
441
|
+
var methods = new prMethods(logger);
|
|
442
|
+
methods.addCustomBind(ast);
|
|
443
|
+
customBindAdded = true;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
352
447
|
doTask("parse", true, () => {
|
|
353
|
-
modulesAST = _.mapValues(options.modulesCode, (code, key) => tryTag(key, () =>
|
|
354
|
-
modulesAST.app = tryTag("app", () =>
|
|
448
|
+
modulesAST = _.mapValues(options.modulesCode, (code, key) => tryTag(key, () => parseSource(code, parseOptions)));
|
|
449
|
+
modulesAST.app = tryTag("app", () => parseSource(options.code, parseOptions));
|
|
355
450
|
});
|
|
356
451
|
|
|
357
452
|
// Merge depedencies into main modules
|
|
@@ -367,7 +462,7 @@ exports.do = function (options) {
|
|
|
367
462
|
});
|
|
368
463
|
|
|
369
464
|
// Simplify graph
|
|
370
|
-
doTask("simplify",
|
|
465
|
+
doTask("simplify", options.simplify !== false, () => {
|
|
371
466
|
var normalizer = new prNormalizer(logger);
|
|
372
467
|
ast = normalizer.simplify(ast);
|
|
373
468
|
});
|
|
@@ -438,6 +533,11 @@ exports.do = function (options) {
|
|
|
438
533
|
methods.removeFirstArguments(method, refers ? method.params.filter(x => x.name.indexOf("$$scope") == 0).length : 0);
|
|
439
534
|
return methods.replaceArgumentReferences(method, true);
|
|
440
535
|
});
|
|
536
|
+
fns.forEach(method => {
|
|
537
|
+
if (method && method.id && methodEntryPoints[method.id.name]) {
|
|
538
|
+
methodEntryPoints[method.id.name].dispatcher = dispatcherForMethod(method);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
441
541
|
if (options.features.control_flow) {
|
|
442
542
|
methods.replaceFunctionCalls(ast, methodEntryPoints);
|
|
443
543
|
fns.forEach(method => {
|
|
@@ -446,25 +546,88 @@ exports.do = function (options) {
|
|
|
446
546
|
}
|
|
447
547
|
});
|
|
448
548
|
|
|
449
|
-
doTask("add_custom_bind", true, () => {
|
|
450
|
-
methods.addCustomBind(ast);
|
|
451
|
-
});
|
|
452
|
-
|
|
453
549
|
doTask("control_flow", options.features.control_flow, () => {
|
|
454
550
|
// Apply control flow flattening and merge methods
|
|
455
551
|
var flattener = new prFlattener(logger, rng);
|
|
456
552
|
var entry = rng.get(), exit = rng.get();
|
|
457
|
-
|
|
553
|
+
var dispatcherGroups = {
|
|
554
|
+
"main$async": {
|
|
555
|
+
async: true,
|
|
556
|
+
fns: []
|
|
557
|
+
},
|
|
558
|
+
"main$generator": {
|
|
559
|
+
generator: true,
|
|
560
|
+
fns: []
|
|
561
|
+
},
|
|
562
|
+
"main$asyncGenerator": {
|
|
563
|
+
async: true,
|
|
564
|
+
generator: true,
|
|
565
|
+
fns: []
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
var syncFns = [];
|
|
569
|
+
|
|
458
570
|
fns.forEach(method => {
|
|
571
|
+
var dispatcher = dispatcherForMethod(method);
|
|
572
|
+
if (dispatcher == "main") {
|
|
573
|
+
syncFns.push(method);
|
|
574
|
+
} else {
|
|
575
|
+
dispatcherGroups[dispatcher].fns.push(method);
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
flattener.addMethod(ast, entry, exit);
|
|
580
|
+
syncFns.forEach(method => {
|
|
459
581
|
methods.bumpArgumentsIndices(method, 1);
|
|
460
582
|
|
|
461
583
|
var entry = methodEntryPoints[method.id.name].entry;
|
|
462
584
|
flattener.addMethod(method.body, entry, exit);
|
|
463
585
|
});
|
|
464
586
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
587
|
+
var syncAst = flattener.getProgram(entry, exit, {
|
|
588
|
+
name: "main",
|
|
589
|
+
invoke: true
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
syncAst = flattener.unifyPrefixStatements(syncAst);
|
|
593
|
+
|
|
594
|
+
var asyncPrograms = [];
|
|
595
|
+
Object.keys(dispatcherGroups).forEach(name => {
|
|
596
|
+
var group = dispatcherGroups[name];
|
|
597
|
+
if (group.fns.length == 0) {
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
var groupFlattener = new prFlattener(logger, rng);
|
|
602
|
+
var groupEntry = methodEntryPoints[group.fns[0].id.name].entry;
|
|
603
|
+
var groupExit = rng.get();
|
|
604
|
+
|
|
605
|
+
group.fns.forEach(method => {
|
|
606
|
+
methods.bumpArgumentsIndices(method, 1);
|
|
607
|
+
|
|
608
|
+
var entry = methodEntryPoints[method.id.name].entry;
|
|
609
|
+
groupFlattener.addMethod(method.body, entry, groupExit);
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
var groupAst = groupFlattener.getProgram(groupEntry, groupExit, {
|
|
613
|
+
name: name,
|
|
614
|
+
async: group.async === true,
|
|
615
|
+
generator: group.generator === true,
|
|
616
|
+
invoke: false
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
groupAst = groupFlattener.unifyPrefixStatements(groupAst);
|
|
620
|
+
asyncPrograms.push(groupAst);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
if (asyncPrograms.length > 0) {
|
|
624
|
+
ast = {
|
|
625
|
+
type: "Program",
|
|
626
|
+
body: Array.prototype.concat.apply([], asyncPrograms.map(program => program.body)).concat(syncAst.body)
|
|
627
|
+
};
|
|
628
|
+
} else {
|
|
629
|
+
ast = syncAst;
|
|
630
|
+
}
|
|
468
631
|
})
|
|
469
632
|
.otherwise(() => {
|
|
470
633
|
if (ast.type == "Program") {
|
|
@@ -476,6 +639,10 @@ exports.do = function (options) {
|
|
|
476
639
|
};
|
|
477
640
|
});
|
|
478
641
|
});
|
|
642
|
+
|
|
643
|
+
doTask("add_runtime_helpers", options.runtimeHelpers !== false && (options.features.scope || options.features.object_packing || options.features.literals || options.babel === false), () => {
|
|
644
|
+
addCustomBindOnce();
|
|
645
|
+
});
|
|
479
646
|
|
|
480
647
|
// Postprocessing
|
|
481
648
|
doTask("postprocessing", true, () => {
|
|
@@ -489,6 +656,10 @@ exports.do = function (options) {
|
|
|
489
656
|
});
|
|
490
657
|
|
|
491
658
|
doTask("mangle", options.features.mangle, () => {
|
|
659
|
+
if (hasMangleUnsupportedSyntax(ast)) {
|
|
660
|
+
logger.warn("Skipping mangle because native modern syntax is not supported by the legacy mangler");
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
492
663
|
var uglifier = new prUglifier(logger);
|
|
493
664
|
if (ast.type == "Program") {
|
|
494
665
|
ast.type = "BlockStatement";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dacely/toildefender",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Modern JavaScript code protection, bytecode virtualization, and obfuscation for the Toil tech stack.",
|
|
5
5
|
"author": "Dacely",
|
|
6
6
|
"contributors": [
|
|
@@ -61,30 +61,7 @@
|
|
|
61
61
|
"docs/all-modes-output.demo.js"
|
|
62
62
|
],
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@babel/
|
|
65
|
-
"@babel/preset-env": "^8.0.2",
|
|
66
|
-
"babel-core": "6.10.4",
|
|
67
|
-
"babel-plugin-check-es2015-constants": "^6.3.13",
|
|
68
|
-
"babel-plugin-transform-es2015-arrow-functions": "^6.3.13",
|
|
69
|
-
"babel-plugin-transform-es2015-block-scoped-functions": "^6.3.13",
|
|
70
|
-
"babel-plugin-transform-es2015-block-scoping": "^6.9.0",
|
|
71
|
-
"babel-plugin-transform-es2015-classes": "^6.9.0",
|
|
72
|
-
"babel-plugin-transform-es2015-computed-properties": "^6.3.13",
|
|
73
|
-
"babel-plugin-transform-es2015-destructuring": "^6.9.0",
|
|
74
|
-
"babel-plugin-transform-es2015-duplicate-keys": "^6.6.0",
|
|
75
|
-
"babel-plugin-transform-es2015-for-of": "^6.6.0",
|
|
76
|
-
"babel-plugin-transform-es2015-function-name": "^6.9.0",
|
|
77
|
-
"babel-plugin-transform-es2015-literals": "^6.3.13",
|
|
78
|
-
"babel-plugin-transform-es2015-modules-commonjs": "^6.6.0",
|
|
79
|
-
"babel-plugin-transform-es2015-object-super": "^6.3.13",
|
|
80
|
-
"babel-plugin-transform-es2015-parameters": "^6.9.0",
|
|
81
|
-
"babel-plugin-transform-es2015-shorthand-properties": "^6.3.13",
|
|
82
|
-
"babel-plugin-transform-es2015-spread": "^6.3.13",
|
|
83
|
-
"babel-plugin-transform-es2015-sticky-regex": "^6.3.13",
|
|
84
|
-
"babel-plugin-transform-es2015-template-literals": "^6.6.0",
|
|
85
|
-
"babel-plugin-transform-es2015-typeof-symbol": "^6.6.0",
|
|
86
|
-
"babel-plugin-transform-es2015-unicode-regex": "^6.3.13",
|
|
87
|
-
"babel-plugin-transform-regenerator": "^6.9.0",
|
|
64
|
+
"@babel/parser": "^8.0.0",
|
|
88
65
|
"escodegen": "^2.1.0",
|
|
89
66
|
"escope": "3.6.0",
|
|
90
67
|
"esprima": "^4.0.1",
|
|
@@ -95,7 +72,7 @@
|
|
|
95
72
|
"minimist": "1.2.0"
|
|
96
73
|
},
|
|
97
74
|
"engines": {
|
|
98
|
-
"node": ">=24.
|
|
75
|
+
"node": ">=24.11.0",
|
|
99
76
|
"npm": ">=10.0.0"
|
|
100
77
|
},
|
|
101
78
|
"publishConfig": {
|
package/processors/deadCode.js
CHANGED
|
@@ -9,6 +9,10 @@ var utils = require("../utils");
|
|
|
9
9
|
|
|
10
10
|
const KEYWORDS = ["await","break","case","catch","class","const","continue","debugger","default","delete","do","else","enum","export","extends","finally","for","function","if","implements","import","in","instanceof","interface","let","new","package","private","protected","public","return","static","super","switch","this","throw","try","typeof","var","void","while","with","yield"];
|
|
11
11
|
|
|
12
|
+
function isClassMethodBody(stack) {
|
|
13
|
+
return stack.some(frame => frame.node.type == "MethodDefinition" || frame.node.type == "ClassBody");
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
module.exports = class DeadCode {
|
|
13
17
|
|
|
14
18
|
constructor (logger) {
|
|
@@ -26,7 +30,7 @@ module.exports = class DeadCode {
|
|
|
26
30
|
var rngAlpha = new utils.UniqueRandomAlpha(3);
|
|
27
31
|
|
|
28
32
|
return traverser.traverse(ast, [], (node, stack) => {
|
|
29
|
-
if (node.type == "BlockStatement") {
|
|
33
|
+
if (node.type == "BlockStatement" && !isClassMethodBody(stack)) {
|
|
30
34
|
for (var i = 0; i < probability; ++i) {
|
|
31
35
|
if (probability - i < Math.random()) {
|
|
32
36
|
continue;
|
package/processors/flattener.js
CHANGED
|
@@ -201,45 +201,69 @@ module.exports = class Flattener {
|
|
|
201
201
|
* Get output switch construct program
|
|
202
202
|
* @param {number} entry Entry point
|
|
203
203
|
* @param {number} exit Exit point
|
|
204
|
+
* @param {Object} options Program options
|
|
204
205
|
* @returns {Program} Switch construct program
|
|
205
206
|
*/
|
|
206
|
-
getProgram (entry, exit) {
|
|
207
|
+
getProgram (entry, exit, options) {
|
|
207
208
|
assert.equal(typeof entry, "number");
|
|
208
209
|
assert.equal(typeof exit, "number");
|
|
210
|
+
|
|
211
|
+
options = options || {};
|
|
212
|
+
var name = options.name || "main";
|
|
213
|
+
var invoke = options.invoke !== false;
|
|
209
214
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
{
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
body:
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
215
|
+
var body = [
|
|
216
|
+
{
|
|
217
|
+
type: "FunctionDeclaration",
|
|
218
|
+
id: { type: "Identifier", name: name },
|
|
219
|
+
params: [
|
|
220
|
+
{ type: "Identifier", name: "state" },
|
|
221
|
+
{ type: "Identifier", name: "scope" }
|
|
222
|
+
],
|
|
223
|
+
body: {
|
|
224
|
+
type: "BlockStatement",
|
|
225
|
+
body: [
|
|
226
|
+
{
|
|
227
|
+
type: "VariableDeclaration",
|
|
228
|
+
kind: "var",
|
|
229
|
+
declarations: [
|
|
230
|
+
{
|
|
231
|
+
type: "VariableDeclarator",
|
|
232
|
+
id: { type: "Identifier", name: "veilmark$tobethrown" },
|
|
233
|
+
init: null
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: "WhileStatement",
|
|
239
|
+
test: { type: "Literal", value: true },
|
|
240
|
+
body: this.getCases(entry, exit)
|
|
241
|
+
}
|
|
242
|
+
]
|
|
230
243
|
},
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
244
|
+
generator: options.generator === true,
|
|
245
|
+
expression: false,
|
|
246
|
+
async: options.async === true
|
|
247
|
+
}
|
|
248
|
+
];
|
|
249
|
+
|
|
250
|
+
if (invoke) {
|
|
251
|
+
body.push({
|
|
252
|
+
type: "ExpressionStatement",
|
|
253
|
+
expression: {
|
|
254
|
+
type: "CallExpression",
|
|
255
|
+
callee: { type: "Identifier", name: name },
|
|
256
|
+
arguments: [
|
|
257
|
+
{ type: "Literal", value: entry },
|
|
258
|
+
{ type: "ObjectExpression", properties: [] }
|
|
259
|
+
]
|
|
241
260
|
}
|
|
242
|
-
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
type: "Program",
|
|
266
|
+
body: body
|
|
243
267
|
};
|
|
244
268
|
}
|
|
245
269
|
|
|
@@ -25,6 +25,10 @@ function objectKey(prop) {
|
|
|
25
25
|
return prop.key.name || prop.key.value;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
function canPackObjectExpression(node) {
|
|
29
|
+
return node.properties.every(prop => prop.type != "SpreadElement" && prop.key);
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
function isBigIntLiteral(node) {
|
|
29
33
|
return node.type == "Literal" && typeof node.value == "bigint";
|
|
30
34
|
}
|
|
@@ -86,21 +90,10 @@ module.exports = class Identifiers {
|
|
|
86
90
|
ast = traverser.traverse(ast, [], (node, stack) => {
|
|
87
91
|
if (node.type == "ObjectExpression") {
|
|
88
92
|
if (options.objectPacking === false) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
});
|
|
94
|
-
return {
|
|
95
|
-
type: "CallExpression",
|
|
96
|
-
callee: { type: "Identifier", name: "veilmark$toObject" },
|
|
97
|
-
arguments: [
|
|
98
|
-
{
|
|
99
|
-
type: "ArrayExpression",
|
|
100
|
-
elements: arr
|
|
101
|
-
}
|
|
102
|
-
]
|
|
103
|
-
};
|
|
93
|
+
return node;
|
|
94
|
+
}
|
|
95
|
+
if (!canPackObjectExpression(node)) {
|
|
96
|
+
return node;
|
|
104
97
|
}
|
|
105
98
|
|
|
106
99
|
var salt = utils.random(1, 65535);
|
|
@@ -117,6 +110,7 @@ module.exports = class Identifiers {
|
|
|
117
110
|
type: "CallExpression",
|
|
118
111
|
callee: { type: "Identifier", name: "veilmark$toObject" },
|
|
119
112
|
arguments: [
|
|
113
|
+
literal(String(utils.hash(schema.join(",")))),
|
|
120
114
|
{
|
|
121
115
|
type: "ArrayExpression",
|
|
122
116
|
elements: schema.map(literal)
|