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
@@ -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 #2: Don't move 'y' (destructuring)", async () => {
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 #3: Don't move 'y' (nested lexical scope)", async () => {
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=15");
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 #4: Move 'y' (for statement initializer)", async () => {
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 #5: Move 'y' (for-in left-hand initializer)", async () => {
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 #6: Don't move const or let variables", async () => {
137
+ test("Variant #7: Don't move const or let variables", async () => {
138
138
  var code = `
139
139
  var fillerExpr;
140
140
 
@@ -157,3 +157,58 @@ test("Variant #6: Don't move const or let variables", async () => {
157
157
 
158
158
  expect(TEST_VARIABLE).toStrictEqual(25);
159
159
  });
160
+
161
+ test("Variant #8: Work with 'use strict'", async () => {
162
+ var code = `
163
+ function myFunction(){
164
+ 'use strict';
165
+
166
+ var x = 1;
167
+
168
+ return this === undefined;
169
+ }
170
+
171
+ TEST_OUTPUT = myFunction();
172
+ `;
173
+
174
+ var output = await JsConfuser(code, {
175
+ target: "node",
176
+ movedDeclarations: true,
177
+ });
178
+
179
+ // Ensure movedDeclarations applied and 'use strict' is still first
180
+ expect(output).toContain("function myFunction(){'use strict';var x;");
181
+
182
+ var TEST_OUTPUT;
183
+ eval(output);
184
+
185
+ expect(TEST_OUTPUT).toStrictEqual(true);
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
+ });
@@ -1,4 +1,5 @@
1
1
  import JsConfuser from "../../../src/index";
2
+ import { ObfuscateOptions } from "../../../src/options";
2
3
 
3
4
  test("Variant #1: Rename variables properly", async () => {
4
5
  var code = "var TEST_VARIABLE = 1;";
@@ -500,3 +501,121 @@ test("Variant #20: Don't break code with var and let variables in same scope", a
500
501
 
501
502
  expect(TEST_OUTPUT).toStrictEqual("Correct Value");
502
503
  });
504
+
505
+ test.each(["hexadecimal", "mangled", "number", "zeroWidth"])(
506
+ "Variant #21: Work with custom identifierGenerator mode",
507
+ async (identifierGeneratorMode) => {
508
+ var output = await JsConfuser(
509
+ `
510
+ var myVar1 = "Correct Value";
511
+
512
+ TEST_OUTPUT = myVar1;
513
+ `,
514
+ {
515
+ target: "node",
516
+ renameVariables: true,
517
+ identifierGenerator:
518
+ identifierGeneratorMode as ObfuscateOptions["identifierGenerator"],
519
+ }
520
+ );
521
+
522
+ // Ensure 'myVar1' got renamed
523
+ expect(output).not.toContain("myVar1");
524
+
525
+ var TEST_OUTPUT;
526
+
527
+ eval(output);
528
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
529
+ }
530
+ );
531
+
532
+ test("Variant #22: Don't rename variables prefixed with '__NO_JS_CONFUSER_RENAME__'", async () => {
533
+ var output = await JsConfuser(
534
+ `
535
+ var myValue = "Correct Value";
536
+
537
+ var __NO_JS_CONFUSER_RENAME__myVar4 = "Incorrect Value";
538
+
539
+ __NO_JS_CONFUSER_RENAME__myVar4 = myValue;
540
+
541
+ eval( "TEST_OUTPUT = __NO_JS_CONFUSER_RENAME__myVar4" );
542
+ `,
543
+ {
544
+ target: "node",
545
+ renameVariables: true,
546
+ }
547
+ );
548
+
549
+ // Ensure 'myValue' got renamed
550
+ expect(output).not.toContain("myValue");
551
+ // Ensure '__NO_JS_CONFUSER_RENAME__myVar4' was not renamed
552
+ expect(output).toContain("__NO_JS_CONFUSER_RENAME__myVar4");
553
+
554
+ // Test the code
555
+ var TEST_OUTPUT;
556
+
557
+ eval(output);
558
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
559
+ });
560
+
561
+ test("Variant #23: Re-use previously generated names", async () => {
562
+ var output = await JsConfuser(
563
+ `
564
+ function log(message){
565
+ TEST_OUTPUT = message;
566
+ }
567
+
568
+ log("Correct Value");
569
+ `,
570
+ {
571
+ target: "node",
572
+ renameVariables: true,
573
+ identifierGenerator: "mangled",
574
+ }
575
+ );
576
+
577
+ expect(output).not.toContain("log");
578
+ expect(output).toContain("function a(a)");
579
+
580
+ var TEST_OUTPUT;
581
+ eval(output);
582
+
583
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
584
+ });
585
+
586
+ test("Variant #24: Reference function name with parameter", async () => {
587
+ var output = await JsConfuser(
588
+ `
589
+ function myFunction(myFunction){
590
+ myFunction.property = "Correct Value";
591
+ }
592
+
593
+ myFunction(myFunction);
594
+ TEST_OUTPUT = myFunction.property;
595
+ `,
596
+ { target: "node", renameVariables: true }
597
+ );
598
+
599
+ var TEST_OUTPUT;
600
+ eval(output);
601
+
602
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
603
+ });
604
+
605
+ test("Variant #25: Reference catch parameter", async () => {
606
+ var output = await JsConfuser(
607
+ `
608
+ try {
609
+ throw "Correct Value";
610
+ } catch ( e ) {
611
+ TEST_OUTPUT = e;
612
+ }
613
+ `,
614
+ { target: "node", renameVariables: true }
615
+ );
616
+
617
+ var TEST_OUTPUT;
618
+ eval(output);
619
+
620
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
621
+ });
@@ -23,7 +23,7 @@ it("add a background interval", async () => {
23
23
  });
24
24
 
25
25
  it("should place syntax-correct code", async () => {
26
- for (var i = 0; i < 50; i++) {
26
+ for (var i = 0; i < 25; i++) {
27
27
  var output = await JsConfuser.obfuscate(
28
28
  `
29
29
  /**
@@ -49,7 +49,7 @@ it("should place syntax-correct code", async () => {
49
49
  `,
50
50
  {
51
51
  compact: true,
52
- controlFlowFlattening: 0.25,
52
+ controlFlowFlattening: true,
53
53
  identifierGenerator: "randomized",
54
54
  lock: { antiDebug: true },
55
55
  minify: true,
@@ -64,6 +64,7 @@ it("should work with endDate and call countermeasures function", async () => {
64
64
  expect(value).toStrictEqual(true);
65
65
  });
66
66
 
67
+ // REMOVED FEATURE:
67
68
  // it("strings should be encoded when startDate and endDate are given", async () => {
68
69
  // var startDate = await JsConfuser.obfuscate(` input("ENCODED_STRING") `, {
69
70
  // target: "node",
@@ -82,54 +83,6 @@ it("should work with endDate and call countermeasures function", async () => {
82
83
  // expect(value).toStrictEqual("ENCODED_STRING");
83
84
  // });
84
85
 
85
- it("should work with nativeFunctions and call countermeasures function", async () => {
86
- var output = await JsConfuser.obfuscate(
87
- ` function countermeasures(){ input(true) } `,
88
- {
89
- target: "node",
90
- lock: {
91
- nativeFunctions: ["fetch"],
92
- countermeasures: "countermeasures",
93
- },
94
- }
95
- );
96
-
97
- // custom function, not "native"
98
- var fetch = () => {};
99
-
100
- var value = "never_called";
101
- function input(valueIn) {
102
- value = valueIn;
103
- }
104
-
105
- eval(output);
106
- expect(value).toStrictEqual(true);
107
- });
108
-
109
- it("should work with nativeFunctions and not call countermeasures function when correct", async () => {
110
- var output = await JsConfuser.obfuscate(
111
- ` function countermeasures(){ input(true) } `,
112
- {
113
- target: "node",
114
- lock: {
115
- nativeFunctions: ["fetch"],
116
- countermeasures: "countermeasures",
117
- },
118
- }
119
- );
120
-
121
- // bound functions return the "[native code]" string
122
- var fetch = (() => {}).bind(this);
123
-
124
- var value = "never_called";
125
- function input(valueIn) {
126
- value = valueIn;
127
- }
128
-
129
- eval(output);
130
- expect(value).toStrictEqual("never_called");
131
- });
132
-
133
86
  it("countermeasures function should still work even with renameVariables enabled", async () => {
134
87
  var output = await JsConfuser.obfuscate(
135
88
  ` function countermeasures(){ input(true) } `,
@@ -432,3 +432,107 @@ test("Variant #22: Properly handle Object constructor (Function Expression)", as
432
432
 
433
433
  expect(TEST_OUTPUT).toStrictEqual(true);
434
434
  });
435
+
436
+ test("Variant #23: Shorten property names and method names", async () => {
437
+ var output = await JsConfuser(
438
+ `
439
+ var myObject = { "myKey": "Correct Value" };
440
+ var myClass = class { ["myMethod"](){ return "Correct Value" } }
441
+
442
+ TEST_OUTPUT = myObject.myKey === (new myClass()).myMethod();
443
+ `,
444
+ { target: "node", minify: true }
445
+ );
446
+
447
+ expect(output).not.toContain("'myKey'");
448
+ expect(output).not.toContain("'myMethod'");
449
+
450
+ var TEST_OUTPUT;
451
+ eval(output);
452
+
453
+ expect(TEST_OUTPUT).toStrictEqual(true);
454
+ });
455
+
456
+ test("Variant #24: Variable grouping in switch case", async () => {
457
+ var output = await JsConfuser(
458
+ `
459
+ switch(true){
460
+ case true:
461
+ var myVar1;
462
+ var myVar2;
463
+ var myVar3 = "Correct Value";
464
+ var myVar4;
465
+
466
+ TEST_OUTPUT = myVar3;
467
+ break;
468
+ }
469
+ `,
470
+ { target: "node", minify: true }
471
+ );
472
+
473
+ // Ensure the variable declarations were grouped
474
+ expect(output).toContain("var myVar1,myVar2,myVar3");
475
+
476
+ var TEST_OUTPUT;
477
+ eval(output);
478
+
479
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
480
+ });
481
+
482
+ test("Variant #25: Don't break redefined function declaration", async () => {
483
+ var output = await JsConfuser(
484
+ `
485
+ function a(){ TEST_OUTPUT = 1 };
486
+ function a(){ TEST_OUTPUT = 2 };
487
+ function a(){ TEST_OUTPUT = 3 };
488
+
489
+ a();
490
+ `,
491
+ { target: "node", minify: true }
492
+ );
493
+
494
+ var TEST_OUTPUT;
495
+ eval(output);
496
+
497
+ expect(TEST_OUTPUT).toStrictEqual(3);
498
+ });
499
+
500
+ test("Variant #26: Don't break nested redefined function declaration", async () => {
501
+ var output = await JsConfuser(
502
+ `
503
+ var a = 0;
504
+ if(true){
505
+ function a(){
506
+ TEST_OUTPUT = 1;
507
+ }
508
+ }
509
+
510
+ a();
511
+ `,
512
+ { target: "node", minify: true }
513
+ );
514
+
515
+ var TEST_OUTPUT;
516
+ eval(output);
517
+
518
+ expect(TEST_OUTPUT).toStrictEqual(1);
519
+ });
520
+
521
+ // https://github.com/MichaelXF/js-confuser/issues/91
522
+ test("Variant #27: Preserve function.length property", async () => {
523
+ var output = await JsConfuser(
524
+ `
525
+ function oneParameter(a){};
526
+ var twoParameters = function({a},{b,c},...d){};
527
+ function threeParameters(a,b,c,d = 1,{e},...f){};
528
+
529
+ TEST_OUTPUT = oneParameter.length + twoParameters.length + threeParameters.length;
530
+ `,
531
+ { target: "node", minify: true }
532
+ );
533
+
534
+ var TEST_OUTPUT;
535
+ eval(output);
536
+
537
+ expect(TEST_OUTPUT).toStrictEqual(6);
538
+ });
@@ -0,0 +1,157 @@
1
+ import JsConfuser from "../../src/index";
2
+
3
+ test("Variant #1: Force Block Statements on If statements", async () => {
4
+ var output = await JsConfuser.obfuscate(
5
+ `
6
+ if ( a ) b();
7
+
8
+ if ( a ) {} else c()
9
+ `,
10
+ {
11
+ target: "node",
12
+ compact: true, // <- Something needs to be enabled
13
+ }
14
+ );
15
+
16
+ // Ensure parenthesis were added
17
+ expect(output).toContain("{b()}");
18
+ expect(output).toContain("{c()}");
19
+ });
20
+
21
+ test("Variant #2: Force Block Statements on Arrow functions", async () => {
22
+ var output = await JsConfuser.obfuscate(
23
+ `
24
+ TEST_OUTPUT = ()=>true;
25
+ `,
26
+ {
27
+ target: "node",
28
+ compact: true, // <- Something needs to be enabled
29
+ }
30
+ );
31
+
32
+ // Ensure parenthesis were added
33
+ expect(output).toContain("return");
34
+ expect(output).toContain("{");
35
+ expect(output).toContain("}");
36
+
37
+ // Ensure code still works
38
+ var TEST_OUTPUT;
39
+ eval(output);
40
+
41
+ expect(typeof TEST_OUTPUT).toStrictEqual("function");
42
+ expect(TEST_OUTPUT()).toStrictEqual(true);
43
+ });
44
+
45
+ test("Variant #3: Force Block Statements on For loops", async () => {
46
+ var output = await JsConfuser.obfuscate(
47
+ `
48
+ for(;;) forStatement();
49
+ for(a in b) forInStatement();
50
+ for(a of b) forOfStatement();
51
+ `,
52
+ {
53
+ target: "node",
54
+ compact: true, // <- Something needs to be enabled
55
+ }
56
+ );
57
+
58
+ // Ensure parenthesis were added
59
+ expect(output).toContain("{forStatement()}");
60
+ expect(output).toContain("{forInStatement()}");
61
+ expect(output).toContain("{forOfStatement()}");
62
+ });
63
+
64
+ test("Variant #4: Force Block Statements on While loops/With statement", async () => {
65
+ var output = await JsConfuser.obfuscate(
66
+ `
67
+ while(1) whileStatement();
68
+ with(a) withStatement();
69
+ `,
70
+ {
71
+ target: "node",
72
+ compact: true, // <- Something needs to be enabled
73
+ }
74
+ );
75
+
76
+ // Ensure parenthesis were added
77
+ expect(output).toContain("{whileStatement()}");
78
+ expect(output).toContain("{withStatement()}");
79
+ });
80
+
81
+ test("Variant #5: Force object accessors to use strings instead", async () => {
82
+ var output = await JsConfuser.obfuscate(
83
+ `
84
+ console.log("Hello World")
85
+ `,
86
+ {
87
+ target: "node",
88
+ compact: true, // <- Something needs to be enabled
89
+ }
90
+ );
91
+
92
+ // Ensure the member expression got changed to a string
93
+ expect(output).toContain("console['log']");
94
+ });
95
+
96
+ test("Variant #6: Force object property keys to use strings instead", async () => {
97
+ var output = await JsConfuser.obfuscate(
98
+ `
99
+ var myObject = {
100
+ myKey: 1
101
+ }
102
+ `,
103
+ {
104
+ target: "node",
105
+ compact: true, // <- Something needs to be enabled
106
+ }
107
+ );
108
+
109
+ // Ensure key got changed to a string
110
+ expect(output).toContain("'myKey'");
111
+ });
112
+
113
+ test("Variant #7: Force Variable declarations to be expanded", async () => {
114
+ var output = await JsConfuser.obfuscate(
115
+ `
116
+ var myVar1, myVar2, myVar3;
117
+
118
+ switch(true){
119
+ case true:
120
+ var mySwitchVar1, mySwitchVar2, mySwitchVar3;
121
+ break;
122
+ }
123
+
124
+ {
125
+ var myBlockVar1;
126
+ var myBlockVar2;
127
+ var myBlockVar3;
128
+ }
129
+
130
+ if(true) var myIfVar1, myIfVar2, myIfVar3;
131
+ `,
132
+ {
133
+ target: "node",
134
+ compact: true, // <- Something needs to be enabled
135
+ }
136
+ );
137
+
138
+ // Ensure the variable declarations got changed
139
+ expect(output).toContain("var myVar1;");
140
+ expect(output).toContain("var myVar2;");
141
+ expect(output).toContain("var myVar3;");
142
+
143
+ // Ensure the switch declarations got changed
144
+ expect(output).toContain("var mySwitchVar1;");
145
+ expect(output).toContain("var mySwitchVar2;");
146
+ expect(output).toContain("var mySwitchVar3;");
147
+
148
+ // Ensure the block declarations got changed
149
+ expect(output).toContain("var myBlockVar1;");
150
+ expect(output).toContain("var myBlockVar2;");
151
+ expect(output).toContain("var myBlockVar3");
152
+
153
+ // Ensure the if-statement declarations got changed
154
+ expect(output).toContain("var myIfVar1;");
155
+ expect(output).toContain("var myIfVar2;");
156
+ expect(output).toContain("var myIfVar3");
157
+ });