js-confuser 1.5.8 → 1.6.0
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/.github/workflows/node.js.yml +2 -2
- package/CHANGELOG.md +69 -0
- package/README.md +143 -7
- package/dist/index.js +33 -4
- package/dist/obfuscator.js +30 -31
- package/dist/options.js +4 -5
- package/dist/order.js +4 -6
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +2 -2
- package/dist/templates/es5.js +18 -0
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +7 -6
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +3 -1
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +82 -55
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +2 -8
- package/dist/transforms/identifier/renameVariables.js +39 -27
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/minify.js +80 -61
- package/dist/transforms/opaquePredicates.js +1 -1
- package/dist/transforms/preparation/preparation.js +2 -2
- package/dist/transforms/preparation.js +231 -0
- package/dist/transforms/renameLabels.js +1 -1
- package/dist/transforms/rgf.js +4 -5
- package/dist/transforms/stack.js +87 -26
- package/dist/transforms/string/encoding.js +150 -179
- package/dist/transforms/string/stringCompression.js +14 -15
- package/dist/transforms/string/stringConcealing.js +25 -8
- package/dist/transforms/string/stringEncoding.js +13 -24
- package/dist/transforms/transform.js +11 -18
- package/dist/traverse.js +24 -18
- package/dist/util/compare.js +2 -2
- package/dist/util/gen.js +15 -0
- package/dist/util/insert.js +31 -7
- package/dist/util/random.js +15 -0
- package/package.json +5 -5
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +26 -29
- package/src/options.ts +17 -21
- package/src/order.ts +4 -8
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +5 -9
- package/src/templates/es5.ts +131 -0
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +8 -6
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +3 -1
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/finalizer.ts +75 -0
- package/src/transforms/flatten.ts +194 -151
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +4 -11
- package/src/transforms/identifier/renameVariables.ts +37 -30
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/minify.ts +116 -77
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +238 -0
- package/src/transforms/renameLabels.ts +2 -2
- package/src/transforms/rgf.ts +6 -7
- package/src/transforms/stack.ts +97 -37
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +41 -11
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +15 -21
- package/src/traverse.ts +24 -12
- package/src/types.ts +11 -2
- package/src/util/compare.ts +2 -2
- package/src/util/gen.ts +21 -1
- package/src/util/insert.ts +49 -9
- package/src/util/random.ts +13 -0
- package/test/code/Cash.test.ts +1 -1
- package/test/code/Dynamic.test.ts +12 -10
- package/test/code/ES6.src.js +136 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +15 -2
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +52 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +44 -1
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +195 -3
- package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
- package/test/transforms/identifier/renameVariables.test.ts +108 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/minify.test.ts +151 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +56 -29
- package/test/transforms/stack.test.ts +91 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +115 -0
- package/test/transforms/string/stringEncoding.test.ts +53 -2
- package/test/transforms/transform.test.ts +66 -0
- package/test/traverse.test.ts +139 -0
- package/test/util/compare.test.ts +23 -1
- package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
- package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
- package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
- package/src/transforms/hexadecimalNumbers.ts +0 -31
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/label.ts +0 -64
- package/src/transforms/preparation/nameConflicts.ts +0 -102
- package/src/transforms/preparation/preparation.ts +0 -176
- package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
- package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _transform = _interopRequireDefault(require("./transform"));
|
|
9
|
+
|
|
10
|
+
var _gen = require("../util/gen");
|
|
11
|
+
|
|
12
|
+
var _order = require("../order");
|
|
13
|
+
|
|
14
|
+
var _insert = require("../util/insert");
|
|
15
|
+
|
|
16
|
+
var _identifiers = require("../util/identifiers");
|
|
17
|
+
|
|
18
|
+
var _compare = require("../util/compare");
|
|
19
|
+
|
|
20
|
+
var _traverse = require("../traverse");
|
|
21
|
+
|
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Preparation arranges the user's code into an AST the obfuscator can easily transform.
|
|
26
|
+
*
|
|
27
|
+
* ExplicitIdentifiers
|
|
28
|
+
* - `object.IDENTIFIER` -> `object['IDENTIFIER']` // Now String Concealing can apply on it
|
|
29
|
+
* - `{ IDENTIFIER: ... }` -> `{ "IDENTIFIER": ... }`
|
|
30
|
+
*
|
|
31
|
+
* ExplicitDeclarations
|
|
32
|
+
* - `var a,b,c` -> `var a; var b; var c;` // Now Stack can apply on it
|
|
33
|
+
*
|
|
34
|
+
* Block
|
|
35
|
+
* - `x => x * 2` -> `x => { return x * 2 }` // Change into Block Statements
|
|
36
|
+
* - `if(true) return` -> `if (true) { return }`
|
|
37
|
+
* - `while(a) a--;` -> `while(a) { a-- }`
|
|
38
|
+
*
|
|
39
|
+
* Label
|
|
40
|
+
* - `for(...) { break; }` -> `_1: for(...) { break _1; }`
|
|
41
|
+
* - `switch(v) { case 1...break }` -> `_2: switch(v) { case 1...break _2; }`
|
|
42
|
+
* - // Control Flow Flattening can safely apply now
|
|
43
|
+
*/
|
|
44
|
+
class Preparation extends _transform.default {
|
|
45
|
+
constructor(o) {
|
|
46
|
+
super(o, _order.ObfuscateOrder.Preparation);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
match(object, parents) {
|
|
50
|
+
return !!object.type;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
transform(object, parents) {
|
|
54
|
+
// ExplicitIdentifiers
|
|
55
|
+
if (object.type === "Identifier") {
|
|
56
|
+
return this.transformExplicitIdentifiers(object, parents);
|
|
57
|
+
} // ExplicitDeclarations
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if (object.type === "VariableDeclaration") {
|
|
61
|
+
return this.transformExplicitDeclarations(object, parents);
|
|
62
|
+
} // Block
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
switch (object.type) {
|
|
66
|
+
/**
|
|
67
|
+
* People use shortcuts and its harder to parse.
|
|
68
|
+
*
|
|
69
|
+
* - `if (a) b()` -> `if (a) { b() }`
|
|
70
|
+
* - Ensures all bodies are `BlockStatement`, not individual expression statements
|
|
71
|
+
*/
|
|
72
|
+
case "IfStatement":
|
|
73
|
+
if (object.consequent.type != "BlockStatement") {
|
|
74
|
+
object.consequent = (0, _gen.BlockStatement)([(0, _insert.clone)(object.consequent)]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (object.alternate && object.alternate.type != "BlockStatement") {
|
|
78
|
+
object.alternate = (0, _gen.BlockStatement)([(0, _insert.clone)(object.alternate)]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
case "WhileStatement":
|
|
84
|
+
case "WithStatement":
|
|
85
|
+
case "ForStatement":
|
|
86
|
+
case "ForOfStatement":
|
|
87
|
+
case "ForInStatement":
|
|
88
|
+
if (object.body.type != "BlockStatement") {
|
|
89
|
+
object.body = (0, _gen.BlockStatement)([(0, _insert.clone)(object.body)]);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
break;
|
|
93
|
+
|
|
94
|
+
case "ArrowFunctionExpression":
|
|
95
|
+
if (object.body.type !== "BlockStatement" && object.expression) {
|
|
96
|
+
object.body = (0, _gen.BlockStatement)([(0, _gen.ReturnStatement)((0, _insert.clone)(object.body))]);
|
|
97
|
+
object.expression = false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
break;
|
|
101
|
+
} // Label
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if ((0, _compare.isLoop)(object) || object.type == "BlockStatement" && parents[0] && parents[0].type == "LabeledStatement" && parents[0].body === object) {
|
|
105
|
+
return this.transformLabel(object, parents);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Ensures every break; statement has a label to point to.
|
|
110
|
+
*
|
|
111
|
+
* This is because Control Flow Flattening adds For Loops which label-less break statements point to the nearest,
|
|
112
|
+
* when they actually need to point to the original statement.
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
transformLabel(object, parents) {
|
|
117
|
+
return () => {
|
|
118
|
+
var currentLabel = parents[0].type == "LabeledStatement" && parents[0].label.name;
|
|
119
|
+
var label = currentLabel || this.getPlaceholder();
|
|
120
|
+
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
121
|
+
if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
|
|
122
|
+
function isContinuableStatement(x) {
|
|
123
|
+
return (0, _compare.isLoop)(x) && x.type !== "SwitchStatement";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function isBreakableStatement(x) {
|
|
127
|
+
return (0, _compare.isLoop)(x) || o.label && x.type == "BlockStatement";
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
var fn = o.type == "ContinueStatement" ? isContinuableStatement : isBreakableStatement;
|
|
131
|
+
var loop = p.find(fn);
|
|
132
|
+
|
|
133
|
+
if (object == loop) {
|
|
134
|
+
if (!o.label) {
|
|
135
|
+
o.label = (0, _gen.Identifier)(label);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}); // Append label statement as this loop has none
|
|
140
|
+
|
|
141
|
+
if (!currentLabel) {
|
|
142
|
+
this.replace(object, (0, _gen.LabeledStatement)(label, { ...object
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Transforms Identifiers (a.IDENTIFIER, {IDENTIFIER:...}) into string properties
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
transformExplicitIdentifiers(object, parents) {
|
|
153
|
+
// Mark functions containing 'eval'
|
|
154
|
+
// Some transformations avoid functions that have 'eval' to not break them
|
|
155
|
+
if (object.name === "eval") {
|
|
156
|
+
var fn = (0, _insert.getFunction)(object, parents);
|
|
157
|
+
|
|
158
|
+
if (fn) {
|
|
159
|
+
fn.$requiresEval = true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
164
|
+
|
|
165
|
+
if (info.isPropertyKey || info.isAccessor) {
|
|
166
|
+
var propIndex = parents.findIndex(x => x.type == "MethodDefinition" || x.type == "Property"); // Don't change constructor!
|
|
167
|
+
|
|
168
|
+
if (propIndex !== -1) {
|
|
169
|
+
if (parents[propIndex].type == "MethodDefinition" && parents[propIndex].kind == "constructor") {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
this.replace(object, (0, _gen.Literal)(object.name));
|
|
175
|
+
parents[0].computed = true;
|
|
176
|
+
parents[0].shorthand = false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Transforms VariableDeclaration into single declarations.
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
transformExplicitDeclarations(object, parents) {
|
|
185
|
+
// for ( var x in ... ) {...}
|
|
186
|
+
var forIndex = parents.findIndex(x => x.type == "ForInStatement" || x.type == "ForOfStatement");
|
|
187
|
+
|
|
188
|
+
if (forIndex != -1 && parents[forIndex].left == (parents[forIndex - 1] || object)) {
|
|
189
|
+
object.declarations.forEach(x => {
|
|
190
|
+
x.init = null;
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
var body = parents[0];
|
|
196
|
+
|
|
197
|
+
if ((0, _compare.isLoop)(body) || body.type == "LabeledStatement") {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (body.type == "ExportNamedDeclaration") {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (!Array.isArray(body)) {
|
|
206
|
+
this.error(new Error("body is " + body.type));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (object.declarations.length > 1) {
|
|
210
|
+
// Make singular
|
|
211
|
+
var index = body.indexOf(object);
|
|
212
|
+
|
|
213
|
+
if (index == -1) {
|
|
214
|
+
this.error(new Error("index is -1"));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
var after = object.declarations.slice(1);
|
|
218
|
+
body.splice(index + 1, 0, ...after.map(x => {
|
|
219
|
+
return {
|
|
220
|
+
type: "VariableDeclaration",
|
|
221
|
+
declarations: [(0, _insert.clone)(x)],
|
|
222
|
+
kind: object.kind
|
|
223
|
+
};
|
|
224
|
+
}));
|
|
225
|
+
object.declarations.length = 1;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
exports.default = Preparation;
|
package/dist/transforms/rgf.js
CHANGED
|
@@ -241,7 +241,8 @@ class RGF extends _transform.default {
|
|
|
241
241
|
// fn
|
|
242
242
|
// In most cases the identifier is being used like this (call expression, or referenced to be called later)
|
|
243
243
|
// Replace it with a simple wrapper function that will pass on the reference array
|
|
244
|
-
var conditionalExpression = (0, _gen.ConditionalExpression)((0, _template.default)("typeof ".concat(referenceArray, "[").concat(index, "] === \"function\" && ").concat(referenceArray, "[").concat(index, "][\"").concat(referenceSignatures[index] || "_", "\"]")).single().expression, (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)(
|
|
244
|
+
var conditionalExpression = (0, _gen.ConditionalExpression)((0, _template.default)("typeof ".concat(referenceArray, "[").concat(index, "] === \"function\" && ").concat(referenceArray, "[").concat(index, "][\"").concat(referenceSignatures[index] || "_", "\"]")).single().expression, (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)( // clone() is required!
|
|
245
|
+
(0, _gen.CallExpression)((0, _insert.clone)(memberExpression), [(0, _gen.Identifier)(referenceArray), (0, _gen.SpreadElement)((0, _gen.Identifier)("arguments"))]))]), (0, _insert.clone)(memberExpression));
|
|
245
246
|
this.replace(o, conditionalExpression);
|
|
246
247
|
}
|
|
247
248
|
}
|
|
@@ -258,8 +259,6 @@ class RGF extends _transform.default {
|
|
|
258
259
|
|
|
259
260
|
let [object, parents] = _ref2;
|
|
260
261
|
var name = object === null || object === void 0 ? void 0 : (_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name;
|
|
261
|
-
var hasName = !!name;
|
|
262
|
-
var params = object.params.map(x => x.name) || [];
|
|
263
262
|
var signature = referenceSignatures[names.get(name)];
|
|
264
263
|
var embeddedName = name || this.getPlaceholder(); // Since `new Function` is completely isolated, create an entire new obfuscator and run remaining transformations.
|
|
265
264
|
// RGF runs early and needs completed code before converting to a string.
|
|
@@ -272,9 +271,9 @@ class RGF extends _transform.default {
|
|
|
272
271
|
integrity: false
|
|
273
272
|
},
|
|
274
273
|
eval: false,
|
|
275
|
-
|
|
274
|
+
stringEncoding: false
|
|
276
275
|
});
|
|
277
|
-
var transforms =
|
|
276
|
+
var transforms = obfuscator.array.filter(x => x.priority > this.priority);
|
|
278
277
|
var embeddedFunction = { ...object,
|
|
279
278
|
type: "FunctionDeclaration",
|
|
280
279
|
id: (0, _gen.Identifier)(embeddedName)
|
package/dist/transforms/stack.js
CHANGED
|
@@ -9,6 +9,8 @@ var _assert = require("assert");
|
|
|
9
9
|
|
|
10
10
|
var _order = require("../order");
|
|
11
11
|
|
|
12
|
+
var _probability = require("../probability");
|
|
13
|
+
|
|
12
14
|
var _template = _interopRequireDefault(require("../templates/template"));
|
|
13
15
|
|
|
14
16
|
var _traverse = require("../traverse");
|
|
@@ -31,9 +33,9 @@ class Stack extends _transform.default {
|
|
|
31
33
|
constructor(o) {
|
|
32
34
|
super(o, _order.ObfuscateOrder.Stack);
|
|
33
35
|
|
|
34
|
-
_defineProperty(this, "
|
|
36
|
+
_defineProperty(this, "mangledExpressionsMade", void 0);
|
|
35
37
|
|
|
36
|
-
this.
|
|
38
|
+
this.mangledExpressionsMade = 0;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
match(object, parents) {
|
|
@@ -41,10 +43,14 @@ class Stack extends _transform.default {
|
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
transform(object, parents) {
|
|
46
|
+
var _this = this;
|
|
47
|
+
|
|
44
48
|
return () => {
|
|
49
|
+
var _getBlockBody$;
|
|
50
|
+
|
|
45
51
|
// Uncaught SyntaxError: Getter must not have any formal parameters.
|
|
46
52
|
// Uncaught SyntaxError: Setter must have exactly one formal parameter
|
|
47
|
-
var propIndex = parents.findIndex(x => x.type
|
|
53
|
+
var propIndex = parents.findIndex(x => x.type === "Property" || x.type === "MethodDefinition");
|
|
48
54
|
|
|
49
55
|
if (propIndex !== -1) {
|
|
50
56
|
if (parents[propIndex].value === (parents[propIndex - 1] || object)) {
|
|
@@ -52,13 +58,40 @@ class Stack extends _transform.default {
|
|
|
52
58
|
return;
|
|
53
59
|
}
|
|
54
60
|
}
|
|
61
|
+
} // Don't apply to functions with 'use strict' directive
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if ((_getBlockBody$ = (0, _insert.getBlockBody)(object.body)[0]) !== null && _getBlockBody$ !== void 0 && _getBlockBody$.directive) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!(0, _probability.ComputeProbabilityMap)(this.options.stack)) {
|
|
69
|
+
return;
|
|
55
70
|
}
|
|
56
71
|
|
|
57
72
|
var defined = new Set();
|
|
58
73
|
var referenced = new Set();
|
|
59
74
|
var illegal = new Set();
|
|
75
|
+
/**
|
|
76
|
+
* Maps old names to new indices
|
|
77
|
+
*/
|
|
78
|
+
|
|
60
79
|
var subscripts = new Map();
|
|
61
80
|
var deadValues = Object.create(null);
|
|
81
|
+
var propertyGen = this.getGenerator();
|
|
82
|
+
|
|
83
|
+
function isTransformableFunction(functionNode) {
|
|
84
|
+
if (functionNode.$requiresEval) return false; // Check for 'this'
|
|
85
|
+
|
|
86
|
+
var isIllegal = false;
|
|
87
|
+
(0, _traverse.walk)(functionNode.body, [], (o, p) => {
|
|
88
|
+
if (o.type === "ThisExpression") {
|
|
89
|
+
isIllegal = true;
|
|
90
|
+
return "EXIT";
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return !isIllegal;
|
|
94
|
+
}
|
|
62
95
|
|
|
63
96
|
function setSubscript(string, index) {
|
|
64
97
|
subscripts.set(string, index + "");
|
|
@@ -74,19 +107,21 @@ class Stack extends _transform.default {
|
|
|
74
107
|
if (o.type == "Identifier") {
|
|
75
108
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
76
109
|
|
|
77
|
-
if (!info.spec.isReferenced) {
|
|
110
|
+
if (!info.spec.isReferenced || info.spec.isExported) {
|
|
78
111
|
return;
|
|
79
112
|
}
|
|
80
113
|
|
|
81
114
|
var c = info.spec.isDefined ? (0, _insert.getDefiningContext)(o, p) : (0, _insert.getReferencingContexts)(o, p).find(x => (0, _insert.isVarContext)(x));
|
|
82
115
|
|
|
83
116
|
if (c !== object) {
|
|
84
|
-
this.log(o.name + " is illegal due to different context");
|
|
117
|
+
// this.log(o.name + " is illegal due to different context");
|
|
85
118
|
illegal.add(o.name);
|
|
86
119
|
}
|
|
87
120
|
|
|
88
121
|
if (info.isClauseParameter || info.isFunctionParameter || (0, _insert.isForInitialize)(o, p)) {
|
|
89
|
-
this.log(
|
|
122
|
+
// this.log(
|
|
123
|
+
// o.name + " is illegal due to clause parameter/function parameter"
|
|
124
|
+
// );
|
|
90
125
|
illegal.add(o.name);
|
|
91
126
|
}
|
|
92
127
|
|
|
@@ -100,19 +135,47 @@ class Stack extends _transform.default {
|
|
|
100
135
|
}
|
|
101
136
|
|
|
102
137
|
if (info.isFunctionDeclaration) {
|
|
103
|
-
|
|
138
|
+
(0, _assert.ok)(p[0].type === "FunctionDeclaration");
|
|
139
|
+
|
|
140
|
+
if (p[0] !== object.body.body[0] || !isTransformableFunction(p[0])) {
|
|
104
141
|
illegal.add(o.name);
|
|
105
142
|
}
|
|
106
|
-
}
|
|
143
|
+
} // The new accessors will either be numbered: [index] or as a string .string
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
var newSubscript = (0, _random.choice)([subscripts.size, propertyGen.generate()]);
|
|
147
|
+
setSubscript(o.name, newSubscript);
|
|
148
|
+
defined.add(o.name); // Stack can only process single VariableDeclarations
|
|
107
149
|
|
|
108
|
-
setSubscript(o.name, subscripts.size);
|
|
109
|
-
defined.add(o.name);
|
|
110
150
|
var varIndex = p.findIndex(x => x.type == "VariableDeclaration");
|
|
111
151
|
|
|
112
|
-
if (varIndex !== -1
|
|
113
|
-
|
|
152
|
+
if (varIndex !== -1) {
|
|
153
|
+
// Invalid 'id' property (must be Identifier)
|
|
154
|
+
if (varIndex !== 2) {
|
|
155
|
+
illegal.add(o.name);
|
|
156
|
+
} else if (p[varIndex].declarations.length > 1) {
|
|
157
|
+
illegal.add(o.name);
|
|
158
|
+
} else {
|
|
159
|
+
var value = p[varIndex].declarations[0].init;
|
|
160
|
+
|
|
161
|
+
if (value && !isTransformableFunction(value)) {
|
|
162
|
+
illegal.add(o.name);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
114
165
|
}
|
|
115
166
|
} else if (info.spec.isReferenced) {
|
|
167
|
+
if (info.spec.isModified) {
|
|
168
|
+
var assignmentIndex = p.findIndex(x => x.type === "AssignmentExpression");
|
|
169
|
+
|
|
170
|
+
if (assignmentIndex !== -1) {
|
|
171
|
+
var value = p[assignmentIndex].right;
|
|
172
|
+
|
|
173
|
+
if (value && !isTransformableFunction(value)) {
|
|
174
|
+
illegal.add(o.name);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
116
179
|
referenced.add(o.name);
|
|
117
180
|
}
|
|
118
181
|
}
|
|
@@ -136,14 +199,15 @@ class Stack extends _transform.default {
|
|
|
136
199
|
return;
|
|
137
200
|
}
|
|
138
201
|
|
|
139
|
-
function
|
|
202
|
+
const numberLiteral = function (number) {
|
|
140
203
|
let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
141
204
|
(0, _assert.ok)(number === number);
|
|
142
205
|
|
|
143
|
-
if (typeof number !== "number" || !Object.keys(deadValues).length || depth >
|
|
206
|
+
if (typeof number !== "number" || !Object.keys(deadValues).length || depth > 4 || (0, _random.chance)(75 + depth * 15 + _this.mangledExpressionsMade / 25)) {
|
|
144
207
|
return (0, _gen.Literal)(number);
|
|
145
208
|
}
|
|
146
209
|
|
|
210
|
+
_this.mangledExpressionsMade++;
|
|
147
211
|
var opposingIndex = (0, _random.choice)(Object.keys(deadValues));
|
|
148
212
|
|
|
149
213
|
if (typeof opposingIndex === "undefined") {
|
|
@@ -153,15 +217,14 @@ class Stack extends _transform.default {
|
|
|
153
217
|
var actualValue = deadValues[opposingIndex];
|
|
154
218
|
(0, _assert.ok)(typeof actualValue === "number");
|
|
155
219
|
return (0, _gen.BinaryExpression)("-", (0, _gen.MemberExpression)((0, _gen.Identifier)(stackName), numberLiteral(isNaN(parseFloat(opposingIndex)) ? opposingIndex : parseFloat(opposingIndex), depth + 1), true), numberLiteral(actualValue - number, depth + 1));
|
|
156
|
-
}
|
|
220
|
+
};
|
|
157
221
|
|
|
158
222
|
function getMemberExpression(index) {
|
|
159
223
|
(0, _assert.ok)(typeof index === "string", typeof index);
|
|
160
224
|
return (0, _gen.MemberExpression)((0, _gen.Identifier)(stackName), numberLiteral(isNaN(parseFloat(index)) ? index : parseFloat(index)), true);
|
|
161
225
|
}
|
|
162
226
|
|
|
163
|
-
var stackName = this.getPlaceholder();
|
|
164
|
-
var made = 1;
|
|
227
|
+
var stackName = this.getPlaceholder() + "_stack";
|
|
165
228
|
|
|
166
229
|
const scan = (o, p) => {
|
|
167
230
|
if (o.type == "Identifier") {
|
|
@@ -216,8 +279,7 @@ class Stack extends _transform.default {
|
|
|
216
279
|
}
|
|
217
280
|
}
|
|
218
281
|
|
|
219
|
-
if (o.type == "Literal" && typeof o.value === "number" && Math.floor(o.value) === o.value && Math.abs(o.value) < 100000 &&
|
|
220
|
-
made++;
|
|
282
|
+
if (o.type == "Literal" && typeof o.value === "number" && Math.floor(o.value) === o.value && Math.abs(o.value) < 100000 && p.find(x => (0, _insert.isFunction)(x)) === object && (0, _random.chance)(50)) {
|
|
221
283
|
return () => {
|
|
222
284
|
this.replaceIdentifierOrLiteral(o, numberLiteral(o.value, 0), p);
|
|
223
285
|
};
|
|
@@ -228,9 +290,9 @@ class Stack extends _transform.default {
|
|
|
228
290
|
object.body.body.forEach((stmt, index) => {
|
|
229
291
|
var isFirst = index == 0;
|
|
230
292
|
|
|
231
|
-
if (isFirst ||
|
|
293
|
+
if (isFirst || (0, _random.chance)(50 - index * 10)) {
|
|
232
294
|
var exprs = [];
|
|
233
|
-
var changes = (0, _random.getRandomInteger)(
|
|
295
|
+
var changes = (0, _random.getRandomInteger)(1, 3);
|
|
234
296
|
|
|
235
297
|
for (var i = 0; i < changes; i++) {
|
|
236
298
|
var expr;
|
|
@@ -240,7 +302,7 @@ class Stack extends _transform.default {
|
|
|
240
302
|
var i = 0;
|
|
241
303
|
|
|
242
304
|
do {
|
|
243
|
-
newIndex = (0, _random.getRandomInteger)(0, 250 + subscripts.size + i * 1000) + "";
|
|
305
|
+
newIndex = (0, _random.choice)([propertyGen.generate(), (0, _random.getRandomInteger)(0, 250 + subscripts.size + i * 1000) + ""]);
|
|
244
306
|
i++;
|
|
245
307
|
} while (valueSet.has(newIndex));
|
|
246
308
|
|
|
@@ -254,9 +316,9 @@ class Stack extends _transform.default {
|
|
|
254
316
|
break;
|
|
255
317
|
|
|
256
318
|
case "deadValue":
|
|
257
|
-
var rand = (0, _random.getRandomInteger)(-
|
|
319
|
+
var rand = (0, _random.getRandomInteger)(-150, 150); // modify an already existing dead value index
|
|
258
320
|
|
|
259
|
-
if (
|
|
321
|
+
if ((0, _random.chance)(50)) {
|
|
260
322
|
var alreadyExisting = (0, _random.choice)(Object.keys(deadValues));
|
|
261
323
|
|
|
262
324
|
if (typeof alreadyExisting === "string") {
|
|
@@ -265,7 +327,6 @@ class Stack extends _transform.default {
|
|
|
265
327
|
}
|
|
266
328
|
|
|
267
329
|
expr = (0, _gen.AssignmentExpression)("=", getMemberExpression(newIndex), numberLiteral(rand));
|
|
268
|
-
(0, _assert.ok)(!subscripts.has(newIndex));
|
|
269
330
|
deadValues[newIndex] = rand;
|
|
270
331
|
break;
|
|
271
332
|
}
|
|
@@ -295,7 +356,7 @@ class Stack extends _transform.default {
|
|
|
295
356
|
|
|
296
357
|
object.params = [(0, _gen.RestElement)((0, _gen.Identifier)(stackName))]; // Ensure the array is correct length
|
|
297
358
|
|
|
298
|
-
(0, _insert.prepend)(object.body, (0, _template.default)("".concat(stackName, "
|
|
359
|
+
(0, _insert.prepend)(object.body, (0, _template.default)("".concat(stackName, "[\"length\"] = ").concat(startingSize)).single());
|
|
299
360
|
};
|
|
300
361
|
}
|
|
301
362
|
|