js-confuser 1.6.0 → 1.7.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/CHANGELOG.md +23 -0
- package/README.md +215 -170
- 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 +4 -1
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +89 -58
- 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 +139 -246
- 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 +37 -3
- package/dist/util/insert.js +24 -3
- package/docs/ControlFlowFlattening.md +595 -0
- package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
- package/{Integrity.md → docs/Integrity.md} +2 -2
- package/docs/RGF.md +419 -0
- package/package.json +1 -1
- 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 +5 -1
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +130 -129
- 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 +214 -404
- 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 +43 -2
- package/src/util/insert.ts +26 -2
- package/test/code/ES6.src.js +24 -0
- package/test/transforms/flatten.test.ts +352 -88
- package/test/transforms/identifier/movedDeclarations.test.ts +37 -9
- package/test/transforms/identifier/renameVariables.test.ts +37 -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 +113 -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
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import JsConfuser from "../../src/index";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
test("Variant #1: Function Declaration", async () => {
|
|
4
4
|
var output = await JsConfuser.obfuscate(
|
|
5
5
|
`
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
nested();
|
|
6
|
+
function myFunction(){
|
|
7
|
+
return 10;
|
|
12
8
|
}
|
|
9
|
+
|
|
10
|
+
TEST_OUTPUT = myFunction();
|
|
13
11
|
`,
|
|
14
12
|
{
|
|
15
13
|
target: "node",
|
|
@@ -17,18 +15,24 @@ it("should bring independent to the global level", async () => {
|
|
|
17
15
|
}
|
|
18
16
|
);
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
expect(output).toContain("_flat_myFunction");
|
|
19
|
+
|
|
20
|
+
var TEST_OUTPUT;
|
|
21
|
+
eval(output);
|
|
22
|
+
|
|
23
|
+
expect(TEST_OUTPUT).toStrictEqual(10);
|
|
22
24
|
});
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
test("Variant #2: Function Expression", async () => {
|
|
25
27
|
var output = await JsConfuser.obfuscate(
|
|
26
28
|
`
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
var outsideVar = "Correct Value";
|
|
30
|
+
|
|
31
|
+
var myFunction = function(){
|
|
32
|
+
return outsideVar;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
TEST_OUTPUT = myFunction();
|
|
32
36
|
`,
|
|
33
37
|
{
|
|
34
38
|
target: "node",
|
|
@@ -36,21 +40,22 @@ it("should have correct return values", async () => {
|
|
|
36
40
|
}
|
|
37
41
|
);
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
input = (x) => (value = x);
|
|
43
|
+
expect(output).toContain("_flat_myFunction");
|
|
41
44
|
|
|
45
|
+
var TEST_OUTPUT;
|
|
42
46
|
eval(output);
|
|
43
|
-
|
|
47
|
+
|
|
48
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
44
49
|
});
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
test("Variant #3: Simple parameters", async () => {
|
|
47
52
|
var output = await JsConfuser.obfuscate(
|
|
48
53
|
`
|
|
49
|
-
function
|
|
50
|
-
|
|
54
|
+
function myFunction(x, y){
|
|
55
|
+
TEST_OUTPUT = x + y;
|
|
51
56
|
}
|
|
52
57
|
|
|
53
|
-
|
|
58
|
+
myFunction(10, 15);
|
|
54
59
|
`,
|
|
55
60
|
{
|
|
56
61
|
target: "node",
|
|
@@ -58,14 +63,15 @@ it("should have correct parameters", async () => {
|
|
|
58
63
|
}
|
|
59
64
|
);
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
expect(output).toContain("_flat_myFunction");
|
|
67
|
+
|
|
68
|
+
var TEST_OUTPUT;
|
|
63
69
|
|
|
64
70
|
eval(output);
|
|
65
|
-
expect(
|
|
71
|
+
expect(TEST_OUTPUT).toStrictEqual(25);
|
|
66
72
|
});
|
|
67
73
|
|
|
68
|
-
|
|
74
|
+
test("Variant #4: Simple parameters nested", async () => {
|
|
69
75
|
var output = await JsConfuser.obfuscate(
|
|
70
76
|
`
|
|
71
77
|
function TEST_FUNCTION(x){
|
|
@@ -91,7 +97,7 @@ it("should have correct parameters when nested", async () => {
|
|
|
91
97
|
expect(value).toStrictEqual(10);
|
|
92
98
|
});
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
test("Variant #5: Correct return values when nested", async () => {
|
|
95
101
|
var output = await JsConfuser.obfuscate(
|
|
96
102
|
`
|
|
97
103
|
function TEST_FUNCTION(){
|
|
@@ -117,7 +123,7 @@ it("should have correct return values when nested", async () => {
|
|
|
117
123
|
expect(value).toStrictEqual(10);
|
|
118
124
|
});
|
|
119
125
|
|
|
120
|
-
|
|
126
|
+
test("Variant #6: Correct values when deeply nested", async () => {
|
|
121
127
|
var output = await JsConfuser.obfuscate(
|
|
122
128
|
`
|
|
123
129
|
function TEST_FUNCTION(x, y){
|
|
@@ -148,7 +154,7 @@ it("should have correct values when deeply nested", async () => {
|
|
|
148
154
|
expect(value).toStrictEqual(15);
|
|
149
155
|
});
|
|
150
156
|
|
|
151
|
-
|
|
157
|
+
test("Variant #7: Correct values when modifying local variables", async () => {
|
|
152
158
|
var output = await JsConfuser.obfuscate(
|
|
153
159
|
`
|
|
154
160
|
function TEST_FUNCTION(x, y){
|
|
@@ -182,7 +188,7 @@ it("should have correct values when modifying local variables", async () => {
|
|
|
182
188
|
expect(value).toStrictEqual(17);
|
|
183
189
|
});
|
|
184
190
|
|
|
185
|
-
|
|
191
|
+
test("Variant #8: Work with dispatcher", async () => {
|
|
186
192
|
var output = await JsConfuser.obfuscate(
|
|
187
193
|
`
|
|
188
194
|
function container(x){
|
|
@@ -211,34 +217,8 @@ it("should work with dispatcher", async () => {
|
|
|
211
217
|
expect(value).toStrictEqual(100);
|
|
212
218
|
});
|
|
213
219
|
|
|
214
|
-
it("should not change functions with const", async () => {
|
|
215
|
-
var output = await JsConfuser.obfuscate(
|
|
216
|
-
`
|
|
217
|
-
function TEST_FUNCTION(x, y){
|
|
218
|
-
const CONSTANT = 20;
|
|
219
|
-
|
|
220
|
-
return CONSTANT + x + y;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
input(TEST_FUNCTION(10, 5));
|
|
224
|
-
`,
|
|
225
|
-
{
|
|
226
|
-
target: "node",
|
|
227
|
-
flatten: true,
|
|
228
|
-
}
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
expect(output).not.toContain("set");
|
|
232
|
-
|
|
233
|
-
var value = "never_called",
|
|
234
|
-
input = (x) => (value = x);
|
|
235
|
-
|
|
236
|
-
eval(output);
|
|
237
|
-
expect(value).toStrictEqual(35);
|
|
238
|
-
});
|
|
239
|
-
|
|
240
220
|
// https://github.com/MichaelXF/js-confuser/issues/25
|
|
241
|
-
|
|
221
|
+
test("Variant #9: Work with pattern-based assignment expressions", async () => {
|
|
242
222
|
var output = await JsConfuser.obfuscate(
|
|
243
223
|
`
|
|
244
224
|
var i = 0;
|
|
@@ -257,7 +237,7 @@ it("should work when pattern-based assignment expressions are involved", async (
|
|
|
257
237
|
);
|
|
258
238
|
|
|
259
239
|
// Ensure flatten was applied
|
|
260
|
-
expect(output).toContain("
|
|
240
|
+
expect(output).toContain("_flat_");
|
|
261
241
|
|
|
262
242
|
var value = "never_called",
|
|
263
243
|
input = (x) => (value = x);
|
|
@@ -266,7 +246,7 @@ it("should work when pattern-based assignment expressions are involved", async (
|
|
|
266
246
|
expect(value).toStrictEqual(1);
|
|
267
247
|
});
|
|
268
248
|
|
|
269
|
-
|
|
249
|
+
test("Variant #10: Async function", async () => {
|
|
270
250
|
var output = await JsConfuser.obfuscate(
|
|
271
251
|
`
|
|
272
252
|
async function timeout(ms){
|
|
@@ -310,33 +290,7 @@ it("should work on async functions", async () => {
|
|
|
310
290
|
}, 2000);
|
|
311
291
|
});
|
|
312
292
|
|
|
313
|
-
|
|
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 () => {
|
|
293
|
+
test("Variant #11: Work with properties", async () => {
|
|
340
294
|
var output = await JsConfuser.obfuscate(
|
|
341
295
|
`
|
|
342
296
|
var outsideVar = "Incorrect Value";
|
|
@@ -369,7 +323,7 @@ it("should work on Properties", async () => {
|
|
|
369
323
|
);
|
|
370
324
|
|
|
371
325
|
// Ensure flatten applied
|
|
372
|
-
expect(output).toContain("
|
|
326
|
+
expect(output).toContain("_flat_");
|
|
373
327
|
|
|
374
328
|
var TEST_OUTPUT;
|
|
375
329
|
eval(output);
|
|
@@ -377,7 +331,7 @@ it("should work on Properties", async () => {
|
|
|
377
331
|
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
378
332
|
});
|
|
379
333
|
|
|
380
|
-
|
|
334
|
+
test("Variant #12: Work with RGF enabled", async () => {
|
|
381
335
|
var output = await JsConfuser.obfuscate(
|
|
382
336
|
`
|
|
383
337
|
var outsideVar = "Correct Value";
|
|
@@ -407,7 +361,7 @@ it("should work with RGF enabled", async () => {
|
|
|
407
361
|
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
408
362
|
});
|
|
409
363
|
|
|
410
|
-
|
|
364
|
+
test("Variant #13: Work with assignment expression in the return statement", async () => {
|
|
411
365
|
var output = await JsConfuser(
|
|
412
366
|
`
|
|
413
367
|
var outside;
|
|
@@ -433,7 +387,7 @@ it("should work with assignment expressions in the return statement", async () =
|
|
|
433
387
|
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
434
388
|
});
|
|
435
389
|
|
|
436
|
-
|
|
390
|
+
test("Variant #14: Work with 'use strict' directive", async () => {
|
|
437
391
|
var output = await JsConfuser(
|
|
438
392
|
`
|
|
439
393
|
function myFunction(){
|
|
@@ -455,3 +409,313 @@ it("should work with 'use strict' directive", async () => {
|
|
|
455
409
|
|
|
456
410
|
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
457
411
|
});
|
|
412
|
+
|
|
413
|
+
// https://github.com/MichaelXF/js-confuser/issues/89
|
|
414
|
+
test("Variant #15: Work with functions with invalid identifier names", async () => {
|
|
415
|
+
var output = await JsConfuser(
|
|
416
|
+
`
|
|
417
|
+
// Input
|
|
418
|
+
var object = {
|
|
419
|
+
"my-function": function () {
|
|
420
|
+
TEST_OUTPUT = "Success";
|
|
421
|
+
},
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
object["my-function"](); // "Success"
|
|
425
|
+
`,
|
|
426
|
+
{ target: "node", flatten: true }
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
var TEST_OUTPUT;
|
|
430
|
+
eval(output);
|
|
431
|
+
|
|
432
|
+
expect(TEST_OUTPUT).toStrictEqual("Success");
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
test("Variant #16: Multiple test", async () => {
|
|
436
|
+
var output = await JsConfuser(
|
|
437
|
+
`
|
|
438
|
+
"use strict";
|
|
439
|
+
|
|
440
|
+
function assertLegalInvocation(){
|
|
441
|
+
if(this !== undefined) throw new Error("Illegal Invocation");
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
(function (){
|
|
445
|
+
var requiredValue = {};
|
|
446
|
+
var value;
|
|
447
|
+
var counter = 0;
|
|
448
|
+
|
|
449
|
+
function getCorrectValueObject(requiredParameter){
|
|
450
|
+
function nestedFunction(){
|
|
451
|
+
var requiredCounterValue = 1;
|
|
452
|
+
if(requiredParameter === requiredValue) {
|
|
453
|
+
if(counter === requiredCounterValue) {
|
|
454
|
+
return {value: "Correct Value"};
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return {value: "Incorrect Value"};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return nestedFunction();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function setValue(){
|
|
465
|
+
// Test update-expression
|
|
466
|
+
counter++;
|
|
467
|
+
|
|
468
|
+
// Test call-expression
|
|
469
|
+
assertLegalInvocation();
|
|
470
|
+
|
|
471
|
+
function nestedSetValue(){
|
|
472
|
+
// Test destructuring
|
|
473
|
+
({value} = getCorrectValueObject(requiredValue));
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
nestedSetValue()
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function myFunction(myParameter1, myParameter2, myParameter3){
|
|
480
|
+
setValue();
|
|
481
|
+
|
|
482
|
+
myParameter1 = TEST_OUTPUT = value;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
myFunction();
|
|
486
|
+
})();
|
|
487
|
+
`,
|
|
488
|
+
{ target: "node", flatten: true }
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
expect(output).toContain("_flat_getCorrectValue");
|
|
492
|
+
expect(output).toContain("_flat_setValue");
|
|
493
|
+
expect(output).toContain("_flat_myFunction");
|
|
494
|
+
|
|
495
|
+
var TEST_OUTPUT;
|
|
496
|
+
eval(output);
|
|
497
|
+
|
|
498
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
test("Variant #17: Don't apply to generator functions", async () => {
|
|
502
|
+
var output = await JsConfuser(
|
|
503
|
+
`
|
|
504
|
+
function* myGeneratorFunction(){
|
|
505
|
+
yield "Correct Value";
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
TEST_OUTPUT = (myGeneratorFunction()).next().value;
|
|
509
|
+
`,
|
|
510
|
+
{ target: "node", flatten: true }
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
expect(output).not.toContain("_flat_myGeneratorFunction");
|
|
514
|
+
|
|
515
|
+
var TEST_OUTPUT;
|
|
516
|
+
eval(output);
|
|
517
|
+
|
|
518
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
test("Variant #18: Redefined variable in nested scope", async () => {
|
|
522
|
+
var output = await JsConfuser(
|
|
523
|
+
`
|
|
524
|
+
(function (){
|
|
525
|
+
var outsideVar = "Incorrect Value 1";
|
|
526
|
+
function myFunction1(){
|
|
527
|
+
(()=>{
|
|
528
|
+
var outsideVar = "Correct Value 1";
|
|
529
|
+
TEST_OUTPUT_1 = outsideVar;
|
|
530
|
+
})();
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
myFunction1();
|
|
534
|
+
|
|
535
|
+
outsideVar = "Correct Value 2";
|
|
536
|
+
|
|
537
|
+
function myFunction2(){
|
|
538
|
+
(()=>{
|
|
539
|
+
var outsideVar = "Incorrect Value 2";
|
|
540
|
+
})();
|
|
541
|
+
TEST_OUTPUT_2 = outsideVar;
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
myFunction2();
|
|
545
|
+
})();
|
|
546
|
+
`,
|
|
547
|
+
{
|
|
548
|
+
target: "node",
|
|
549
|
+
flatten: true,
|
|
550
|
+
renameVariables: (x) => !x.includes("_flat_"),
|
|
551
|
+
}
|
|
552
|
+
);
|
|
553
|
+
|
|
554
|
+
expect(output).toContain("_flat_myFunction1");
|
|
555
|
+
expect(output).toContain("_flat_myFunction2");
|
|
556
|
+
|
|
557
|
+
var TEST_OUTPUT_1, TEST_OUTPUT_2;
|
|
558
|
+
eval(output);
|
|
559
|
+
|
|
560
|
+
expect(TEST_OUTPUT_1).toStrictEqual("Correct Value 1");
|
|
561
|
+
expect(TEST_OUTPUT_2).toStrictEqual("Correct Value 2");
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
test("Variant #19: Nested function declaration", async () => {
|
|
565
|
+
var output = await JsConfuser(
|
|
566
|
+
`
|
|
567
|
+
function myFunction(){
|
|
568
|
+
TEST_OUTPUT = nestedFunctionDeclaration();
|
|
569
|
+
|
|
570
|
+
function nestedFunctionDeclaration(){
|
|
571
|
+
return "Correct Value";
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
myFunction();
|
|
576
|
+
`,
|
|
577
|
+
{
|
|
578
|
+
target: "node",
|
|
579
|
+
flatten: true,
|
|
580
|
+
}
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
expect(output).toContain("_flat_myFunction");
|
|
584
|
+
|
|
585
|
+
var TEST_OUTPUT;
|
|
586
|
+
eval(output);
|
|
587
|
+
|
|
588
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
test("Variant #20: Don't apply to functions that use 'this' 'arguments' or 'eval'", async () => {
|
|
592
|
+
var output = await JsConfuser(
|
|
593
|
+
`
|
|
594
|
+
function myFunction(){
|
|
595
|
+
usesEval();
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function usesThis(){
|
|
599
|
+
return this;
|
|
600
|
+
}
|
|
601
|
+
function usesArguments(){
|
|
602
|
+
return arguments;
|
|
603
|
+
}
|
|
604
|
+
function usesEval(){
|
|
605
|
+
eval("TEST_OUTPUT = 'Correct Value'");
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
myFunction();
|
|
609
|
+
`,
|
|
610
|
+
{
|
|
611
|
+
target: "node",
|
|
612
|
+
flatten: true,
|
|
613
|
+
}
|
|
614
|
+
);
|
|
615
|
+
|
|
616
|
+
expect(output).toContain("_flat_myFunction");
|
|
617
|
+
expect(output).not.toContain("_flat_usesThis");
|
|
618
|
+
expect(output).not.toContain("_flat_usesArguments");
|
|
619
|
+
expect(output).not.toContain("_flat_usesEval");
|
|
620
|
+
|
|
621
|
+
var TEST_OUTPUT;
|
|
622
|
+
eval(output);
|
|
623
|
+
|
|
624
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
test("Variant #21: Preserve function.length property", async () => {
|
|
628
|
+
var output = await JsConfuser(
|
|
629
|
+
`
|
|
630
|
+
function oneParameter(a){};
|
|
631
|
+
var twoParameters = function({a},{b,c},...d){};
|
|
632
|
+
function threeParameters(a,b,c,d = 1,{e},...f){};
|
|
633
|
+
|
|
634
|
+
TEST_OUTPUT = oneParameter.length + twoParameters.length + threeParameters.length;
|
|
635
|
+
`,
|
|
636
|
+
{
|
|
637
|
+
target: "node",
|
|
638
|
+
flatten: true,
|
|
639
|
+
}
|
|
640
|
+
);
|
|
641
|
+
|
|
642
|
+
expect(output).toContain("_flat_oneParameter");
|
|
643
|
+
expect(output).not.toContain("_flat_twoParameters");
|
|
644
|
+
expect(output).not.toContain("_flat_threeParameters");
|
|
645
|
+
|
|
646
|
+
var TEST_OUTPUT;
|
|
647
|
+
eval(output);
|
|
648
|
+
|
|
649
|
+
expect(TEST_OUTPUT).toStrictEqual(6);
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
test("Variant #22: Modify object properties", async () => {
|
|
653
|
+
var output = await JsConfuser(
|
|
654
|
+
`
|
|
655
|
+
var myObject = {};
|
|
656
|
+
|
|
657
|
+
function setProperty(property, value){
|
|
658
|
+
myObject[property] = value;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function getProperty(property){
|
|
662
|
+
return myObject[property];
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
setProperty("TEST_PROPERTY", "Correct Value");
|
|
666
|
+
TEST_OUTPUT = getProperty("TEST_PROPERTY");
|
|
667
|
+
`,
|
|
668
|
+
{ target: "node", flatten: true }
|
|
669
|
+
);
|
|
670
|
+
|
|
671
|
+
expect(output).toContain("_flat_setProperty");
|
|
672
|
+
expect(output).toContain("_flat_getProperty");
|
|
673
|
+
|
|
674
|
+
var TEST_OUTPUT;
|
|
675
|
+
|
|
676
|
+
eval(output);
|
|
677
|
+
expect(TEST_OUTPUT).toStrictEqual("Correct Value");
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
test("Variant #23: Reference original function name", async () => {
|
|
681
|
+
var output = await JsConfuser(
|
|
682
|
+
`
|
|
683
|
+
(function (){
|
|
684
|
+
function myFunction(){
|
|
685
|
+
var valueToCheck = myFunction;
|
|
686
|
+
TEST_OUTPUT = typeof valueToCheck === "function";
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
myFunction();
|
|
690
|
+
})();
|
|
691
|
+
`,
|
|
692
|
+
{ target: "node", flatten: true }
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
expect(output).toContain("_flat_myFunction");
|
|
696
|
+
|
|
697
|
+
var TEST_OUTPUT;
|
|
698
|
+
|
|
699
|
+
eval(output);
|
|
700
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
test("Variant #24: Typeof expression", async () => {
|
|
704
|
+
var output = await JsConfuser(
|
|
705
|
+
`
|
|
706
|
+
function myFunction(){
|
|
707
|
+
TEST_OUTPUT = typeof nonExistentVariable === "undefined";
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
myFunction();
|
|
711
|
+
`,
|
|
712
|
+
{ target: "node", flatten: true }
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
expect(output).toContain("_flat_myFunction");
|
|
716
|
+
|
|
717
|
+
var TEST_OUTPUT;
|
|
718
|
+
|
|
719
|
+
eval(output);
|
|
720
|
+
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
721
|
+
});
|
|
@@ -12,7 +12,7 @@ test("Variant #1: Move variable 'y' to top", async () => {
|
|
|
12
12
|
movedDeclarations: true,
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
expect(output).toContain("var y;");
|
|
15
|
+
expect(output).toContain("var x=10,y;");
|
|
16
16
|
expect(output).toContain("y=15");
|
|
17
17
|
|
|
18
18
|
var TEST_VARIABLE;
|
|
@@ -34,7 +34,7 @@ test("Variant #2: Move variable 'y' and 'z' to top", async () => {
|
|
|
34
34
|
movedDeclarations: true,
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
expect(output).toContain("var y,z");
|
|
37
|
+
expect(output).toContain("var x=10,y,z;");
|
|
38
38
|
expect(output).toContain("y=15");
|
|
39
39
|
expect(output).toContain("z=5");
|
|
40
40
|
|
|
@@ -44,7 +44,7 @@ test("Variant #2: Move variable 'y' and 'z' to top", async () => {
|
|
|
44
44
|
expect(TEST_VARIABLE).toStrictEqual(30);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
test("Variant #
|
|
47
|
+
test("Variant #3: Don't move 'y' (destructuring)", async () => {
|
|
48
48
|
var code = `
|
|
49
49
|
var x = 10;
|
|
50
50
|
var [y] = [15];
|
|
@@ -64,7 +64,7 @@ test("Variant #2: Don't move 'y' (destructuring)", async () => {
|
|
|
64
64
|
expect(TEST_VARIABLE).toStrictEqual(25);
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
test("Variant #
|
|
67
|
+
test("Variant #4: Move 'y' (nested lexical scope)", async () => {
|
|
68
68
|
var code = `
|
|
69
69
|
var x = 10;
|
|
70
70
|
var y = 15;
|
|
@@ -81,7 +81,7 @@ test("Variant #3: Don't move 'y' (nested lexical scope)", async () => {
|
|
|
81
81
|
movedDeclarations: true,
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
expect(output).toContain("var y
|
|
84
|
+
expect(output).toContain("var x=10,y;");
|
|
85
85
|
|
|
86
86
|
var TEST_VARIABLE;
|
|
87
87
|
eval(output);
|
|
@@ -89,7 +89,7 @@ test("Variant #3: Don't move 'y' (nested lexical scope)", async () => {
|
|
|
89
89
|
expect(TEST_VARIABLE).toStrictEqual(20);
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
test("Variant #
|
|
92
|
+
test("Variant #5: Move 'y' (for statement initializer)", async () => {
|
|
93
93
|
var code = `
|
|
94
94
|
var x = 10;
|
|
95
95
|
for ( var y = 0; y < 15; y++ ) {
|
|
@@ -111,7 +111,7 @@ test("Variant #4: Move 'y' (for statement initializer)", async () => {
|
|
|
111
111
|
expect(TEST_VARIABLE).toStrictEqual(25);
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
-
test("Variant #
|
|
114
|
+
test("Variant #6: Move 'y' (for-in left-hand initializer)", async () => {
|
|
115
115
|
var code = `
|
|
116
116
|
var x = 10;
|
|
117
117
|
for ( var y in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] ) {
|
|
@@ -134,7 +134,7 @@ test("Variant #5: Move 'y' (for-in left-hand initializer)", async () => {
|
|
|
134
134
|
expect(TEST_VARIABLE).toStrictEqual(25);
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
-
test("Variant #
|
|
137
|
+
test("Variant #7: Don't move const or let variables", async () => {
|
|
138
138
|
var code = `
|
|
139
139
|
var fillerExpr;
|
|
140
140
|
|
|
@@ -158,7 +158,7 @@ test("Variant #6: Don't move const or let variables", async () => {
|
|
|
158
158
|
expect(TEST_VARIABLE).toStrictEqual(25);
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
-
test("Variant #
|
|
161
|
+
test("Variant #8: Work with 'use strict'", async () => {
|
|
162
162
|
var code = `
|
|
163
163
|
function myFunction(){
|
|
164
164
|
'use strict';
|
|
@@ -184,3 +184,31 @@ test("Variant #7: Work with 'use strict'", async () => {
|
|
|
184
184
|
|
|
185
185
|
expect(TEST_OUTPUT).toStrictEqual(true);
|
|
186
186
|
});
|
|
187
|
+
|
|
188
|
+
test("Variant #9: Defined variable without an initializer", async () => {
|
|
189
|
+
var code = `
|
|
190
|
+
var x;
|
|
191
|
+
x = 1;
|
|
192
|
+
var y;
|
|
193
|
+
y = 2;
|
|
194
|
+
TEST_OUTPUT = x + y;
|
|
195
|
+
`;
|
|
196
|
+
|
|
197
|
+
var output1 = await JsConfuser(code, {
|
|
198
|
+
target: "node",
|
|
199
|
+
movedDeclarations: true,
|
|
200
|
+
controlFlowFlattening: true,
|
|
201
|
+
duplicateLiteralsRemoval: true,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
var output2 = await JsConfuser(output1, {
|
|
205
|
+
target: "node",
|
|
206
|
+
movedDeclarations: true,
|
|
207
|
+
controlFlowFlattening: true,
|
|
208
|
+
duplicateLiteralsRemoval: true,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
var TEST_OUTPUT;
|
|
212
|
+
eval(output2);
|
|
213
|
+
expect(TEST_OUTPUT).toStrictEqual(3);
|
|
214
|
+
});
|