js-confuser 1.6.0 → 1.7.1
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/CHANGELOG.md +42 -0
- package/README.md +215 -172
- package/dist/constants.js +6 -2
- package/dist/obfuscator.js +0 -6
- package/dist/options.js +4 -4
- package/dist/presets.js +6 -7
- package/dist/templates/crash.js +2 -2
- package/dist/templates/functionLength.js +16 -0
- package/dist/transforms/dispatcher.js +10 -1
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +95 -59
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/flatten.js +224 -147
- package/dist/transforms/identifier/movedDeclarations.js +38 -85
- package/dist/transforms/identifier/renameVariables.js +94 -41
- package/dist/transforms/lock/lock.js +0 -37
- package/dist/transforms/minify.js +2 -2
- package/dist/transforms/rgf.js +145 -244
- package/dist/transforms/stack.js +42 -1
- package/dist/transforms/transform.js +1 -1
- package/dist/util/gen.js +2 -1
- package/dist/util/identifiers.js +38 -4
- package/dist/util/insert.js +24 -3
- package/docs/ControlFlowFlattening.md +595 -0
- package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
- package/docs/ES5.md +197 -0
- package/{Integrity.md → docs/Integrity.md} +2 -2
- package/docs/RGF.md +419 -0
- package/package.json +2 -2
- package/src/constants.ts +3 -0
- package/src/obfuscator.ts +0 -4
- package/src/options.ts +9 -86
- package/src/presets.ts +6 -7
- package/src/templates/crash.ts +10 -10
- package/src/templates/functionLength.ts +14 -0
- package/src/transforms/dispatcher.ts +15 -1
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +135 -130
- package/src/transforms/extraction/objectExtraction.ts +4 -0
- package/src/transforms/flatten.ts +357 -290
- package/src/transforms/identifier/movedDeclarations.ts +50 -96
- package/src/transforms/identifier/renameVariables.ts +120 -56
- package/src/transforms/lock/lock.ts +1 -42
- package/src/transforms/minify.ts +11 -2
- package/src/transforms/rgf.ts +221 -402
- package/src/transforms/stack.ts +62 -0
- package/src/transforms/transform.ts +6 -2
- package/src/util/gen.ts +7 -2
- package/src/util/identifiers.ts +48 -4
- package/src/util/insert.ts +26 -2
- package/test/code/ES6.src.js +24 -0
- package/test/transforms/dispatcher.test.ts +27 -0
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +21 -8
- package/test/transforms/extraction/objectExtraction.test.ts +35 -15
- package/test/transforms/flatten.test.ts +352 -88
- package/test/transforms/identifier/globalConcealing.test.ts +23 -2
- package/test/transforms/identifier/movedDeclarations.test.ts +37 -9
- package/test/transforms/identifier/renameVariables.test.ts +37 -0
- package/test/transforms/lock/integrity.test.ts +24 -0
- package/test/transforms/lock/lock.test.ts +1 -48
- package/test/transforms/minify.test.ts +19 -0
- package/test/transforms/rgf.test.ts +262 -353
- package/test/transforms/stack.test.ts +52 -0
- package/test/util/identifiers.test.ts +134 -1
- package/test/util/insert.test.ts +57 -3
- package/src/transforms/eval.ts +0 -89
- package/src/transforms/identifier/nameRecycling.ts +0 -280
- package/test/transforms/eval.test.ts +0 -131
- package/test/transforms/identifier/nameRecycling.test.ts +0 -205
package/src/transforms/stack.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { walk } from "../traverse";
|
|
|
6
6
|
import {
|
|
7
7
|
AssignmentExpression,
|
|
8
8
|
BinaryExpression,
|
|
9
|
+
CallExpression,
|
|
9
10
|
ExpressionStatement,
|
|
10
11
|
Identifier,
|
|
11
12
|
IfStatement,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
} from "../util/gen";
|
|
19
20
|
import { getIdentifierInfo } from "../util/identifiers";
|
|
20
21
|
import {
|
|
22
|
+
computeFunctionLength,
|
|
21
23
|
getBlockBody,
|
|
22
24
|
getDefiningContext,
|
|
23
25
|
getReferencingContexts,
|
|
@@ -28,10 +30,14 @@ import {
|
|
|
28
30
|
} from "../util/insert";
|
|
29
31
|
import { chance, choice, getRandomInteger } from "../util/random";
|
|
30
32
|
import Transform from "./transform";
|
|
33
|
+
import { noRenameVariablePrefix } from "../constants";
|
|
34
|
+
import { FunctionLengthTemplate } from "../templates/functionLength";
|
|
31
35
|
|
|
32
36
|
export default class Stack extends Transform {
|
|
33
37
|
mangledExpressionsMade: number;
|
|
34
38
|
|
|
39
|
+
functionLengthName: string;
|
|
40
|
+
|
|
35
41
|
constructor(o) {
|
|
36
42
|
super(o, ObfuscateOrder.Stack);
|
|
37
43
|
|
|
@@ -111,8 +117,14 @@ export default class Stack extends Transform {
|
|
|
111
117
|
});
|
|
112
118
|
|
|
113
119
|
var startingSize = subscripts.size;
|
|
120
|
+
var isIllegal = false;
|
|
114
121
|
|
|
115
122
|
walk(object.body, [object, ...parents], (o, p) => {
|
|
123
|
+
if (o.type === "Identifier" && o.name === "arguments") {
|
|
124
|
+
isIllegal = true;
|
|
125
|
+
return "EXIT";
|
|
126
|
+
}
|
|
127
|
+
|
|
116
128
|
if (o.type == "Identifier") {
|
|
117
129
|
var info = getIdentifierInfo(o, p);
|
|
118
130
|
if (!info.spec.isReferenced || info.spec.isExported) {
|
|
@@ -128,6 +140,10 @@ export default class Stack extends Transform {
|
|
|
128
140
|
illegal.add(o.name);
|
|
129
141
|
}
|
|
130
142
|
|
|
143
|
+
if (o.name.startsWith(noRenameVariablePrefix)) {
|
|
144
|
+
illegal.add(o.name);
|
|
145
|
+
}
|
|
146
|
+
|
|
131
147
|
if (
|
|
132
148
|
info.isClauseParameter ||
|
|
133
149
|
info.isFunctionParameter ||
|
|
@@ -200,6 +216,8 @@ export default class Stack extends Transform {
|
|
|
200
216
|
}
|
|
201
217
|
});
|
|
202
218
|
|
|
219
|
+
if (isIllegal) return;
|
|
220
|
+
|
|
203
221
|
illegal.forEach((name) => {
|
|
204
222
|
defined.delete(name);
|
|
205
223
|
referenced.delete(name);
|
|
@@ -467,6 +485,9 @@ export default class Stack extends Transform {
|
|
|
467
485
|
object.body.body.splice(parseInt(index) + i, 0, rotateNodes[index]);
|
|
468
486
|
});
|
|
469
487
|
|
|
488
|
+
// Preserve function.length property
|
|
489
|
+
var originalFunctionLength = computeFunctionLength(object.params);
|
|
490
|
+
|
|
470
491
|
// Set the params for this function to be the stack array
|
|
471
492
|
object.params = [RestElement(Identifier(stackName))];
|
|
472
493
|
|
|
@@ -475,6 +496,47 @@ export default class Stack extends Transform {
|
|
|
475
496
|
object.body,
|
|
476
497
|
Template(`${stackName}["length"] = ${startingSize}`).single()
|
|
477
498
|
);
|
|
499
|
+
|
|
500
|
+
if (originalFunctionLength !== 0) {
|
|
501
|
+
if (!this.functionLengthName) {
|
|
502
|
+
this.functionLengthName = this.getPlaceholder();
|
|
503
|
+
prepend(
|
|
504
|
+
parents[parents.length - 1] || object,
|
|
505
|
+
FunctionLengthTemplate.single({ name: this.functionLengthName })
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if (object.type === "FunctionDeclaration") {
|
|
510
|
+
var body = parents[0];
|
|
511
|
+
if (Array.isArray(body)) {
|
|
512
|
+
var index = body.indexOf(object);
|
|
513
|
+
|
|
514
|
+
body.splice(
|
|
515
|
+
index,
|
|
516
|
+
0,
|
|
517
|
+
ExpressionStatement(
|
|
518
|
+
CallExpression(Identifier(this.functionLengthName), [
|
|
519
|
+
Identifier(object.id.name),
|
|
520
|
+
Literal(originalFunctionLength),
|
|
521
|
+
])
|
|
522
|
+
)
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
} else {
|
|
526
|
+
ok(
|
|
527
|
+
object.type === "FunctionExpression" ||
|
|
528
|
+
object.type === "ArrowFunctionExpression"
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
this.replace(
|
|
532
|
+
object,
|
|
533
|
+
CallExpression(Identifier(this.functionLengthName), [
|
|
534
|
+
{ ...object },
|
|
535
|
+
Literal(originalFunctionLength),
|
|
536
|
+
])
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
478
540
|
};
|
|
479
541
|
}
|
|
480
542
|
}
|
|
@@ -9,7 +9,11 @@ import { ok } from "assert";
|
|
|
9
9
|
import Obfuscator from "../obfuscator";
|
|
10
10
|
import { ObfuscateOptions } from "../options";
|
|
11
11
|
import { ComputeProbabilityMap } from "../probability";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
placeholderVariablePrefix,
|
|
14
|
+
reservedIdentifiers,
|
|
15
|
+
reservedKeywords,
|
|
16
|
+
} from "../constants";
|
|
13
17
|
import { ObfuscateOrder } from "../order";
|
|
14
18
|
|
|
15
19
|
/**
|
|
@@ -176,7 +180,7 @@ export default class Transform {
|
|
|
176
180
|
[...Array(size)]
|
|
177
181
|
.map(() => Math.floor(Math.random() * 10).toString(10))
|
|
178
182
|
.join("");
|
|
179
|
-
return
|
|
183
|
+
return placeholderVariablePrefix + genRanHex(10);
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
/**
|
package/src/util/gen.ts
CHANGED
|
@@ -171,7 +171,12 @@ export function BreakStatement(label?: string) {
|
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
export function Property(
|
|
174
|
+
export function Property(
|
|
175
|
+
key: Node,
|
|
176
|
+
value: Node,
|
|
177
|
+
computed = false,
|
|
178
|
+
kind: "init" | "set" | "get" = "init"
|
|
179
|
+
) {
|
|
175
180
|
if (!key) {
|
|
176
181
|
throw new Error("key is undefined");
|
|
177
182
|
}
|
|
@@ -183,7 +188,7 @@ export function Property(key: Node, value: Node, computed = false) {
|
|
|
183
188
|
key: key,
|
|
184
189
|
computed: computed,
|
|
185
190
|
value: value,
|
|
186
|
-
kind:
|
|
191
|
+
kind: kind,
|
|
187
192
|
method: false,
|
|
188
193
|
shorthand: false,
|
|
189
194
|
};
|
package/src/util/identifiers.ts
CHANGED
|
@@ -30,6 +30,23 @@ export function validateChain(object: Node, parents: Node[]) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
function objectPatternCheck(object: Node, parents: Node[]) {
|
|
34
|
+
var objectPatternIndex = parents.findIndex((x) => x.type === "ObjectPattern");
|
|
35
|
+
if (objectPatternIndex == -1) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var property = parents[objectPatternIndex].properties.find(
|
|
40
|
+
(property) => parents[objectPatternIndex - 2] === property
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (property.key === (parents[objectPatternIndex - 3] || object)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
33
50
|
/**
|
|
34
51
|
* Returns detailed information about the given Identifier node.
|
|
35
52
|
* @param object
|
|
@@ -74,19 +91,43 @@ export function getIdentifierInfo(object: Node, parents: Node[]) {
|
|
|
74
91
|
var isVariableDeclaration =
|
|
75
92
|
varIndex != -1 &&
|
|
76
93
|
parents[varIndex].id == (parents[varIndex - 1] || object) &&
|
|
77
|
-
parents.find((x) => x.type == "VariableDeclaration")
|
|
94
|
+
parents.find((x) => x.type == "VariableDeclaration") &&
|
|
95
|
+
objectPatternCheck(object, parents);
|
|
96
|
+
|
|
97
|
+
var functionIndex = parents.findIndex((x) => isFunction(x));
|
|
98
|
+
|
|
99
|
+
// Assignment pattern check!
|
|
100
|
+
if (isVariableDeclaration) {
|
|
101
|
+
var slicedParents = parents.slice(
|
|
102
|
+
0,
|
|
103
|
+
functionIndex != -1 ? Math.min(varIndex, functionIndex) : varIndex
|
|
104
|
+
);
|
|
105
|
+
var i = 0;
|
|
106
|
+
for (var parent of slicedParents) {
|
|
107
|
+
var childNode = slicedParents[i - 1] || object;
|
|
108
|
+
if (parent.type === "AssignmentPattern" && parent.right === childNode) {
|
|
109
|
+
isVariableDeclaration = false;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
i++;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
78
115
|
|
|
79
116
|
var forIndex = parents.findIndex((x) => x.type == "ForStatement");
|
|
80
117
|
var isForInitializer =
|
|
81
118
|
forIndex != -1 &&
|
|
82
119
|
parents[forIndex].init == (parents[forIndex - 1] || object);
|
|
83
120
|
|
|
84
|
-
var functionIndex = parents.findIndex((x) => isFunction(x));
|
|
85
|
-
|
|
86
121
|
var isFunctionDeclaration =
|
|
87
122
|
functionIndex != -1 &&
|
|
88
123
|
parents[functionIndex].type == "FunctionDeclaration" &&
|
|
89
124
|
parents[functionIndex].id == object;
|
|
125
|
+
|
|
126
|
+
var isNamedFunctionExpression =
|
|
127
|
+
functionIndex != -1 &&
|
|
128
|
+
parents[functionIndex].type === "FunctionExpression" &&
|
|
129
|
+
parents[functionIndex].id === object;
|
|
130
|
+
|
|
90
131
|
var isAFunctionParameter = isFunctionParameter(object, parents);
|
|
91
132
|
|
|
92
133
|
var isClauseParameter = false;
|
|
@@ -112,7 +153,9 @@ export function getIdentifierInfo(object: Node, parents: Node[]) {
|
|
|
112
153
|
|
|
113
154
|
var isAssignmentLeft =
|
|
114
155
|
assignmentIndex !== -1 &&
|
|
115
|
-
parents[assignmentIndex].left ===
|
|
156
|
+
parents[assignmentIndex].left ===
|
|
157
|
+
(parents[assignmentIndex - 1] || object) &&
|
|
158
|
+
objectPatternCheck(object, parents);
|
|
116
159
|
var isAssignmentValue =
|
|
117
160
|
assignmentIndex !== -1 &&
|
|
118
161
|
parents[assignmentIndex].right === (parents[assignmentIndex - 1] || object);
|
|
@@ -272,6 +315,7 @@ export function getIdentifierInfo(object: Node, parents: Node[]) {
|
|
|
272
315
|
isDefined:
|
|
273
316
|
isVariableDeclaration ||
|
|
274
317
|
isFunctionDeclaration ||
|
|
318
|
+
isNamedFunctionExpression ||
|
|
275
319
|
isAFunctionParameter ||
|
|
276
320
|
isClassDeclaration ||
|
|
277
321
|
isClauseParameter ||
|
package/src/util/insert.ts
CHANGED
|
@@ -145,13 +145,13 @@ export function getAllDefiningContexts(o: Node, p: Node[]): Node[] {
|
|
|
145
145
|
// Get Function
|
|
146
146
|
var fn = getFunction(o, p);
|
|
147
147
|
|
|
148
|
-
contexts.push(fn.body);
|
|
148
|
+
// contexts.push(fn.body);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
if (info.isClauseParameter) {
|
|
152
152
|
var catchClause = p.find((x) => x.type === "CatchClause");
|
|
153
153
|
if (catchClause) {
|
|
154
|
-
|
|
154
|
+
return [catchClause];
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -376,3 +376,27 @@ export function isForInitialize(
|
|
|
376
376
|
|
|
377
377
|
return false;
|
|
378
378
|
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Computes the `function.length` property given the parameter nodes.
|
|
382
|
+
*
|
|
383
|
+
* @param params
|
|
384
|
+
* @returns
|
|
385
|
+
*/
|
|
386
|
+
export function computeFunctionLength(params: Node[]): number {
|
|
387
|
+
var count = 0;
|
|
388
|
+
|
|
389
|
+
for (var parameterNode of params) {
|
|
390
|
+
if (
|
|
391
|
+
parameterNode.type === "Identifier" ||
|
|
392
|
+
parameterNode.type === "ObjectPattern" ||
|
|
393
|
+
parameterNode.type === "ArrayPattern"
|
|
394
|
+
) {
|
|
395
|
+
count++;
|
|
396
|
+
} else {
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return count;
|
|
402
|
+
}
|
package/test/code/ES6.src.js
CHANGED
|
@@ -203,6 +203,30 @@ function labeledBreaksAndContinues() {
|
|
|
203
203
|
var variant15 = labeledBreaksAndContinues();
|
|
204
204
|
expect(variant15).toStrictEqual(15);
|
|
205
205
|
|
|
206
|
+
// Variant #16: Function.length property
|
|
207
|
+
var variant16 = function (
|
|
208
|
+
n1,
|
|
209
|
+
n2,
|
|
210
|
+
n3,
|
|
211
|
+
n4,
|
|
212
|
+
n5,
|
|
213
|
+
n6,
|
|
214
|
+
n7,
|
|
215
|
+
n8,
|
|
216
|
+
n9,
|
|
217
|
+
n10,
|
|
218
|
+
n11,
|
|
219
|
+
n12,
|
|
220
|
+
n13,
|
|
221
|
+
n14,
|
|
222
|
+
n15,
|
|
223
|
+
n16
|
|
224
|
+
) {
|
|
225
|
+
var _ = true;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
expect(variant16.length).toStrictEqual(16);
|
|
229
|
+
|
|
206
230
|
// Set 'ranAllTest' to TRUE
|
|
207
231
|
ranAllTest = true;
|
|
208
232
|
|
|
@@ -373,3 +373,30 @@ test("Variant #16: Don't change functions that use 'eval'", async () => {
|
|
|
373
373
|
|
|
374
374
|
expect(TEST_OUTPUT).toStrictEqual(2);
|
|
375
375
|
});
|
|
376
|
+
|
|
377
|
+
// https://github.com/MichaelXF/js-confuser/issues/103
|
|
378
|
+
test("Variant #17: Don't break default parameter, function expression", async () => {
|
|
379
|
+
var output = await JsConfuser(
|
|
380
|
+
`
|
|
381
|
+
var X = "Correct Value";
|
|
382
|
+
|
|
383
|
+
function printX(
|
|
384
|
+
getX = function () {
|
|
385
|
+
return X;
|
|
386
|
+
}
|
|
387
|
+
) {
|
|
388
|
+
var X = "Incorrect Value";
|
|
389
|
+
|
|
390
|
+
TEST_OUTPUT = getX();
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
printX();
|
|
394
|
+
`,
|
|
395
|
+
{ target: "node", dispatcher: true }
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
var TEST_OUTPUT;
|
|
399
|
+
eval(output);
|
|
400
|
+
|
|
401
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
402
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import JsConfuser from "../../../src/index";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
test("Variant #1: Remove duplicate literals", async () => {
|
|
4
4
|
var code = `
|
|
5
5
|
|
|
6
6
|
var TEST_ARRAY = [5,5];
|
|
@@ -15,7 +15,7 @@ it("should remove duplicate literals", async () => {
|
|
|
15
15
|
expect(output).toContain("5");
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
test("Variant #2: Remove duplicate literals and execute correctly", async () => {
|
|
19
19
|
var code = `
|
|
20
20
|
|
|
21
21
|
TEST_ARRAY = [5,5];
|
|
@@ -36,7 +36,7 @@ it("should remove duplicate literals and execute correctly", async () => {
|
|
|
36
36
|
expect(TEST_ARRAY).toEqual([5, 5]);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
test("Variant #3: Remove 'undefined' and 'null' values", async () => {
|
|
40
40
|
var code = `
|
|
41
41
|
|
|
42
42
|
TEST_ARRAY = [undefined,undefined,null,null];
|
|
@@ -60,7 +60,7 @@ it("should remove 'undefined' and 'null' values", async () => {
|
|
|
60
60
|
expect(TEST_ARRAY).toEqual([undefined, undefined, null, null]);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
test("Variant #4: Do not remove empty strings", async () => {
|
|
64
64
|
var code = `
|
|
65
65
|
|
|
66
66
|
TEST_ARRAY = ['','','',''];
|
|
@@ -80,7 +80,7 @@ it("should not remove empty strings", async () => {
|
|
|
80
80
|
expect(TEST_ARRAY).toEqual(["", "", "", ""]);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
test("Variant #5: Work with NaN values", async () => {
|
|
84
84
|
var code = `
|
|
85
85
|
|
|
86
86
|
TEST_ARRAY = [NaN];
|
|
@@ -98,7 +98,7 @@ it("should work with NaN values", async () => {
|
|
|
98
98
|
expect(TEST_ARRAY[0] === TEST_ARRAY[0]).toStrictEqual(false);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
test("Variant #6: Work on property keys", async () => {
|
|
102
102
|
var code = `
|
|
103
103
|
var myObject = {
|
|
104
104
|
myKey: 100
|
|
@@ -124,7 +124,7 @@ it("should work on property keys", async () => {
|
|
|
124
124
|
expect(TEST_VAR).toStrictEqual(100);
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
test("Variant #7: Work on class keys", async () => {
|
|
128
128
|
var code = `
|
|
129
129
|
class MyClass {
|
|
130
130
|
myMethod(){
|
|
@@ -150,7 +150,7 @@ it("should work on class keys", async () => {
|
|
|
150
150
|
expect(TEST_VAR).toStrictEqual(100);
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
test("Variant #8: Do not encode constructor key", async () => {
|
|
154
154
|
var code = `
|
|
155
155
|
class MyClass {
|
|
156
156
|
constructor(){
|
|
@@ -177,3 +177,16 @@ it("should not encode constructor key", async () => {
|
|
|
177
177
|
|
|
178
178
|
expect(TEST_VAR).toStrictEqual(100);
|
|
179
179
|
});
|
|
180
|
+
|
|
181
|
+
// https://github.com/MichaelXF/js-confuser/issues/105
|
|
182
|
+
test("Variant #9: Undefined as variable name", async () => {
|
|
183
|
+
var output = await JsConfuser(
|
|
184
|
+
`
|
|
185
|
+
var undefined = 0;
|
|
186
|
+
var undefined = 1;
|
|
187
|
+
`,
|
|
188
|
+
{ target: "node", duplicateLiteralsRemoval: true }
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
eval(output);
|
|
192
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import JsConfuser from "../../../src/index";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
test("Variant #1: Extract properties", async () => {
|
|
4
4
|
var code = `
|
|
5
5
|
var TEST_OBJECT = {
|
|
6
6
|
TEST_1: "Hello World",
|
|
@@ -34,7 +34,7 @@ it("should extract properties", async () => {
|
|
|
34
34
|
eval(output);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
test("Variant #2: Extract function properties correctly", async () => {
|
|
38
38
|
var code = `
|
|
39
39
|
var TEST_OBJECT = {
|
|
40
40
|
isBoolean: x=>typeof x === "boolean",
|
|
@@ -68,7 +68,7 @@ it("should extract function properties correctly", async () => {
|
|
|
68
68
|
eval(output);
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
test("Variant #3: Not extract properties on with dynamically added keys", async () => {
|
|
72
72
|
var code = `
|
|
73
73
|
var TEST_OBJECT = {
|
|
74
74
|
first_key: 1
|
|
@@ -100,7 +100,7 @@ it("should not extract properties on with dynamically added keys", async () => {
|
|
|
100
100
|
eval(output);
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
test("Variant #4: Not extract properties on with dynamically added keys even when in nested contexts", async () => {
|
|
104
104
|
var code = `
|
|
105
105
|
var TEST_OBJECT = {
|
|
106
106
|
first_key: 1
|
|
@@ -135,7 +135,7 @@ it("should not extract properties on with dynamically added keys even when in ne
|
|
|
135
135
|
eval(output);
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
test("Variant #5: Not extract properties on objects with computed properties", async () => {
|
|
139
139
|
var code = `
|
|
140
140
|
|
|
141
141
|
var key = "111"
|
|
@@ -166,7 +166,7 @@ it("should not extract properties on objects with computed properties", async ()
|
|
|
166
166
|
eval(output);
|
|
167
167
|
});
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
test("Variant #6: Not extract properties on objects with computed properties (string)", async () => {
|
|
170
170
|
var code = `
|
|
171
171
|
|
|
172
172
|
var v = "key";
|
|
@@ -197,7 +197,7 @@ it("should not extract properties on objects with computed properties (string)",
|
|
|
197
197
|
eval(output);
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
test("Variant #7: Not extract properties on objects when the object is referenced independently", async () => {
|
|
201
201
|
var code = `
|
|
202
202
|
|
|
203
203
|
var TEST_OBJECT = {
|
|
@@ -229,7 +229,7 @@ it("should not extract properties on objects when the object is referenced indep
|
|
|
229
229
|
eval(output);
|
|
230
230
|
});
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
test("Variant #8: Not extract properties on objects when the variable gets redefined", async () => {
|
|
233
233
|
var code = `
|
|
234
234
|
|
|
235
235
|
var TEST_OBJECT = {
|
|
@@ -260,7 +260,7 @@ it("should not extract properties on objects when the variable gets redefined",
|
|
|
260
260
|
eval(output);
|
|
261
261
|
});
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
test("Variant #9: Not extract properties on objects when the variable gets reassigned", async () => {
|
|
264
264
|
var code = `
|
|
265
265
|
|
|
266
266
|
var TEST_OBJECT = {
|
|
@@ -292,7 +292,7 @@ it("should not extract properties on objects when the variable gets reassigned",
|
|
|
292
292
|
eval(output);
|
|
293
293
|
});
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
test("Variant #10: Not extract properties on objects with methods referencing 'this'", async () => {
|
|
296
296
|
var code = `
|
|
297
297
|
|
|
298
298
|
var TEST_OBJECT = {
|
|
@@ -325,7 +325,7 @@ it("should not extract properties on objects with methods referencing 'this'", a
|
|
|
325
325
|
eval(output);
|
|
326
326
|
});
|
|
327
327
|
|
|
328
|
-
|
|
328
|
+
test("Variant #11: Not extract properties on objects when properties are dynamically deleted", async () => {
|
|
329
329
|
var code = `
|
|
330
330
|
|
|
331
331
|
var TEST_OBJECT = {
|
|
@@ -356,7 +356,7 @@ it("should not extract properties on objects when properties are dynamically del
|
|
|
356
356
|
eval(output);
|
|
357
357
|
});
|
|
358
358
|
|
|
359
|
-
|
|
359
|
+
test("Variant #12: Not extract properties on objects with computed accessors", async () => {
|
|
360
360
|
var code = `
|
|
361
361
|
|
|
362
362
|
var TEST_OBJECT = {
|
|
@@ -388,7 +388,7 @@ it("should not extract properties on objects with computed accessors", async ()
|
|
|
388
388
|
eval(output);
|
|
389
389
|
});
|
|
390
390
|
|
|
391
|
-
|
|
391
|
+
test("Variant #13: Properly use custom callback to exclude certain names from being changed", async () => {
|
|
392
392
|
var code = `
|
|
393
393
|
|
|
394
394
|
var TEST_OBJECT = {
|
|
@@ -424,7 +424,7 @@ it("should properly use custom callback to exclude certain names from being chan
|
|
|
424
424
|
eval(output);
|
|
425
425
|
});
|
|
426
426
|
|
|
427
|
-
|
|
427
|
+
test("Variant #14: Not apply to objects with non-init properties (method, set, get)", async () => {
|
|
428
428
|
var code = `
|
|
429
429
|
|
|
430
430
|
var realValue = 0;
|
|
@@ -448,7 +448,7 @@ it("should not apply to objects with non-init properties (method, set, get)", as
|
|
|
448
448
|
});
|
|
449
449
|
|
|
450
450
|
// https://github.com/MichaelXF/js-confuser/issues/78
|
|
451
|
-
|
|
451
|
+
test("Variant #15: Handle objects with spread elements", async () => {
|
|
452
452
|
var output = await JsConfuser(
|
|
453
453
|
`
|
|
454
454
|
var x = { firstName: "John", lastName: "Doe" }
|
|
@@ -467,3 +467,23 @@ it("should handle objects with spread elements", async () => {
|
|
|
467
467
|
|
|
468
468
|
expect(TEST_OUTPUT).toStrictEqual({ firstName: "John", lastName: "Doe" });
|
|
469
469
|
});
|
|
470
|
+
|
|
471
|
+
// https://github.com/MichaelXF/js-confuser/issues/106
|
|
472
|
+
test("Variant #16: Handle const declarations", async () => {
|
|
473
|
+
var output = await JsConfuser(
|
|
474
|
+
`
|
|
475
|
+
const obj = {prop: 0};
|
|
476
|
+
obj.prop = 1;
|
|
477
|
+
TEST_OUTPUT = obj.prop;
|
|
478
|
+
`,
|
|
479
|
+
{
|
|
480
|
+
target: "node",
|
|
481
|
+
objectExtraction: true,
|
|
482
|
+
}
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
var TEST_OUTPUT;
|
|
486
|
+
eval(output);
|
|
487
|
+
|
|
488
|
+
expect(TEST_OUTPUT).toStrictEqual(1);
|
|
489
|
+
});
|