js-confuser 1.5.8 → 1.6.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 (139) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +69 -0
  3. package/README.md +143 -7
  4. package/dist/index.js +33 -4
  5. package/dist/obfuscator.js +30 -31
  6. package/dist/options.js +4 -5
  7. package/dist/order.js +4 -6
  8. package/dist/probability.js +2 -4
  9. package/dist/templates/bufferToString.js +13 -0
  10. package/dist/templates/crash.js +2 -2
  11. package/dist/templates/es5.js +18 -0
  12. package/dist/transforms/antiTooling.js +1 -1
  13. package/dist/transforms/calculator.js +77 -21
  14. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  15. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
  16. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  17. package/dist/transforms/deadCode.js +33 -25
  18. package/dist/transforms/dispatcher.js +7 -6
  19. package/dist/transforms/es5/antiClass.js +6 -2
  20. package/dist/transforms/es5/antiDestructuring.js +3 -1
  21. package/dist/transforms/es5/es5.js +31 -34
  22. package/dist/transforms/eval.js +11 -0
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
  24. package/dist/transforms/extraction/objectExtraction.js +6 -1
  25. package/dist/transforms/finalizer.js +82 -0
  26. package/dist/transforms/flatten.js +82 -55
  27. package/dist/transforms/hexadecimalNumbers.js +34 -9
  28. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  29. package/dist/transforms/identifier/globalConcealing.js +10 -83
  30. package/dist/transforms/identifier/movedDeclarations.js +2 -8
  31. package/dist/transforms/identifier/renameVariables.js +39 -27
  32. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  33. package/dist/transforms/minify.js +80 -61
  34. package/dist/transforms/opaquePredicates.js +1 -1
  35. package/dist/transforms/preparation/preparation.js +2 -2
  36. package/dist/transforms/preparation.js +231 -0
  37. package/dist/transforms/renameLabels.js +1 -1
  38. package/dist/transforms/rgf.js +4 -5
  39. package/dist/transforms/stack.js +87 -26
  40. package/dist/transforms/string/encoding.js +150 -179
  41. package/dist/transforms/string/stringCompression.js +14 -15
  42. package/dist/transforms/string/stringConcealing.js +25 -8
  43. package/dist/transforms/string/stringEncoding.js +13 -24
  44. package/dist/transforms/transform.js +11 -18
  45. package/dist/traverse.js +24 -18
  46. package/dist/util/compare.js +2 -2
  47. package/dist/util/gen.js +15 -0
  48. package/dist/util/insert.js +31 -7
  49. package/dist/util/random.js +15 -0
  50. package/package.json +5 -5
  51. package/src/index.ts +57 -19
  52. package/src/obfuscator.ts +26 -29
  53. package/src/options.ts +17 -21
  54. package/src/order.ts +4 -8
  55. package/src/probability.ts +2 -3
  56. package/src/templates/bufferToString.ts +68 -0
  57. package/src/templates/crash.ts +5 -9
  58. package/src/templates/es5.ts +131 -0
  59. package/src/transforms/antiTooling.ts +1 -1
  60. package/src/transforms/calculator.ts +122 -59
  61. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  62. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
  63. package/src/transforms/deadCode.ts +383 -26
  64. package/src/transforms/dispatcher.ts +8 -6
  65. package/src/transforms/es5/antiClass.ts +10 -1
  66. package/src/transforms/es5/antiDestructuring.ts +3 -1
  67. package/src/transforms/es5/es5.ts +32 -77
  68. package/src/transforms/eval.ts +18 -0
  69. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
  70. package/src/transforms/extraction/objectExtraction.ts +12 -5
  71. package/src/transforms/finalizer.ts +75 -0
  72. package/src/transforms/flatten.ts +194 -151
  73. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  74. package/src/transforms/identifier/globalConcealing.ts +14 -103
  75. package/src/transforms/identifier/movedDeclarations.ts +4 -11
  76. package/src/transforms/identifier/renameVariables.ts +37 -30
  77. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  78. package/src/transforms/minify.ts +116 -77
  79. package/src/transforms/opaquePredicates.ts +2 -2
  80. package/src/transforms/preparation.ts +238 -0
  81. package/src/transforms/renameLabels.ts +2 -2
  82. package/src/transforms/rgf.ts +6 -7
  83. package/src/transforms/stack.ts +97 -37
  84. package/src/transforms/string/encoding.ts +115 -212
  85. package/src/transforms/string/stringCompression.ts +27 -18
  86. package/src/transforms/string/stringConcealing.ts +41 -11
  87. package/src/transforms/string/stringEncoding.ts +18 -18
  88. package/src/transforms/transform.ts +15 -21
  89. package/src/traverse.ts +24 -12
  90. package/src/types.ts +11 -2
  91. package/src/util/compare.ts +2 -2
  92. package/src/util/gen.ts +21 -1
  93. package/src/util/insert.ts +49 -9
  94. package/src/util/random.ts +13 -0
  95. package/test/code/Cash.test.ts +1 -1
  96. package/test/code/Dynamic.test.ts +12 -10
  97. package/test/code/ES6.src.js +136 -0
  98. package/test/code/ES6.test.ts +28 -2
  99. package/test/code/NewFeatures.test.ts +19 -0
  100. package/test/index.test.ts +15 -2
  101. package/test/probability.test.ts +44 -0
  102. package/test/templates/template.test.ts +1 -1
  103. package/test/transforms/antiTooling.test.ts +52 -0
  104. package/test/transforms/calculator.test.ts +40 -0
  105. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
  106. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  107. package/test/transforms/deadCode.test.ts +66 -15
  108. package/test/transforms/dispatcher.test.ts +44 -1
  109. package/test/transforms/es5/antiClass.test.ts +33 -0
  110. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  111. package/test/transforms/eval.test.ts +53 -0
  112. package/test/transforms/extraction/objectExtraction.test.ts +21 -0
  113. package/test/transforms/flatten.test.ts +195 -3
  114. package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
  115. package/test/transforms/identifier/renameVariables.test.ts +108 -0
  116. package/test/transforms/lock/antiDebug.test.ts +2 -2
  117. package/test/transforms/minify.test.ts +151 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +56 -29
  120. package/test/transforms/stack.test.ts +91 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +115 -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/compare.test.ts +23 -1
  127. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  128. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  129. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  130. package/src/transforms/hexadecimalNumbers.ts +0 -31
  131. package/src/transforms/hideInitializingCode.ts +0 -432
  132. package/src/transforms/label.ts +0 -64
  133. package/src/transforms/preparation/nameConflicts.ts +0 -102
  134. package/src/transforms/preparation/preparation.ts +0 -176
  135. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  136. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  137. package/test/transforms/hideInitializingCode.test.ts +0 -336
  138. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  139. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -0,0 +1,173 @@
1
+ import JsConfuser from "../../../src/index";
2
+
3
+ test("Variant #1: Join expressions in a sequence expression", async () => {
4
+ var output = await JsConfuser(
5
+ `
6
+ TEST_OUTPUT=0;
7
+ TEST_OUTPUT++;
8
+ `,
9
+ { target: "node", controlFlowFlattening: true }
10
+ );
11
+
12
+ expect(output).toContain("(TEST_OUTPUT=0,TEST_OUTPUT++");
13
+
14
+ var TEST_OUTPUT;
15
+ eval(output);
16
+
17
+ expect(TEST_OUTPUT).toStrictEqual(1);
18
+ });
19
+
20
+ test("Variant #2: If Statement", async () => {
21
+ var output = await JsConfuser(
22
+ `
23
+ TEST_OUTPUT=0;
24
+ if(true){
25
+ TEST_OUTPUT++;
26
+ }
27
+ `,
28
+ { target: "node", controlFlowFlattening: true }
29
+ );
30
+
31
+ expect(output).toContain("if(TEST_OUTPUT=0,true)");
32
+
33
+ var TEST_OUTPUT;
34
+ eval(output);
35
+
36
+ expect(TEST_OUTPUT).toStrictEqual(1);
37
+ });
38
+
39
+ test("Variant #3: ForStatement (Variable Declaration initializer)", async () => {
40
+ var output = await JsConfuser(
41
+ `
42
+ TEST_OUTPUT=0;
43
+ for(var i =0; i < 10; i++){
44
+ TEST_OUTPUT++;
45
+ }
46
+ `,
47
+ { target: "node", controlFlowFlattening: true }
48
+ );
49
+
50
+ expect(output).toContain("for(var i=(TEST_OUTPUT=0,0)");
51
+
52
+ var TEST_OUTPUT;
53
+ eval(output);
54
+
55
+ expect(TEST_OUTPUT).toStrictEqual(10);
56
+ });
57
+
58
+ test("Variant #4: ForStatement (Assignment expression initializer)", async () => {
59
+ var output = await JsConfuser(
60
+ `
61
+ TEST_OUTPUT=0;
62
+ for(i = 0; i < 10; i++){
63
+ TEST_OUTPUT++;
64
+ }
65
+ `,
66
+ { target: "node", controlFlowFlattening: true }
67
+ );
68
+
69
+ expect(output).toContain("for(i=(TEST_OUTPUT=0,0)");
70
+
71
+ var TEST_OUTPUT, i;
72
+ eval(output);
73
+
74
+ expect(TEST_OUTPUT).toStrictEqual(10);
75
+ });
76
+
77
+ test("Variant #5: Return statement", async () => {
78
+ var output = await JsConfuser(
79
+ `
80
+ function fn(){
81
+ TEST_OUTPUT = 10;
82
+ return "Value";
83
+ }
84
+ fn();
85
+ `,
86
+ { target: "node", controlFlowFlattening: true }
87
+ );
88
+
89
+ expect(output).toContain("return TEST_OUTPUT=10,'Value'}");
90
+
91
+ var TEST_OUTPUT;
92
+ eval(output);
93
+
94
+ expect(TEST_OUTPUT).toStrictEqual(10);
95
+ });
96
+
97
+ test("Variant #6: Return statement (no argument)", async () => {
98
+ var output = await JsConfuser(
99
+ `
100
+ function fn(){
101
+ TEST_OUTPUT = 10;
102
+ return;
103
+ }
104
+ fn();
105
+ `,
106
+ { target: "node", controlFlowFlattening: true }
107
+ );
108
+
109
+ expect(output).toContain("return TEST_OUTPUT=10,undefined}");
110
+
111
+ var TEST_OUTPUT;
112
+ eval(output);
113
+
114
+ expect(TEST_OUTPUT).toStrictEqual(10);
115
+ });
116
+
117
+ test("Variant #7: Throw statement", async () => {
118
+ var output = await JsConfuser(
119
+ `
120
+ function fn(){
121
+ TEST_OUTPUT = "Correct Value";
122
+ throw new Error("My Error")
123
+ }
124
+ try {
125
+ fn();
126
+ } catch(e){
127
+
128
+ }
129
+ `,
130
+ { target: "node", controlFlowFlattening: true }
131
+ );
132
+
133
+ expect(output).toContain("throw TEST_OUTPUT='Correct Value',new Error");
134
+
135
+ var TEST_OUTPUT;
136
+ eval(output);
137
+
138
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
139
+ });
140
+
141
+ test("Variant #8: Variable declaration", async () => {
142
+ var output = await JsConfuser(
143
+ `
144
+ TEST_OUTPUT = "Correct Value";
145
+ var x = 1, y = 2;
146
+ `,
147
+ { target: "node", controlFlowFlattening: true }
148
+ );
149
+
150
+ expect(output).toContain("var x=(TEST_OUTPUT='Correct Value',1)");
151
+
152
+ var TEST_OUTPUT;
153
+ eval(output);
154
+
155
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
156
+ });
157
+
158
+ test("Variant #9: Variable declaration (no initializer)", async () => {
159
+ var output = await JsConfuser(
160
+ `
161
+ TEST_OUTPUT = "Correct Value";
162
+ var x,y;
163
+ `,
164
+ { target: "node", controlFlowFlattening: true }
165
+ );
166
+
167
+ expect(output).toContain("var x=(TEST_OUTPUT='Correct Value',undefined)");
168
+
169
+ var TEST_OUTPUT;
170
+ eval(output);
171
+
172
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
173
+ });
@@ -1,21 +1,25 @@
1
1
  import JsConfuser from "../../src/index";
2
2
 
3
- it("should execute properly", async () => {
3
+ test("Variant #1: Execute properly", async () => {
4
4
  var code = `
5
- var array = [];
6
-
7
- array.push(1);
8
- array.push(2);
9
- array.push(3);
10
- array.push(4);
11
- array.push(5);
12
- array.push(6);
13
- array.push(7);
14
- array.push(8);
15
- array.push(9);
16
- array.push(10);
17
-
18
- input(array);
5
+ function myFunction(){
6
+ var array = [];
7
+
8
+ array.push(1);
9
+ array.push(2);
10
+ array.push(3);
11
+ array.push(4);
12
+ array.push(5);
13
+ array.push(6);
14
+ array.push(7);
15
+ array.push(8);
16
+ array.push(9);
17
+ array.push(10);
18
+
19
+ input(array);
20
+ }
21
+
22
+ myFunction();
19
23
  `;
20
24
 
21
25
  var output = await JsConfuser(code, {
@@ -23,6 +27,53 @@ it("should execute properly", async () => {
23
27
  deadCode: true,
24
28
  });
25
29
 
30
+ // Ensure Dead code was added
31
+ expect(output).toContain("if");
32
+
33
+ var value = "never_called";
34
+ function input(valueIn) {
35
+ value = valueIn;
36
+ }
37
+
38
+ eval(output);
39
+
40
+ expect(value).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
41
+ });
42
+
43
+ test("Variant #2: Preserve 'use strict' directive", async () => {
44
+ var code = `
45
+ 'use strict';
46
+ function myFunction(){
47
+ var array = [];
48
+
49
+ array.push(1);
50
+ array.push(2);
51
+ array.push(3);
52
+ array.push(4);
53
+ array.push(5);
54
+ array.push(6);
55
+ array.push(7);
56
+ array.push(8);
57
+ array.push(9);
58
+ array.push(10);
59
+
60
+ input(array);
61
+ }
62
+
63
+ myFunction();
64
+ `;
65
+
66
+ var output = await JsConfuser(code, {
67
+ target: "browser",
68
+ deadCode: true,
69
+ });
70
+
71
+ // Ensure 'use strict' was preversed
72
+ expect(output.startsWith("'use strict'")).toStrictEqual(true);
73
+
74
+ // Ensure Dead code was added
75
+ expect(output).toContain("if");
76
+
26
77
  var value = "never_called";
27
78
  function input(valueIn) {
28
79
  value = valueIn;
@@ -1,4 +1,3 @@
1
- import { isObject } from "util";
2
1
  import JsConfuser from "../../src/index";
3
2
 
4
3
  it("should middleman function calls", async () => {
@@ -330,3 +329,47 @@ it("should apply to every level of the code", async () => {
330
329
 
331
330
  expect(value).toStrictEqual(100);
332
331
  });
332
+
333
+ // https://github.com/MichaelXF/js-confuser/issues/77
334
+ it("should work with code that uses toString() function", async () => {
335
+ var output = await JsConfuser(
336
+ `
337
+ function myFunction(){
338
+
339
+ }
340
+
341
+ TEST_OUTPUT = toString();
342
+ `,
343
+ {
344
+ target: "node",
345
+ dispatcher: true,
346
+ }
347
+ );
348
+
349
+ var toString = () => "Correct Value";
350
+ var TEST_OUTPUT;
351
+
352
+ eval(output);
353
+
354
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
355
+ });
356
+
357
+ test("Variant #16: Don't change functions that use 'eval'", async () => {
358
+ var output = await JsConfuser(
359
+ `
360
+ function myEvalFunction(){
361
+ return eval("1+1");
362
+ }
363
+
364
+ TEST_OUTPUT = myEvalFunction();
365
+ `,
366
+ { target: "node", dispatcher: true }
367
+ );
368
+
369
+ expect(output).not.toContain("dispatcher");
370
+
371
+ var TEST_OUTPUT;
372
+ eval(output);
373
+
374
+ expect(TEST_OUTPUT).toStrictEqual(2);
375
+ });
@@ -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
+ });
@@ -139,3 +139,19 @@ it("should fix destructuring inside the try...catch clause", async () => {
139
139
 
140
140
  expect(TEST_VARIABLE).toStrictEqual(100);
141
141
  });
142
+
143
+ it("should fix destructuring member expressions", async () => {
144
+ var code = `
145
+ var myObject = { nested: {} };
146
+ [myObject.key1, myObject["key2"], myObject.nested.key3] = [1, 2, 3];
147
+
148
+ TEST_VARIABLE = [myObject.key1, myObject.key2, myObject.nested.key3];
149
+ `;
150
+
151
+ var output = await JsConfuser(code, { target: "node", es5: true });
152
+
153
+ var TEST_VARIABLE;
154
+ eval(output);
155
+
156
+ expect(TEST_VARIABLE).toStrictEqual([1, 2, 3]);
157
+ });
@@ -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
- expect(output).toContain("set");
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
- expect(output).toContain("set");
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,193 @@ 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
+ });
409
+
410
+ it("should work with assignment expressions in the return statement", async () => {
411
+ var output = await JsConfuser(
412
+ `
413
+ var outside;
414
+
415
+ function myFunction(){
416
+ return outside = "Correct Value"
417
+ }
418
+
419
+ myFunction(outside);
420
+
421
+ TEST_OUTPUT = outside;
422
+
423
+ `,
424
+ { target: "node", flatten: true }
425
+ );
426
+
427
+ // Ensure flat was applied
428
+ expect(output).toContain("_flat_myFunction");
429
+
430
+ var TEST_OUTPUT;
431
+ eval(output);
432
+
433
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
434
+ });
435
+
436
+ it("should work with 'use strict' directive", async () => {
437
+ var output = await JsConfuser(
438
+ `
439
+ function myFunction(){
440
+ "use strict";
441
+
442
+ return "Correct Value";
443
+ }
444
+
445
+ TEST_OUTPUT = myFunction();
446
+ `,
447
+ { target: "node", flatten: true }
448
+ );
449
+
450
+ // Ensure flat was applied
451
+ expect(output).toContain("_flat_myFunction");
452
+
453
+ var TEST_OUTPUT;
454
+ eval(output);
455
+
456
+ expect(TEST_OUTPUT).toStrictEqual("Correct Value");
457
+ });
@@ -157,3 +157,30 @@ 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 #7: 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
+ });