js-confuser 1.5.8 → 1.5.9
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 +37 -0
- package/dist/index.js +45 -4
- package/dist/obfuscator.js +10 -5
- package/dist/options.js +2 -3
- package/dist/order.js +3 -3
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -2
- package/dist/transforms/dispatcher.js +3 -3
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +1 -1
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +4 -4
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/flatten.js +73 -50
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/movedDeclarations.js +1 -1
- package/dist/transforms/minify.js +22 -6
- package/dist/transforms/rgf.js +4 -4
- package/dist/transforms/stack.js +1 -1
- package/dist/transforms/string/stringConcealing.js +2 -2
- package/dist/traverse.js +0 -8
- package/dist/util/compare.js +2 -2
- package/dist/util/insert.js +20 -6
- package/package.json +1 -1
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +6 -1
- package/src/options.ts +10 -2
- package/src/order.ts +3 -3
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +14 -2
- package/src/transforms/dispatcher.ts +4 -3
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +1 -1
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +5 -5
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/flatten.ts +181 -128
- package/src/transforms/hexadecimalNumbers.ts +37 -9
- package/src/transforms/identifier/movedDeclarations.ts +1 -1
- package/src/transforms/minify.ts +37 -5
- package/src/transforms/rgf.ts +4 -3
- package/src/transforms/stack.ts +3 -1
- package/src/transforms/string/stringConcealing.ts +2 -2
- package/src/traverse.ts +1 -8
- package/src/types.ts +9 -1
- package/src/util/compare.ts +2 -2
- package/src/util/insert.ts +37 -8
- package/test/code/ES6.src.js +14 -0
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +13 -1
- package/test/transforms/antiTooling.test.ts +30 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +22 -0
- package/test/transforms/dispatcher.test.ts +24 -0
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +146 -3
- package/test/transforms/identifier/renameVariables.test.ts +26 -0
- package/test/transforms/minify.test.ts +66 -0
- package/test/transforms/rgf.test.ts +56 -0
- package/test/transforms/string/stringConcealing.test.ts +33 -0
- package/test/util/compare.test.ts +23 -1
|
@@ -214,7 +214,7 @@ export default class StringConcealing extends Transform {
|
|
|
214
214
|
if (Math.random() > 0.5) {
|
|
215
215
|
callExpr = CallExpression(
|
|
216
216
|
MemberExpression(Identifier(fnName), Identifier("apply"), false),
|
|
217
|
-
[
|
|
217
|
+
[Identifier("undefined"), ArrayExpression([Literal(index)])]
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
220
|
|
|
@@ -222,7 +222,7 @@ export default class StringConcealing extends Transform {
|
|
|
222
222
|
else if (Math.random() > 0.5) {
|
|
223
223
|
callExpr = CallExpression(
|
|
224
224
|
MemberExpression(Identifier(fnName), Identifier("call"), false),
|
|
225
|
-
[
|
|
225
|
+
[Identifier("undefined"), Literal(index)]
|
|
226
226
|
);
|
|
227
227
|
}
|
|
228
228
|
|
package/src/traverse.ts
CHANGED
|
@@ -39,16 +39,9 @@ export type ExitCallback = () => void;
|
|
|
39
39
|
export function walk(
|
|
40
40
|
object: Node | Node[],
|
|
41
41
|
parents: Node[],
|
|
42
|
-
onEnter: EnterCallback
|
|
43
|
-
seen = new Set<Node>()
|
|
42
|
+
onEnter: EnterCallback
|
|
44
43
|
): "EXIT" | void {
|
|
45
44
|
if (typeof object === "object" && object) {
|
|
46
|
-
if (seen.has(object as any)) {
|
|
47
|
-
console.log(object);
|
|
48
|
-
throw new Error("Already seen: " + (object as any).type);
|
|
49
|
-
}
|
|
50
|
-
seen.add(object as any);
|
|
51
|
-
|
|
52
45
|
var newParents: Node[] = [object as Node, ...parents];
|
|
53
46
|
|
|
54
47
|
if (!Array.isArray(object)) {
|
package/src/types.ts
CHANGED
|
@@ -119,4 +119,12 @@ export type IJsConfuserDebugObfuscation = (
|
|
|
119
119
|
code: string,
|
|
120
120
|
options: ObfuscateOptions,
|
|
121
121
|
callback: (name: string, complete: number, totalTransforms: number) => void
|
|
122
|
-
) => Promise<
|
|
122
|
+
) => Promise<{
|
|
123
|
+
obfuscated: string;
|
|
124
|
+
transformationTimes: { [transformName: string]: number };
|
|
125
|
+
parseTime: number;
|
|
126
|
+
compileTime: number;
|
|
127
|
+
obfuscationTime: number;
|
|
128
|
+
totalTransforms: number;
|
|
129
|
+
totalPossibleTransforms: number;
|
|
130
|
+
}>;
|
package/src/util/compare.ts
CHANGED
|
@@ -53,8 +53,8 @@ export function isValidIdentifier(name: string): boolean {
|
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
var x = name.match(/^[A-z$_][A-z0-9$_]*/);
|
|
57
|
-
return x && x[0] == name;
|
|
56
|
+
var x = name.match(/^[A-Za-z$_][A-Za-z0-9$_]*/);
|
|
57
|
+
return !!(x && x[0] == name);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function isInsideType(
|
package/src/util/insert.ts
CHANGED
|
@@ -113,8 +113,14 @@ export function getDefiningContext(o: Node, p: Node[]): Node {
|
|
|
113
113
|
var variableDeclaration = p.find((x) => x.type == "VariableDeclaration");
|
|
114
114
|
ok(variableDeclaration);
|
|
115
115
|
|
|
116
|
-
if (
|
|
117
|
-
|
|
116
|
+
if (
|
|
117
|
+
variableDeclaration.kind === "let" ||
|
|
118
|
+
variableDeclaration.kind === "const"
|
|
119
|
+
) {
|
|
120
|
+
var context = getVarContext(o, p);
|
|
121
|
+
if (context && context.type === "Program") {
|
|
122
|
+
return getLexContext(o, p);
|
|
123
|
+
}
|
|
118
124
|
}
|
|
119
125
|
}
|
|
120
126
|
|
|
@@ -178,7 +184,7 @@ export function getBlockBody(block: Node): Node[] {
|
|
|
178
184
|
return getBlockBody(block.body);
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
export function getIndexDirect(object: Node, parent: Node
|
|
187
|
+
export function getIndexDirect(object: Node, parent: Node): string {
|
|
182
188
|
return Object.keys(parent).find((x) => parent[x] == object);
|
|
183
189
|
}
|
|
184
190
|
|
|
@@ -255,16 +261,25 @@ export function prepend(block: Node, ...nodes: Node[]) {
|
|
|
255
261
|
ok(!Array.isArray(block), "block should not be array");
|
|
256
262
|
|
|
257
263
|
if (block.type == "Program") {
|
|
258
|
-
var
|
|
264
|
+
var moveBy = 0;
|
|
259
265
|
block.body.forEach((stmt, i) => {
|
|
260
266
|
if (stmt.type == "ImportDeclaration") {
|
|
261
|
-
if (
|
|
262
|
-
|
|
267
|
+
if (moveBy == i) {
|
|
268
|
+
moveBy++;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (
|
|
273
|
+
stmt.type === "ExpressionStatement" &&
|
|
274
|
+
typeof stmt.directive === "string"
|
|
275
|
+
) {
|
|
276
|
+
if (moveBy == i) {
|
|
277
|
+
moveBy++;
|
|
263
278
|
}
|
|
264
279
|
}
|
|
265
280
|
});
|
|
266
281
|
|
|
267
|
-
block.body.splice(
|
|
282
|
+
block.body.splice(moveBy, 0, ...nodes);
|
|
268
283
|
} else {
|
|
269
284
|
getBlockBody(block).unshift(...nodes);
|
|
270
285
|
}
|
|
@@ -313,7 +328,10 @@ export function clone<T>(object: T): T {
|
|
|
313
328
|
* @param p
|
|
314
329
|
* @returns
|
|
315
330
|
*/
|
|
316
|
-
export function isForInitialize(
|
|
331
|
+
export function isForInitialize(
|
|
332
|
+
o: Node,
|
|
333
|
+
p: Node[]
|
|
334
|
+
): "initializer" | "left-hand" | false {
|
|
317
335
|
validateChain(o, p);
|
|
318
336
|
|
|
319
337
|
var forIndex = p.findIndex(
|
|
@@ -322,6 +340,17 @@ export function isForInitialize(o, p): "initializer" | "left-hand" | false {
|
|
|
322
340
|
x.type == "ForInStatement" ||
|
|
323
341
|
x.type == "ForOfStatement"
|
|
324
342
|
);
|
|
343
|
+
|
|
344
|
+
if (
|
|
345
|
+
p
|
|
346
|
+
.slice(0, forIndex)
|
|
347
|
+
.find((x) =>
|
|
348
|
+
["ArrowFunctionExpression", "BlockStatement"].includes(x.type)
|
|
349
|
+
)
|
|
350
|
+
) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
|
|
325
354
|
if (forIndex !== -1) {
|
|
326
355
|
if (p[forIndex].type == "ForStatement") {
|
|
327
356
|
if (p[forIndex].init == (p[forIndex - 1] || o)) {
|
package/test/code/ES6.src.js
CHANGED
|
@@ -73,3 +73,17 @@ for (var x of [3, 3, 5]) {
|
|
|
73
73
|
sum += x;
|
|
74
74
|
}
|
|
75
75
|
expect(sum).toStrictEqual(11);
|
|
76
|
+
|
|
77
|
+
// Variant #12 More complex for-loop initializer
|
|
78
|
+
var outside = 12;
|
|
79
|
+
for (
|
|
80
|
+
var myFunction = function () {
|
|
81
|
+
return outside;
|
|
82
|
+
};
|
|
83
|
+
false;
|
|
84
|
+
|
|
85
|
+
) {}
|
|
86
|
+
|
|
87
|
+
var TEST_OUTPUT = myFunction();
|
|
88
|
+
|
|
89
|
+
expect(TEST_OUTPUT).toStrictEqual(12);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import JsConfuser from "../../src/index";
|
|
2
|
+
|
|
3
|
+
// https://github.com/MichaelXF/js-confuser/issues/79
|
|
4
|
+
test("Variant #1: Support BigInt Literals (1n)", async () => {
|
|
5
|
+
var code = `
|
|
6
|
+
TEST_OUTPUT = 1n;
|
|
7
|
+
`;
|
|
8
|
+
|
|
9
|
+
var output = await JsConfuser(code, {
|
|
10
|
+
target: "node",
|
|
11
|
+
renameVariables: true,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
var TEST_OUTPUT;
|
|
15
|
+
eval(output);
|
|
16
|
+
|
|
17
|
+
expect(typeof TEST_OUTPUT).toStrictEqual("bigint");
|
|
18
|
+
expect(TEST_OUTPUT).toStrictEqual(1n);
|
|
19
|
+
});
|
package/test/index.test.ts
CHANGED
|
@@ -230,7 +230,19 @@ describe("debugObfuscation", () => {
|
|
|
230
230
|
callback
|
|
231
231
|
);
|
|
232
232
|
|
|
233
|
-
expect(typeof output).toStrictEqual("
|
|
233
|
+
expect(typeof output).toStrictEqual("object");
|
|
234
|
+
expect(typeof output.obfuscated).toStrictEqual("string");
|
|
235
|
+
expect(typeof output.obfuscationTime).toStrictEqual("number");
|
|
236
|
+
expect(typeof output.compileTime).toStrictEqual("number");
|
|
237
|
+
expect(typeof output.parseTime).toStrictEqual("number");
|
|
238
|
+
expect(typeof output.totalPossibleTransforms).toStrictEqual("number");
|
|
239
|
+
expect(typeof output.totalTransforms).toStrictEqual("number");
|
|
240
|
+
expect(typeof output.transformationTimes).toStrictEqual("object");
|
|
241
|
+
expect(typeof output.transformationTimes.RenameVariables).toStrictEqual(
|
|
242
|
+
"number"
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
eval(output.obfuscated);
|
|
234
246
|
expect(called).toStrictEqual(true);
|
|
235
247
|
});
|
|
236
248
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import JsConfuser from "../../src/index";
|
|
2
|
+
|
|
3
|
+
// https://github.com/MichaelXF/js-confuser/issues/74
|
|
4
|
+
test("Variant #1: Don't break Symbols", async () => {
|
|
5
|
+
if (typeof Symbol !== "undefined") {
|
|
6
|
+
for (var i = 0; i < 6; i++) {
|
|
7
|
+
var output = await JsConfuser(
|
|
8
|
+
`
|
|
9
|
+
|
|
10
|
+
var sym1 = Symbol();
|
|
11
|
+
|
|
12
|
+
if (true) {
|
|
13
|
+
sym1;
|
|
14
|
+
sym1;
|
|
15
|
+
sym1;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
TEST_OUTPUT = sym1;
|
|
19
|
+
|
|
20
|
+
`,
|
|
21
|
+
{ target: "node", renameVariables: true }
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
var TEST_OUTPUT;
|
|
25
|
+
|
|
26
|
+
eval(output);
|
|
27
|
+
expect(typeof TEST_OUTPUT).toStrictEqual("symbol");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
@@ -708,3 +708,25 @@ test("Variant #21: Don't move Import Declarations", async () => {
|
|
|
708
708
|
"1cac63f39fd68d8c531f27b807610fb3d50f0fc3f186995767fb6316e7200a3e"
|
|
709
709
|
);
|
|
710
710
|
});
|
|
711
|
+
|
|
712
|
+
// https://github.com/MichaelXF/js-confuser/issues/81
|
|
713
|
+
test("Variant #22: Don't break typeof expression", async () => {
|
|
714
|
+
var output = await JsConfuser(
|
|
715
|
+
`
|
|
716
|
+
TEST_OUTPUT = false;
|
|
717
|
+
if(typeof nonExistentVariable === "undefined") {
|
|
718
|
+
TEST_OUTPUT = true;
|
|
719
|
+
}
|
|
720
|
+
`,
|
|
721
|
+
{
|
|
722
|
+
target: "node",
|
|
723
|
+
controlFlowFlattening: true,
|
|
724
|
+
}
|
|
725
|
+
);
|
|
726
|
+
|
|
727
|
+
var TEST_OUTPUT;
|
|
728
|
+
|
|
729
|
+
eval(output);
|
|
730
|
+
|
|
731
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
732
|
+
});
|
|
@@ -330,3 +330,27 @@ it("should apply to every level of the code", async () => {
|
|
|
330
330
|
|
|
331
331
|
expect(value).toStrictEqual(100);
|
|
332
332
|
});
|
|
333
|
+
|
|
334
|
+
// https://github.com/MichaelXF/js-confuser/issues/77
|
|
335
|
+
it("should work with code that uses toString() function", async () => {
|
|
336
|
+
var output = await JsConfuser(
|
|
337
|
+
`
|
|
338
|
+
function myFunction(){
|
|
339
|
+
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
TEST_OUTPUT = toString();
|
|
343
|
+
`,
|
|
344
|
+
{
|
|
345
|
+
target: "node",
|
|
346
|
+
dispatcher: true,
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
var toString = () => "Correct Value";
|
|
351
|
+
var TEST_OUTPUT;
|
|
352
|
+
|
|
353
|
+
eval(output);
|
|
354
|
+
|
|
355
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
356
|
+
});
|
|
@@ -392,3 +392,36 @@ it("should work with stringConcealing and hide method names", async () => {
|
|
|
392
392
|
|
|
393
393
|
expect(TEST_VALUE).toStrictEqual(100);
|
|
394
394
|
});
|
|
395
|
+
|
|
396
|
+
// https://github.com/MichaelXF/js-confuser/issues/72
|
|
397
|
+
it("should support class fields", async () => {
|
|
398
|
+
var output = await JsConfuser(
|
|
399
|
+
`
|
|
400
|
+
class MyClass {
|
|
401
|
+
myField = 1;
|
|
402
|
+
["myComputedField"] = 2;
|
|
403
|
+
|
|
404
|
+
static myStaticField = 3;
|
|
405
|
+
static ["myComputedStaticField"] = 4;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
var myObject = new MyClass();
|
|
409
|
+
TEST_OUTPUT_1 = myObject.myField;
|
|
410
|
+
TEST_OUTPUT_2 = myObject.myComputedField;
|
|
411
|
+
TEST_OUTPUT_3 = MyClass.myStaticField;
|
|
412
|
+
TEST_OUTPUT_4 = MyClass.myComputedStaticField;
|
|
413
|
+
`,
|
|
414
|
+
{
|
|
415
|
+
target: "node",
|
|
416
|
+
es5: true,
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
var TEST_OUTPUT_1, TEST_OUTPUT_2, TEST_OUTPUT_3, TEST_OUTPUT_4;
|
|
421
|
+
|
|
422
|
+
eval(output);
|
|
423
|
+
expect(TEST_OUTPUT_1).toStrictEqual(1);
|
|
424
|
+
expect(TEST_OUTPUT_2).toStrictEqual(2);
|
|
425
|
+
expect(TEST_OUTPUT_3).toStrictEqual(3);
|
|
426
|
+
expect(TEST_OUTPUT_4).toStrictEqual(4);
|
|
427
|
+
});
|
|
@@ -76,3 +76,56 @@ it("should work with Integrity also enabled", async () => {
|
|
|
76
76
|
|
|
77
77
|
expect(value).toStrictEqual("Hello World");
|
|
78
78
|
});
|
|
79
|
+
|
|
80
|
+
it("should work on async functions", async () => {
|
|
81
|
+
var output = await JsConfuser(
|
|
82
|
+
`
|
|
83
|
+
async function myFunction(){
|
|
84
|
+
return "Correct Value";
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
(async ()=>{
|
|
88
|
+
TEST_FUNCTION( await myFunction() );
|
|
89
|
+
})();
|
|
90
|
+
`,
|
|
91
|
+
{ target: "node", eval: true }
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
expect(output).toContain("eval");
|
|
95
|
+
|
|
96
|
+
var wasCalled = false;
|
|
97
|
+
|
|
98
|
+
function TEST_FUNCTION(value) {
|
|
99
|
+
wasCalled = true;
|
|
100
|
+
expect(value).toStrictEqual("Correct Value");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
eval(output);
|
|
104
|
+
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
expect(wasCalled).toStrictEqual(true);
|
|
107
|
+
}, 1000);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should work on generator functions", async () => {
|
|
111
|
+
var output = await JsConfuser(
|
|
112
|
+
`
|
|
113
|
+
function* myFunction(){
|
|
114
|
+
yield "Correct Value";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const gen = myFunction();
|
|
118
|
+
|
|
119
|
+
TEST_OUTPUT = gen.next().value;
|
|
120
|
+
`,
|
|
121
|
+
{ target: "node", eval: true }
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
expect(output).toContain("eval");
|
|
125
|
+
|
|
126
|
+
var TEST_OUTPUT;
|
|
127
|
+
|
|
128
|
+
eval(output);
|
|
129
|
+
|
|
130
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
131
|
+
});
|
|
@@ -446,3 +446,24 @@ it("should not apply to objects with non-init properties (method, set, get)", as
|
|
|
446
446
|
expect(output).toContain("TEST_OBJECT");
|
|
447
447
|
expect(output).toContain("set ");
|
|
448
448
|
});
|
|
449
|
+
|
|
450
|
+
// https://github.com/MichaelXF/js-confuser/issues/78
|
|
451
|
+
it("should handle objects with spread elements", async () => {
|
|
452
|
+
var output = await JsConfuser(
|
|
453
|
+
`
|
|
454
|
+
var x = { firstName: "John", lastName: "Doe" }
|
|
455
|
+
var y = { ...x };
|
|
456
|
+
|
|
457
|
+
TEST_OUTPUT = y;
|
|
458
|
+
`,
|
|
459
|
+
{
|
|
460
|
+
target: "node",
|
|
461
|
+
objectExtraction: true,
|
|
462
|
+
}
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
var TEST_OUTPUT;
|
|
466
|
+
eval(output);
|
|
467
|
+
|
|
468
|
+
expect(TEST_OUTPUT).toStrictEqual({ firstName: "John", lastName: "Doe" });
|
|
469
|
+
});
|
|
@@ -4,7 +4,7 @@ it("should bring independent to the global level", async () => {
|
|
|
4
4
|
var output = await JsConfuser.obfuscate(
|
|
5
5
|
`
|
|
6
6
|
function container(){
|
|
7
|
-
function nested(){
|
|
7
|
+
function nested(param){
|
|
8
8
|
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -17,7 +17,8 @@ it("should bring independent to the global level", async () => {
|
|
|
17
17
|
}
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
// Ensure flatten was applied
|
|
21
|
+
expect(output).toContain("[param]");
|
|
21
22
|
});
|
|
22
23
|
|
|
23
24
|
it("should have correct return values", async () => {
|
|
@@ -255,7 +256,8 @@ it("should work when pattern-based assignment expressions are involved", async (
|
|
|
255
256
|
}
|
|
256
257
|
);
|
|
257
258
|
|
|
258
|
-
|
|
259
|
+
// Ensure flatten was applied
|
|
260
|
+
expect(output).toContain("[i],[]");
|
|
259
261
|
|
|
260
262
|
var value = "never_called",
|
|
261
263
|
input = (x) => (value = x);
|
|
@@ -263,3 +265,144 @@ it("should work when pattern-based assignment expressions are involved", async (
|
|
|
263
265
|
eval(output);
|
|
264
266
|
expect(value).toStrictEqual(1);
|
|
265
267
|
});
|
|
268
|
+
|
|
269
|
+
it("should work on async functions", async () => {
|
|
270
|
+
var output = await JsConfuser.obfuscate(
|
|
271
|
+
`
|
|
272
|
+
async function timeout(ms){
|
|
273
|
+
return await new Promise((resolve, reject)=>{
|
|
274
|
+
setTimeout(()=>{
|
|
275
|
+
resolve();
|
|
276
|
+
}, ms);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
(async ()=>{
|
|
281
|
+
var startTime = Date.now();
|
|
282
|
+
|
|
283
|
+
await timeout(1000);
|
|
284
|
+
|
|
285
|
+
var endTime = Date.now();
|
|
286
|
+
|
|
287
|
+
var duration = endTime - startTime;
|
|
288
|
+
|
|
289
|
+
TEST_CALLBACK(duration);
|
|
290
|
+
})();
|
|
291
|
+
`,
|
|
292
|
+
{
|
|
293
|
+
target: "node",
|
|
294
|
+
flatten: true,
|
|
295
|
+
}
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
expect(output).toContain("_flat_timeout");
|
|
299
|
+
|
|
300
|
+
var wasCalled = false;
|
|
301
|
+
var TEST_CALLBACK = (time) => {
|
|
302
|
+
expect(time).toBeGreaterThan(500);
|
|
303
|
+
wasCalled = true;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
eval(output);
|
|
307
|
+
|
|
308
|
+
setTimeout(() => {
|
|
309
|
+
expect(wasCalled).toStrictEqual(true);
|
|
310
|
+
}, 2000);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("should work on Function Expressions", async () => {
|
|
314
|
+
var output = await JsConfuser.obfuscate(
|
|
315
|
+
`
|
|
316
|
+
var outsideVar = "Correct Value";
|
|
317
|
+
|
|
318
|
+
var myFunctionExpression = function(){
|
|
319
|
+
return outsideVar;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
TEST_OUTPUT = myFunctionExpression();
|
|
323
|
+
`,
|
|
324
|
+
{
|
|
325
|
+
target: "node",
|
|
326
|
+
flatten: true,
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
// Ensure flatten applied
|
|
331
|
+
expect(output).toContain("_flat_myFunctionExpression");
|
|
332
|
+
|
|
333
|
+
var TEST_OUTPUT;
|
|
334
|
+
eval(output);
|
|
335
|
+
|
|
336
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("should work on Properties", async () => {
|
|
340
|
+
var output = await JsConfuser.obfuscate(
|
|
341
|
+
`
|
|
342
|
+
var outsideVar = "Incorrect Value";
|
|
343
|
+
|
|
344
|
+
var myObject = {
|
|
345
|
+
myInitProperty: function(){
|
|
346
|
+
return outsideVar;
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
myMethodProperty(){
|
|
350
|
+
return;
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
get myGetProperty(){
|
|
354
|
+
return;
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
set mySetProperty(val){
|
|
358
|
+
outsideVar = val;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
myObject.mySetProperty = "Correct Value";
|
|
363
|
+
TEST_OUTPUT = myObject.myInitProperty();
|
|
364
|
+
`,
|
|
365
|
+
{
|
|
366
|
+
target: "node",
|
|
367
|
+
flatten: true,
|
|
368
|
+
}
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
// Ensure flatten applied
|
|
372
|
+
expect(output).toContain("_flat_myInitProperty");
|
|
373
|
+
|
|
374
|
+
var TEST_OUTPUT;
|
|
375
|
+
eval(output);
|
|
376
|
+
|
|
377
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it("should work with RGF enabled", async () => {
|
|
381
|
+
var output = await JsConfuser.obfuscate(
|
|
382
|
+
`
|
|
383
|
+
var outsideVar = "Correct Value";
|
|
384
|
+
|
|
385
|
+
function myFunction(){
|
|
386
|
+
return outsideVar;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
TEST_OUTPUT = myFunction();
|
|
390
|
+
`,
|
|
391
|
+
{
|
|
392
|
+
target: "node",
|
|
393
|
+
flatten: true,
|
|
394
|
+
rgf: true,
|
|
395
|
+
}
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
// Ensure flatten applied
|
|
399
|
+
expect(output).toContain("_flat_myFunction");
|
|
400
|
+
|
|
401
|
+
// Ensure RGF applied
|
|
402
|
+
expect(output).toContain("new Function");
|
|
403
|
+
|
|
404
|
+
var TEST_OUTPUT;
|
|
405
|
+
eval(output);
|
|
406
|
+
|
|
407
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
408
|
+
});
|
|
@@ -474,3 +474,29 @@ test("Variant #19: Don't break Import Declarations", async () => {
|
|
|
474
474
|
"1cac63f39fd68d8c531f27b807610fb3d50f0fc3f186995767fb6316e7200a3e"
|
|
475
475
|
);
|
|
476
476
|
});
|
|
477
|
+
|
|
478
|
+
// https://github.com/MichaelXF/js-confuser/issues/80
|
|
479
|
+
test("Variant #20: Don't break code with var and let variables in same scope", async () => {
|
|
480
|
+
var output = await JsConfuser(
|
|
481
|
+
`
|
|
482
|
+
function log(param) {
|
|
483
|
+
let message = param;
|
|
484
|
+
var isWarning = false;
|
|
485
|
+
var isError = false;
|
|
486
|
+
|
|
487
|
+
TEST_OUTPUT = message;
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
log("Correct Value");
|
|
491
|
+
`,
|
|
492
|
+
{
|
|
493
|
+
target: "node",
|
|
494
|
+
renameVariables: true,
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
var TEST_OUTPUT;
|
|
499
|
+
eval(output);
|
|
500
|
+
|
|
501
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
502
|
+
});
|
|
@@ -269,6 +269,7 @@ test("Variant #15: Removing implied 'return'", async () => {
|
|
|
269
269
|
function MyFunction(){
|
|
270
270
|
var output = "Hello World";
|
|
271
271
|
console.log(output);
|
|
272
|
+
this; // Stop arrow function conversion
|
|
272
273
|
return;
|
|
273
274
|
}
|
|
274
275
|
|
|
@@ -366,3 +367,68 @@ test("Variant #19: Remove unreachable code following a throw statement", async (
|
|
|
366
367
|
|
|
367
368
|
expect(output).not.toContain("unreachableStmt");
|
|
368
369
|
});
|
|
370
|
+
|
|
371
|
+
// https://github.com/MichaelXF/js-confuser/issues/76
|
|
372
|
+
test("Variant #20: Properly handle objects with `, ^, [, ] as keys", async () => {
|
|
373
|
+
var output = await JsConfuser(
|
|
374
|
+
`
|
|
375
|
+
TEST_OBJECT = {
|
|
376
|
+
"\`": true,
|
|
377
|
+
"^": true,
|
|
378
|
+
"]": true,
|
|
379
|
+
"[": true
|
|
380
|
+
};
|
|
381
|
+
`,
|
|
382
|
+
{
|
|
383
|
+
target: "node",
|
|
384
|
+
minify: true,
|
|
385
|
+
}
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
var TEST_OBJECT;
|
|
389
|
+
eval(output);
|
|
390
|
+
|
|
391
|
+
expect(TEST_OBJECT).toStrictEqual({
|
|
392
|
+
"`": true,
|
|
393
|
+
"^": true,
|
|
394
|
+
"]": true,
|
|
395
|
+
"[": true,
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// https://github.com/MichaelXF/js-confuser/issues/75
|
|
400
|
+
test("Variant #21: Properly handle Object constructor (Function Declaration)", async () => {
|
|
401
|
+
var output = await JsConfuser(
|
|
402
|
+
`
|
|
403
|
+
function MyClass() {};
|
|
404
|
+
|
|
405
|
+
var myObject = new MyClass();
|
|
406
|
+
|
|
407
|
+
TEST_OUTPUT = myObject instanceof MyClass;
|
|
408
|
+
`,
|
|
409
|
+
{ target: "node", minify: true }
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
var TEST_OUTPUT = false;
|
|
413
|
+
eval(output);
|
|
414
|
+
|
|
415
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
test("Variant #22: Properly handle Object constructor (Function Expression)", async () => {
|
|
419
|
+
var output = await JsConfuser(
|
|
420
|
+
`
|
|
421
|
+
var MyClass = function() {};
|
|
422
|
+
|
|
423
|
+
var myObject = new MyClass();
|
|
424
|
+
|
|
425
|
+
TEST_OUTPUT = myObject instanceof MyClass;
|
|
426
|
+
`,
|
|
427
|
+
{ target: "node", minify: true }
|
|
428
|
+
);
|
|
429
|
+
|
|
430
|
+
var TEST_OUTPUT = false;
|
|
431
|
+
eval(output);
|
|
432
|
+
|
|
433
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
434
|
+
});
|