js-confuser 1.5.9 → 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.
Files changed (143) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +346 -165
  4. package/dist/constants.js +6 -2
  5. package/dist/index.js +9 -21
  6. package/dist/obfuscator.js +19 -31
  7. package/dist/options.js +5 -5
  8. package/dist/order.js +1 -3
  9. package/dist/presets.js +6 -7
  10. package/dist/probability.js +2 -4
  11. package/dist/templates/bufferToString.js +13 -0
  12. package/dist/templates/crash.js +3 -3
  13. package/dist/templates/es5.js +18 -0
  14. package/dist/templates/functionLength.js +16 -0
  15. package/dist/transforms/calculator.js +77 -21
  16. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  17. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -1
  18. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  19. package/dist/transforms/deadCode.js +33 -25
  20. package/dist/transforms/dispatcher.js +8 -4
  21. package/dist/transforms/es5/antiDestructuring.js +2 -0
  22. package/dist/transforms/es5/es5.js +31 -34
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +92 -58
  24. package/dist/transforms/finalizer.js +82 -0
  25. package/dist/transforms/flatten.js +229 -148
  26. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  27. package/dist/transforms/identifier/globalConcealing.js +10 -83
  28. package/dist/transforms/identifier/movedDeclarations.js +35 -88
  29. package/dist/transforms/identifier/renameVariables.js +124 -59
  30. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  31. package/dist/transforms/lock/lock.js +0 -37
  32. package/dist/transforms/minify.js +60 -57
  33. package/dist/transforms/opaquePredicates.js +1 -1
  34. package/dist/transforms/preparation/preparation.js +2 -2
  35. package/dist/transforms/preparation.js +231 -0
  36. package/dist/transforms/renameLabels.js +1 -1
  37. package/dist/transforms/rgf.js +139 -247
  38. package/dist/transforms/stack.js +128 -26
  39. package/dist/transforms/string/encoding.js +150 -179
  40. package/dist/transforms/string/stringCompression.js +14 -15
  41. package/dist/transforms/string/stringConcealing.js +25 -8
  42. package/dist/transforms/string/stringEncoding.js +13 -24
  43. package/dist/transforms/transform.js +12 -19
  44. package/dist/traverse.js +24 -10
  45. package/dist/util/gen.js +17 -1
  46. package/dist/util/identifiers.js +37 -3
  47. package/dist/util/insert.js +35 -4
  48. package/dist/util/random.js +15 -0
  49. package/docs/ControlFlowFlattening.md +595 -0
  50. package/{Countermeasures.md → docs/Countermeasures.md} +1 -15
  51. package/{Integrity.md → docs/Integrity.md} +2 -2
  52. package/docs/RGF.md +419 -0
  53. package/package.json +5 -5
  54. package/src/constants.ts +3 -0
  55. package/src/index.ts +2 -2
  56. package/src/obfuscator.ts +19 -31
  57. package/src/options.ts +14 -103
  58. package/src/order.ts +1 -5
  59. package/src/presets.ts +6 -7
  60. package/src/probability.ts +2 -3
  61. package/src/templates/bufferToString.ts +68 -0
  62. package/src/templates/crash.ts +15 -19
  63. package/src/templates/es5.ts +131 -0
  64. package/src/templates/functionLength.ts +14 -0
  65. package/src/transforms/calculator.ts +122 -59
  66. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  67. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +4 -1
  68. package/src/transforms/deadCode.ts +383 -26
  69. package/src/transforms/dispatcher.ts +9 -4
  70. package/src/transforms/es5/antiDestructuring.ts +2 -0
  71. package/src/transforms/es5/es5.ts +32 -77
  72. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +133 -129
  73. package/src/transforms/{hexadecimalNumbers.ts → finalizer.ts} +29 -13
  74. package/src/transforms/flatten.ts +357 -300
  75. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  76. package/src/transforms/identifier/globalConcealing.ts +14 -103
  77. package/src/transforms/identifier/movedDeclarations.ts +49 -102
  78. package/src/transforms/identifier/renameVariables.ts +149 -78
  79. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  80. package/src/transforms/lock/lock.ts +1 -42
  81. package/src/transforms/minify.ts +91 -75
  82. package/src/transforms/opaquePredicates.ts +2 -2
  83. package/src/transforms/preparation.ts +238 -0
  84. package/src/transforms/renameLabels.ts +2 -2
  85. package/src/transforms/rgf.ts +213 -405
  86. package/src/transforms/stack.ts +156 -36
  87. package/src/transforms/string/encoding.ts +115 -212
  88. package/src/transforms/string/stringCompression.ts +27 -18
  89. package/src/transforms/string/stringConcealing.ts +39 -9
  90. package/src/transforms/string/stringEncoding.ts +18 -18
  91. package/src/transforms/transform.ts +21 -23
  92. package/src/traverse.ts +23 -4
  93. package/src/types.ts +2 -1
  94. package/src/util/gen.ts +28 -3
  95. package/src/util/identifiers.ts +43 -2
  96. package/src/util/insert.ts +38 -3
  97. package/src/util/random.ts +13 -0
  98. package/test/code/Cash.test.ts +1 -1
  99. package/test/code/Dynamic.test.ts +12 -10
  100. package/test/code/ES6.src.js +146 -0
  101. package/test/code/ES6.test.ts +28 -2
  102. package/test/index.test.ts +2 -1
  103. package/test/probability.test.ts +44 -0
  104. package/test/templates/template.test.ts +1 -1
  105. package/test/transforms/antiTooling.test.ts +22 -0
  106. package/test/transforms/calculator.test.ts +40 -0
  107. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +702 -160
  108. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  109. package/test/transforms/deadCode.test.ts +66 -15
  110. package/test/transforms/dispatcher.test.ts +20 -1
  111. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  112. package/test/transforms/flatten.test.ts +399 -86
  113. package/test/transforms/identifier/movedDeclarations.test.ts +63 -8
  114. package/test/transforms/identifier/renameVariables.test.ts +119 -0
  115. package/test/transforms/lock/antiDebug.test.ts +2 -2
  116. package/test/transforms/lock/lock.test.ts +1 -48
  117. package/test/transforms/minify.test.ts +104 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +261 -381
  120. package/test/transforms/stack.test.ts +143 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +82 -0
  123. package/test/transforms/string/stringEncoding.test.ts +53 -2
  124. package/test/transforms/transform.test.ts +66 -0
  125. package/test/traverse.test.ts +139 -0
  126. package/test/util/identifiers.test.ts +113 -1
  127. package/test/util/insert.test.ts +57 -3
  128. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  129. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  130. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  131. package/src/transforms/eval.ts +0 -89
  132. package/src/transforms/hideInitializingCode.ts +0 -432
  133. package/src/transforms/identifier/nameRecycling.ts +0 -280
  134. package/src/transforms/label.ts +0 -64
  135. package/src/transforms/preparation/nameConflicts.ts +0 -102
  136. package/src/transforms/preparation/preparation.ts +0 -176
  137. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  138. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  139. package/test/transforms/eval.test.ts +0 -131
  140. package/test/transforms/hideInitializingCode.test.ts +0 -336
  141. package/test/transforms/identifier/nameRecycling.test.ts +0 -205
  142. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  143. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -1,15 +1,13 @@
1
1
  import JsConfuser from "../../src/index";
2
2
 
3
- it("should bring independent to the global level", async () => {
3
+ test("Variant #1: Function Declaration", async () => {
4
4
  var output = await JsConfuser.obfuscate(
5
5
  `
6
- function container(){
7
- function nested(param){
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
- // Ensure flatten was applied
21
- expect(output).toContain("[param]");
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
- it("should have correct return values", async () => {
26
+ test("Variant #2: Function Expression", async () => {
25
27
  var output = await JsConfuser.obfuscate(
26
28
  `
27
- function TEST_FUNCTION(){
28
- return 10;
29
+ var outsideVar = "Correct Value";
30
+
31
+ var myFunction = function(){
32
+ return outsideVar;
29
33
  }
30
34
 
31
- input(TEST_FUNCTION());
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
- var value = "never_called",
40
- input = (x) => (value = x);
43
+ expect(output).toContain("_flat_myFunction");
41
44
 
45
+ var TEST_OUTPUT;
42
46
  eval(output);
43
- expect(value).toStrictEqual(10);
47
+
48
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
44
49
  });
45
50
 
46
- it("should have correct parameters", async () => {
51
+ test("Variant #3: Simple parameters", async () => {
47
52
  var output = await JsConfuser.obfuscate(
48
53
  `
49
- function TEST_FUNCTION(x, y){
50
- input(x + y);
54
+ function myFunction(x, y){
55
+ TEST_OUTPUT = x + y;
51
56
  }
52
57
 
53
- TEST_FUNCTION(10, 15);
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
- var value = "never_called",
62
- input = (x) => (value = x);
66
+ expect(output).toContain("_flat_myFunction");
67
+
68
+ var TEST_OUTPUT;
63
69
 
64
70
  eval(output);
65
- expect(value).toStrictEqual(25);
71
+ expect(TEST_OUTPUT).toStrictEqual(25);
66
72
  });
67
73
 
68
- it("should have correct parameters when nested", async () => {
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
- it("should have correct return values when nested", async () => {
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
- it("should have correct values when deeply nested", async () => {
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
- it("should have correct values when modifying local variables", async () => {
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
- it("should work with dispatcher", async () => {
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
- it("should work when pattern-based assignment expressions are involved", async () => {
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("[i],[]");
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
- it("should work on async functions", async () => {
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
- 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 () => {
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("_flat_myInitProperty");
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
- it("should work with RGF enabled", async () => {
334
+ test("Variant #12: Work with RGF enabled", async () => {
381
335
  var output = await JsConfuser.obfuscate(
382
336
  `
383
337
  var outsideVar = "Correct Value";
@@ -406,3 +360,362 @@ it("should work with RGF enabled", async () => {
406
360
 
407
361
  expect(TEST_OUTPUT).toStrictEqual("Correct Value");
408
362
  });
363
+
364
+ test("Variant #13: Work with assignment expression in the return statement", async () => {
365
+ var output = await JsConfuser(
366
+ `
367
+ var outside;
368
+
369
+ function myFunction(){
370
+ return outside = "Correct Value"
371
+ }
372
+
373
+ myFunction(outside);
374
+
375
+ TEST_OUTPUT = outside;
376
+
377
+ `,
378
+ { target: "node", flatten: true }
379
+ );
380
+
381
+ // Ensure flat was applied
382
+ expect(output).toContain("_flat_myFunction");
383
+
384
+ var TEST_OUTPUT;
385
+ eval(output);
386
+
387
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
388
+ });
389
+
390
+ test("Variant #14: Work with 'use strict' directive", async () => {
391
+ var output = await JsConfuser(
392
+ `
393
+ function myFunction(){
394
+ "use strict";
395
+
396
+ return "Correct Value";
397
+ }
398
+
399
+ TEST_OUTPUT = myFunction();
400
+ `,
401
+ { target: "node", flatten: true }
402
+ );
403
+
404
+ // Ensure flat was applied
405
+ expect(output).toContain("_flat_myFunction");
406
+
407
+ var TEST_OUTPUT;
408
+ eval(output);
409
+
410
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
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
+ });