js-confuser 1.7.2 → 2.0.0-alpha.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 (263) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +6 -4
  2. package/.github/workflows/node.js.yml +1 -1
  3. package/CHANGELOG.md +105 -0
  4. package/Migration.md +57 -0
  5. package/README.md +23 -913
  6. package/dist/constants.js +69 -13
  7. package/dist/index.js +108 -152
  8. package/dist/obfuscator.js +316 -118
  9. package/dist/options.js +1 -109
  10. package/dist/order.js +30 -30
  11. package/dist/presets.js +47 -45
  12. package/dist/probability.js +25 -32
  13. package/dist/templates/bufferToStringTemplate.js +9 -0
  14. package/dist/templates/deadCodeTemplates.js +9 -0
  15. package/dist/templates/getGlobalTemplate.js +19 -0
  16. package/dist/templates/integrityTemplate.js +30 -0
  17. package/dist/templates/setFunctionLengthTemplate.js +9 -0
  18. package/dist/templates/stringCompressionTemplate.js +10 -0
  19. package/dist/templates/tamperProtectionTemplates.js +21 -0
  20. package/dist/templates/template.js +213 -93
  21. package/dist/transforms/astScrambler.js +100 -0
  22. package/dist/transforms/calculator.js +70 -127
  23. package/dist/transforms/controlFlowFlattening.js +1182 -0
  24. package/dist/transforms/deadCode.js +62 -577
  25. package/dist/transforms/dispatcher.js +300 -309
  26. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +88 -189
  27. package/dist/transforms/extraction/objectExtraction.js +131 -215
  28. package/dist/transforms/finalizer.js +56 -59
  29. package/dist/transforms/flatten.js +275 -276
  30. package/dist/transforms/functionOutlining.js +230 -0
  31. package/dist/transforms/identifier/globalConcealing.js +217 -103
  32. package/dist/transforms/identifier/movedDeclarations.js +167 -91
  33. package/dist/transforms/identifier/renameVariables.js +240 -187
  34. package/dist/transforms/lock/integrity.js +61 -184
  35. package/dist/transforms/lock/lock.js +263 -303
  36. package/dist/transforms/minify.js +431 -436
  37. package/dist/transforms/opaquePredicates.js +65 -118
  38. package/dist/transforms/pack.js +160 -0
  39. package/dist/transforms/plugin.js +179 -0
  40. package/dist/transforms/preparation.js +263 -163
  41. package/dist/transforms/renameLabels.js +132 -56
  42. package/dist/transforms/rgf.js +142 -240
  43. package/dist/transforms/shuffle.js +52 -145
  44. package/dist/transforms/string/encoding.js +45 -173
  45. package/dist/transforms/string/stringCompression.js +81 -126
  46. package/dist/transforms/string/stringConcealing.js +189 -224
  47. package/dist/transforms/string/stringEncoding.js +32 -40
  48. package/dist/transforms/string/stringSplitting.js +54 -55
  49. package/dist/transforms/variableMasking.js +232 -0
  50. package/dist/utils/ControlObject.js +125 -0
  51. package/dist/utils/IntGen.js +46 -0
  52. package/dist/utils/NameGen.js +106 -0
  53. package/dist/utils/ast-utils.js +560 -0
  54. package/dist/utils/function-utils.js +56 -0
  55. package/dist/utils/gen-utils.js +48 -0
  56. package/dist/utils/node.js +77 -0
  57. package/dist/utils/object-utils.js +21 -0
  58. package/dist/utils/random-utils.js +91 -0
  59. package/dist/utils/static-utils.js +64 -0
  60. package/dist/validateOptions.js +122 -0
  61. package/index.d.ts +1 -17
  62. package/package.json +27 -22
  63. package/src/constants.ts +139 -77
  64. package/src/index.ts +70 -163
  65. package/src/obfuscationResult.ts +43 -0
  66. package/src/obfuscator.ts +328 -135
  67. package/src/options.ts +154 -623
  68. package/src/order.ts +14 -14
  69. package/src/presets.ts +39 -34
  70. package/src/probability.ts +21 -36
  71. package/src/templates/{bufferToString.ts → bufferToStringTemplate.ts} +5 -54
  72. package/src/templates/deadCodeTemplates.ts +1185 -0
  73. package/src/templates/getGlobalTemplate.ts +72 -0
  74. package/src/templates/integrityTemplate.ts +69 -0
  75. package/src/templates/setFunctionLengthTemplate.ts +11 -0
  76. package/src/templates/stringCompressionTemplate.ts +42 -0
  77. package/src/templates/tamperProtectionTemplates.ts +116 -0
  78. package/src/templates/template.ts +183 -92
  79. package/src/transforms/astScrambler.ts +99 -0
  80. package/src/transforms/calculator.ts +96 -224
  81. package/src/transforms/controlFlowFlattening.ts +1594 -0
  82. package/src/transforms/deadCode.ts +85 -628
  83. package/src/transforms/dispatcher.ts +431 -636
  84. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +147 -299
  85. package/src/transforms/extraction/objectExtraction.ts +160 -333
  86. package/src/transforms/finalizer.ts +63 -64
  87. package/src/transforms/flatten.ts +439 -557
  88. package/src/transforms/functionOutlining.ts +225 -0
  89. package/src/transforms/identifier/globalConcealing.ts +261 -189
  90. package/src/transforms/identifier/movedDeclarations.ts +228 -142
  91. package/src/transforms/identifier/renameVariables.ts +252 -258
  92. package/src/transforms/lock/integrity.ts +84 -260
  93. package/src/transforms/lock/lock.ts +342 -491
  94. package/src/transforms/minify.ts +523 -663
  95. package/src/transforms/opaquePredicates.ts +90 -229
  96. package/src/transforms/pack.ts +195 -0
  97. package/src/transforms/plugin.ts +185 -0
  98. package/src/transforms/preparation.ts +337 -215
  99. package/src/transforms/renameLabels.ts +176 -77
  100. package/src/transforms/rgf.ts +293 -386
  101. package/src/transforms/shuffle.ts +80 -254
  102. package/src/transforms/string/encoding.ts +26 -129
  103. package/src/transforms/string/stringCompression.ts +118 -236
  104. package/src/transforms/string/stringConcealing.ts +255 -339
  105. package/src/transforms/string/stringEncoding.ts +28 -47
  106. package/src/transforms/string/stringSplitting.ts +61 -75
  107. package/src/transforms/variableMasking.ts +257 -0
  108. package/src/utils/ControlObject.ts +141 -0
  109. package/src/utils/IntGen.ts +33 -0
  110. package/src/utils/NameGen.ts +106 -0
  111. package/src/utils/ast-utils.ts +667 -0
  112. package/src/utils/function-utils.ts +50 -0
  113. package/src/utils/gen-utils.ts +48 -0
  114. package/src/utils/node.ts +78 -0
  115. package/src/utils/object-utils.ts +21 -0
  116. package/src/utils/random-utils.ts +79 -0
  117. package/src/utils/static-utils.ts +66 -0
  118. package/src/validateOptions.ts +256 -0
  119. package/tsconfig.json +13 -8
  120. package/babel.config.js +0 -12
  121. package/dev.js +0 -8
  122. package/dist/compiler.js +0 -34
  123. package/dist/parser.js +0 -59
  124. package/dist/precedence.js +0 -66
  125. package/dist/templates/bufferToString.js +0 -108
  126. package/dist/templates/crash.js +0 -59
  127. package/dist/templates/es5.js +0 -137
  128. package/dist/templates/functionLength.js +0 -34
  129. package/dist/templates/globals.js +0 -9
  130. package/dist/transforms/antiTooling.js +0 -88
  131. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +0 -1281
  132. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +0 -131
  133. package/dist/transforms/es5/antiClass.js +0 -164
  134. package/dist/transforms/es5/antiDestructuring.js +0 -193
  135. package/dist/transforms/es5/antiES6Object.js +0 -185
  136. package/dist/transforms/es5/antiSpreadOperator.js +0 -35
  137. package/dist/transforms/es5/antiTemplate.js +0 -66
  138. package/dist/transforms/es5/es5.js +0 -123
  139. package/dist/transforms/extraction/classExtraction.js +0 -83
  140. package/dist/transforms/identifier/globalAnalysis.js +0 -70
  141. package/dist/transforms/identifier/variableAnalysis.js +0 -104
  142. package/dist/transforms/lock/antiDebug.js +0 -76
  143. package/dist/transforms/stack.js +0 -343
  144. package/dist/transforms/transform.js +0 -350
  145. package/dist/traverse.js +0 -110
  146. package/dist/util/compare.js +0 -145
  147. package/dist/util/gen.js +0 -564
  148. package/dist/util/guard.js +0 -9
  149. package/dist/util/identifiers.js +0 -355
  150. package/dist/util/insert.js +0 -362
  151. package/dist/util/math.js +0 -19
  152. package/dist/util/object.js +0 -40
  153. package/dist/util/random.js +0 -130
  154. package/dist/util/scope.js +0 -20
  155. package/docs/ControlFlowFlattening.md +0 -595
  156. package/docs/Countermeasures.md +0 -63
  157. package/docs/ES5.md +0 -197
  158. package/docs/Integrity.md +0 -75
  159. package/docs/RGF.md +0 -419
  160. package/samples/example.js +0 -15
  161. package/samples/high.js +0 -1
  162. package/samples/input.js +0 -3
  163. package/samples/javascriptobfuscator.com.js +0 -8
  164. package/samples/jscrambler_advanced.js +0 -1894
  165. package/samples/jscrambler_light.js +0 -1134
  166. package/samples/low.js +0 -1
  167. package/samples/medium.js +0 -1
  168. package/samples/obfuscator.io.js +0 -1686
  169. package/samples/preemptive.com.js +0 -16
  170. package/src/compiler.ts +0 -35
  171. package/src/parser.ts +0 -49
  172. package/src/precedence.ts +0 -61
  173. package/src/templates/crash.ts +0 -55
  174. package/src/templates/es5.ts +0 -131
  175. package/src/templates/functionLength.ts +0 -32
  176. package/src/templates/globals.ts +0 -3
  177. package/src/transforms/antiTooling.ts +0 -102
  178. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +0 -2146
  179. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +0 -179
  180. package/src/transforms/es5/antiClass.ts +0 -272
  181. package/src/transforms/es5/antiDestructuring.ts +0 -294
  182. package/src/transforms/es5/antiES6Object.ts +0 -267
  183. package/src/transforms/es5/antiSpreadOperator.ts +0 -56
  184. package/src/transforms/es5/antiTemplate.ts +0 -98
  185. package/src/transforms/es5/es5.ts +0 -149
  186. package/src/transforms/extraction/classExtraction.ts +0 -168
  187. package/src/transforms/identifier/globalAnalysis.ts +0 -85
  188. package/src/transforms/identifier/variableAnalysis.ts +0 -118
  189. package/src/transforms/lock/antiDebug.ts +0 -112
  190. package/src/transforms/stack.ts +0 -551
  191. package/src/transforms/transform.ts +0 -453
  192. package/src/traverse.ts +0 -120
  193. package/src/types.ts +0 -131
  194. package/src/util/compare.ts +0 -181
  195. package/src/util/gen.ts +0 -651
  196. package/src/util/guard.ts +0 -7
  197. package/src/util/identifiers.ts +0 -494
  198. package/src/util/insert.ts +0 -419
  199. package/src/util/math.ts +0 -15
  200. package/src/util/object.ts +0 -39
  201. package/src/util/random.ts +0 -141
  202. package/src/util/scope.ts +0 -21
  203. package/test/code/Cash.src.js +0 -1011
  204. package/test/code/Cash.test.ts +0 -49
  205. package/test/code/Dynamic.src.js +0 -118
  206. package/test/code/Dynamic.test.ts +0 -49
  207. package/test/code/ES6.src.js +0 -235
  208. package/test/code/ES6.test.ts +0 -42
  209. package/test/code/NewFeatures.test.ts +0 -19
  210. package/test/code/StrictMode.src.js +0 -65
  211. package/test/code/StrictMode.test.js +0 -37
  212. package/test/compare.test.ts +0 -104
  213. package/test/index.test.ts +0 -249
  214. package/test/options.test.ts +0 -132
  215. package/test/presets.test.ts +0 -22
  216. package/test/probability.test.ts +0 -44
  217. package/test/templates/template.test.ts +0 -14
  218. package/test/transforms/antiTooling.test.ts +0 -52
  219. package/test/transforms/calculator.test.ts +0 -78
  220. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +0 -1274
  221. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +0 -192
  222. package/test/transforms/deadCode.test.ts +0 -85
  223. package/test/transforms/dispatcher.test.ts +0 -457
  224. package/test/transforms/es5/antiClass.test.ts +0 -427
  225. package/test/transforms/es5/antiDestructuring.test.ts +0 -157
  226. package/test/transforms/es5/antiES6Object.test.ts +0 -245
  227. package/test/transforms/es5/antiTemplate.test.ts +0 -116
  228. package/test/transforms/es5/es5.test.ts +0 -110
  229. package/test/transforms/extraction/classExtraction.test.ts +0 -86
  230. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +0 -200
  231. package/test/transforms/extraction/objectExtraction.test.ts +0 -491
  232. package/test/transforms/flatten.test.ts +0 -721
  233. package/test/transforms/hexadecimalNumbers.test.ts +0 -62
  234. package/test/transforms/identifier/globalConcealing.test.ts +0 -72
  235. package/test/transforms/identifier/movedDeclarations.test.ts +0 -275
  236. package/test/transforms/identifier/renameVariables.test.ts +0 -621
  237. package/test/transforms/lock/antiDebug.test.ts +0 -66
  238. package/test/transforms/lock/browserLock.test.ts +0 -129
  239. package/test/transforms/lock/countermeasures.test.ts +0 -100
  240. package/test/transforms/lock/integrity.test.ts +0 -161
  241. package/test/transforms/lock/lock.test.ts +0 -204
  242. package/test/transforms/lock/osLock.test.ts +0 -312
  243. package/test/transforms/lock/selfDefending.test.ts +0 -68
  244. package/test/transforms/minify.test.ts +0 -575
  245. package/test/transforms/opaquePredicates.test.ts +0 -43
  246. package/test/transforms/preparation.test.ts +0 -157
  247. package/test/transforms/renameLabels.test.ts +0 -95
  248. package/test/transforms/rgf.test.ts +0 -378
  249. package/test/transforms/shuffle.test.ts +0 -135
  250. package/test/transforms/stack.test.ts +0 -573
  251. package/test/transforms/string/stringCompression.test.ts +0 -120
  252. package/test/transforms/string/stringConcealing.test.ts +0 -299
  253. package/test/transforms/string/stringEncoding.test.ts +0 -95
  254. package/test/transforms/string/stringSplitting.test.ts +0 -135
  255. package/test/transforms/transform.test.ts +0 -66
  256. package/test/traverse.test.ts +0 -139
  257. package/test/util/compare.test.ts +0 -34
  258. package/test/util/gen.test.ts +0 -121
  259. package/test/util/identifiers.test.ts +0 -253
  260. package/test/util/insert.test.ts +0 -142
  261. package/test/util/math.test.ts +0 -5
  262. package/test/util/random.test.ts +0 -71
  263. /package/dist/{types.js → obfuscationResult.js} +0 -0
@@ -1,1274 +0,0 @@
1
- import JsConfuser from "../../../src/index";
2
-
3
- test("Variant #1: Obfuscate code and still execute in correct order", async () => {
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
- TEST_OUTPUT = array;
19
- `;
20
-
21
- var output = await JsConfuser(code, {
22
- target: "browser",
23
- controlFlowFlattening: true,
24
- });
25
-
26
- // Ensure Control Flow Flattening applied
27
- expect(output).toContain("while");
28
-
29
- // Ensure the output is the exact same
30
- var TEST_OUTPUT;
31
- eval(output);
32
-
33
- expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
34
- });
35
-
36
- test("Variant #2: Obfuscate for loops", async () => {
37
- var code = `
38
- var array = [];
39
-
40
- for ( var i = 1; i <= 10; i++ ) {
41
- array.push(i);
42
- }
43
-
44
- TEST_OUTPUT = array;
45
- `;
46
-
47
- var output = await JsConfuser(code, {
48
- target: "browser",
49
- controlFlowFlattening: true,
50
- });
51
-
52
- // Ensure Control Flow Flattening applied
53
- expect(output).toContain("while");
54
-
55
- // Ensure the for statement got flattened
56
- expect(output).not.toContain("for");
57
-
58
- // Ensure the output is the exact same
59
- var TEST_OUTPUT;
60
-
61
- eval(output);
62
- expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
63
- });
64
-
65
- test("Variant #3: Obfuscate while loops", async () => {
66
- var code = `
67
- var array = [];
68
- var i = 1;
69
-
70
- while ( i <= 10 ) {
71
- array.push(i);
72
- i++
73
- }
74
-
75
- TEST_OUTPUT = array;
76
- `;
77
-
78
- var output = await JsConfuser(code, {
79
- target: "browser",
80
- controlFlowFlattening: true,
81
- });
82
-
83
- // Ensure Control Flow Flattening applied
84
- expect(output).toContain("while");
85
-
86
- // Ensure the output is the exact same
87
- var TEST_OUTPUT;
88
- eval(output);
89
-
90
- expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
91
- });
92
-
93
- test("Variant #4: Work with break statements", async () => {
94
- var code = `
95
-
96
- var TEST_ARRAY = [];
97
-
98
- for ( var i =1; i < 50; i++ ) {
99
- if ( i == 11 ) {
100
- break;
101
- }
102
- TEST_ARRAY.push(i);
103
- }
104
-
105
- TEST_OUTPUT = TEST_ARRAY;
106
- `;
107
-
108
- var output = await JsConfuser(code, {
109
- target: "browser",
110
- controlFlowFlattening: true,
111
- });
112
-
113
- // Ensure Control Flow Flattening applied
114
- expect(output).toContain("switch");
115
- expect(output).toContain("while");
116
-
117
- // Ensure the output is the exact same
118
- var TEST_OUTPUT;
119
-
120
- eval(output);
121
- expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
122
- });
123
-
124
- test("Variant #5: Don't obfuscate code with `let` (Lexically bound variables)", async () => {
125
- var code = `
126
- let array = [];
127
-
128
- array.push(1);
129
- array.push(2);
130
- array.push(3);
131
- array.push(4);
132
- array.push(5);
133
- array.push(6);
134
- array.push(7);
135
- array.push(8);
136
- array.push(9);
137
- array.push(10);
138
-
139
- TEST_OUTPUT = array;
140
- `;
141
-
142
- var output = await JsConfuser(code, {
143
- target: "node",
144
- controlFlowFlattening: true,
145
- });
146
-
147
- // Ensure Control Flow Flattening did NOT apply here
148
- expect(output).not.toContain("while");
149
-
150
- // Ensure the output is the exact same
151
- var TEST_OUTPUT;
152
- eval(output);
153
-
154
- expect(TEST_OUTPUT).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
155
- });
156
-
157
- test("Variant #6: Don't obfuscate code with `let` (Lexically bound variables)", async () => {
158
- var code = `
159
- var array=[];
160
- for ( let i =1; i <= 10; i++ ) {
161
- array.push(i);
162
- }
163
-
164
- TEST_OUTPUT = array;
165
- `;
166
-
167
- var output = await JsConfuser(code, {
168
- target: "node",
169
- controlFlowFlattening: true,
170
- });
171
-
172
- // Ensure Control Flow Flattening did NOT apply here
173
- expect(output).not.toContain("while");
174
-
175
- // Ensure the output is the exact same
176
- var TEST_OUTPUT;
177
- eval(output);
178
-
179
- expect(TEST_OUTPUT).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
180
- });
181
-
182
- test("Variant #7: Allow option to be set a percentage threshold", async () => {
183
- var code = `
184
- var array = [];
185
- var i = 1;
186
-
187
- while ( i <= 10 ) {
188
- array.push(i);
189
- i++
190
- }
191
-
192
- TEST_OUTPUT = array;
193
- `;
194
-
195
- var output = await JsConfuser(code, {
196
- target: "browser",
197
- controlFlowFlattening: 0.5,
198
- });
199
-
200
- // Ensure the output is the exact same
201
- var TEST_OUTPUT;
202
-
203
- eval(output);
204
- expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
205
- });
206
-
207
- test("Variant #8: Work when obfuscated multiple times", async () => {
208
- var code = `
209
- var array = [];
210
-
211
- switch(true){
212
- case true: // Always true
213
- if(true){ // Always true
214
- var i;
215
-
216
- for ( i = 1; i <= 10; i++ ) {
217
- if(typeof i === "number") { // Always true
218
- array.push(i);
219
-
220
- var filler1;
221
- var filler2;
222
- var filler3;
223
- }
224
-
225
- var filler1;
226
- var filler2;
227
- var filler3;
228
- }
229
-
230
- var filler1;
231
- var filler2;
232
- var filler3;
233
- }
234
-
235
- var filler1;
236
- var filler2;
237
- var filler3;
238
- break;
239
- }
240
-
241
- TEST_OUTPUT = array;
242
- `; // [1,2,3,4,5,6,7,8,9,10]
243
-
244
- var output = await JsConfuser(code, {
245
- target: "node",
246
- controlFlowFlattening: true,
247
- });
248
-
249
- // Ensure Control Flow Flattening applied
250
- expect(output).toContain("while");
251
-
252
- var doublyObfuscated = await JsConfuser(output, {
253
- target: "node",
254
- controlFlowFlattening: true,
255
- });
256
-
257
- // Ensure the output is the exact same
258
- var TEST_OUTPUT;
259
-
260
- eval(doublyObfuscated);
261
- expect(TEST_OUTPUT).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
262
- });
263
-
264
- test("Variant #9: Don't entangle floats or NaN", async () => {
265
- var output = await JsConfuser(
266
- `
267
- function TEST_FUNCTION(){
268
-
269
- var a = NaN;
270
- var b = 10.01;
271
- var c = 15.01;
272
- var d = "MyString";
273
- input(b + c)
274
- }
275
-
276
- TEST_FUNCTION()
277
- `,
278
- {
279
- target: "node",
280
- controlFlowFlattening: true,
281
- }
282
- );
283
-
284
- expect(output).toContain("10.01");
285
- expect(output).toContain("15.01");
286
- expect(output).toContain("NaN");
287
- expect(output).toContain("MyString");
288
-
289
- var value = "never_called";
290
- function input(valueIn) {
291
- value = valueIn;
292
- }
293
-
294
- eval(output);
295
- expect(value).toStrictEqual(25.02);
296
- });
297
-
298
- test("Variant #10: Correctly entangle property keys", async () => {
299
- var output = await JsConfuser(
300
- `
301
- function TEST_FUNCTION(){
302
-
303
- var obj = {
304
- 10: 10,
305
- 9: 9,
306
- 8: 8,
307
- 7: 7,
308
- 6: 6,
309
- 5: 5,
310
- 4: 4,
311
- 3: 3,
312
- 2: 2,
313
- 1: 1,
314
- }
315
-
316
- var ten = obj["5"] + obj["3"] + obj["2"];
317
-
318
- input(ten)
319
- }
320
-
321
- TEST_FUNCTION()
322
- `,
323
- {
324
- target: "node",
325
- controlFlowFlattening: true,
326
- }
327
- );
328
-
329
- var value = "never_called";
330
- function input(valueIn) {
331
- value = valueIn;
332
- }
333
-
334
- eval(output);
335
- expect(value).toStrictEqual(10);
336
- });
337
-
338
- test("Variant #11: Flatten nested if statements", async () => {
339
- var output = await JsConfuser(
340
- `
341
- TEST_ARRAY = [];
342
-
343
- if(true){
344
- TEST_ARRAY.push(1);
345
- } else {
346
- TEST_ARRAY.push(-1);
347
- }
348
-
349
- if(true){
350
- TEST_ARRAY.push(2);
351
- }
352
-
353
- if(false){
354
- TEST_ARRAY.push(-1);
355
- }
356
-
357
- if(true){
358
- TEST_ARRAY.push(3);
359
- if(true){
360
- TEST_ARRAY.push(4);
361
- } else {
362
- TEST_ARRAY.push(-1);
363
- }
364
- TEST_ARRAY.push(5);
365
- }
366
- var fillerExpr1;
367
- var fillerExpr2;
368
- var fillerExpr3;
369
- var fillerExpr4;
370
- var fillerExpr5;
371
- `,
372
- {
373
- target: "node",
374
- controlFlowFlattening: true,
375
- }
376
- );
377
-
378
- var TEST_ARRAY;
379
-
380
- eval(output);
381
- expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
382
- });
383
-
384
- test("Variant #12: Flatten nested for loops", async () => {
385
- var output = await JsConfuser(
386
- `
387
- TEST_ARRAY = [];
388
-
389
- for ( var i = -5; i < 0; i++ ) {
390
- var o = 0;
391
- for ( var j = 1; j < 4; j++ ) {
392
- o += j;
393
- }
394
-
395
- // o is 6
396
- TEST_ARRAY.push(i + o);
397
- }
398
- var fillerExpr1;
399
- var fillerExpr2;
400
- var fillerExpr3;
401
- var fillerExpr4;
402
- var fillerExpr5;
403
- `,
404
- {
405
- target: "node",
406
- controlFlowFlattening: true,
407
- }
408
- );
409
-
410
- expect(output).not.toContain("for(var i)");
411
- expect(output).not.toContain("for(var j)");
412
-
413
- var TEST_ARRAY;
414
-
415
- eval(output);
416
- expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
417
- });
418
-
419
- test("Variant #13: Flatten nested while loops", async () => {
420
- var output = await JsConfuser(
421
- `
422
- TEST_ARRAY = [];
423
-
424
- var i = -5
425
- while ( i < 0 ) {
426
- var o = 0;
427
- var j = 1;
428
-
429
- while( j < 4 ){
430
- o += j;
431
-
432
- j++;
433
- }
434
-
435
- // o is 6
436
- TEST_ARRAY.push(i + o);
437
- i++;
438
- }
439
- var fillerExpr1;
440
- var fillerExpr2;
441
- var fillerExpr3;
442
- var fillerExpr4;
443
- var fillerExpr5;
444
- `,
445
- {
446
- target: "node",
447
- controlFlowFlattening: true,
448
- }
449
- );
450
-
451
- var TEST_ARRAY;
452
-
453
- expect(output).not.toContain("while(i<0)");
454
- expect(output).not.toContain("while(j<4)");
455
-
456
- eval(output);
457
- expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
458
- });
459
-
460
- test("Variant #14: Flatten nested switch statements", async () => {
461
- var output = await JsConfuser(
462
- `
463
- TEST_ARRAY = [];
464
-
465
- var i = 0;
466
- switch(i){
467
- case 1: TEST_ARRAY.push(-1); break;
468
- case 2: TEST_ARRAY.push(-1); break;
469
- case 0:
470
- TEST_ARRAY.push(1);
471
-
472
- var j = 0;
473
- var i = 0;
474
- switch(j){
475
- case 1: TEST_ARRAY.push(-1); break;
476
- case 2: TEST_ARRAY.push(-1); break;
477
- case 0:
478
- TEST_ARRAY.push(2);
479
- break;
480
- case 4: TEST_ARRAY.push(-1); break;
481
- case 8: TEST_ARRAY.push(-1); break;
482
- }
483
-
484
- TEST_ARRAY.push(3);
485
-
486
- break;
487
- case 4: TEST_ARRAY.push(-1); break;
488
- case 8: TEST_ARRAY.push(-1); break;
489
- }
490
-
491
- TEST_ARRAY.push(4);
492
- TEST_ARRAY.push(5);
493
- `,
494
- {
495
- target: "node",
496
- controlFlowFlattening: true,
497
- }
498
- );
499
-
500
- expect(output).not.toContain("switch(i");
501
- expect(output).not.toContain("switch(j");
502
-
503
- var TEST_ARRAY;
504
-
505
- eval(output);
506
- expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
507
- });
508
-
509
- test("Variant #16: Flatten with nested break and continue statements", async () => {
510
- var output = await JsConfuser(
511
- `
512
- TEST_ARRAY = [];
513
-
514
- for ( var i =1; i < 10; i++ ) {
515
- if(i%2==0){
516
- continue;
517
- }
518
- if(i==7){
519
- break;
520
- }
521
- TEST_ARRAY.push(i);
522
- }
523
-
524
- var j;
525
-
526
- a: for ( var i = 0; i < 5; i++ ) {
527
- if ( i == 3 ) {
528
- for ( j = 0; j < 5; j++ ) {
529
- if ( j == 1 ) {break a;}
530
- if ( j % 2 == 0 ) { continue a;}
531
- }
532
- TEST_ARRAY.push(-1);
533
- }
534
- }
535
-
536
- var fillerExpr1;
537
- var fillerExpr2;
538
- var fillerExpr3;
539
- var fillerExpr4;
540
- var fillerExpr5;
541
- `,
542
- {
543
- target: "node",
544
- controlFlowFlattening: true,
545
- }
546
- );
547
-
548
- var TEST_ARRAY;
549
-
550
- eval(output);
551
- expect(TEST_ARRAY).toStrictEqual([1, 3, 5]);
552
- });
553
-
554
- test("Variant #17: Flatten with infinite for loop and break", async () => {
555
- var output = await JsConfuser(
556
- `
557
- TEST_ARRAY = [];
558
- var i = 1;
559
-
560
- for ( ;; ) {
561
- if (i == 6){break;}
562
-
563
- TEST_ARRAY.push(i), i++;
564
- }
565
-
566
- var fillerExpr1;
567
- var fillerExpr2;
568
- var fillerExpr3;
569
- var fillerExpr4;
570
- var fillerExpr5;
571
- `,
572
- {
573
- target: "node",
574
- controlFlowFlattening: true,
575
- }
576
- );
577
-
578
- expect(output).not.toContain("for(;");
579
-
580
- var TEST_ARRAY;
581
-
582
- eval(output);
583
- expect(TEST_ARRAY).toStrictEqual([1, 2, 3, 4, 5]);
584
- });
585
-
586
- test("Variant #20: Work with redefined functions", async () => {
587
- var output = await JsConfuser(
588
- `
589
- var counter = 0;
590
- function increment(){
591
- counter++;
592
-
593
- if(counter == 3) {
594
- increment = () => { counter = "Correct Value" }
595
- }
596
- }
597
-
598
- increment(); // 1
599
- increment(); // 2
600
- increment(); // 3
601
-
602
- var originalIncrement = increment;
603
- increment = ()=>{};
604
-
605
- increment(); // 3
606
- increment(); // 3
607
- increment(); // 3
608
-
609
- increment = undefined;
610
-
611
- increment = typeof increment === "undefined" ? originalIncrement : 0;
612
-
613
- increment(); // "Correct Value"
614
-
615
- TEST_OUTPUT = counter;
616
- `,
617
- {
618
- target: "node",
619
- controlFlowFlattening: true,
620
- }
621
- );
622
-
623
- // Ensure Control Flow Flattening applied
624
- expect(output).toContain("while");
625
-
626
- var TEST_OUTPUT;
627
-
628
- eval(output);
629
- expect(TEST_OUTPUT).toStrictEqual("Correct Value");
630
- });
631
-
632
- // https://github.com/MichaelXF/js-confuser/issues/70
633
- test("Variant #21: Don't move Import Declarations", async () => {
634
- var output = await JsConfuser(
635
- `
636
- import {createHash} from "crypto";
637
- var inputString = "Hash this string";
638
- var hashed = createHash("sha256").update(inputString).digest("hex");
639
- TEST_OUTPUT = hashed;
640
- `,
641
- {
642
- target: "node",
643
- controlFlowFlattening: true,
644
- }
645
- );
646
-
647
- // Ensure Control Flow FLattening was applied
648
- expect(output).toContain("switch");
649
-
650
- // Ensure the import declaration wasn't moved
651
- expect(output.startsWith("import")).toStrictEqual(true);
652
-
653
- // Convert to runnable code
654
- output = output.replace(
655
- `import{createHash}from'crypto';`,
656
- "const {createHash}=require('crypto');"
657
- );
658
-
659
- var TEST_OUTPUT = "";
660
-
661
- eval(output);
662
-
663
- expect(TEST_OUTPUT).toStrictEqual(
664
- "1cac63f39fd68d8c531f27b807610fb3d50f0fc3f186995767fb6316e7200a3e"
665
- );
666
- });
667
-
668
- // https://github.com/MichaelXF/js-confuser/issues/81
669
- test("Variant #22: Don't break typeof expression", async () => {
670
- var output = await JsConfuser(
671
- `
672
- TEST_OUTPUT = false;
673
- if(typeof nonExistentVariable === "undefined") {
674
- TEST_OUTPUT = true;
675
- }
676
- `,
677
- {
678
- target: "node",
679
- controlFlowFlattening: true,
680
- }
681
- );
682
-
683
- var TEST_OUTPUT;
684
-
685
- eval(output);
686
-
687
- expect(TEST_OUTPUT).toStrictEqual(true);
688
- });
689
-
690
- test("Variant #23: Don't break Super calls", async () => {
691
- var output = await JsConfuser(
692
- `
693
- class MyClass1 {
694
- constructor(val){
695
- this.val = val;
696
- }
697
- }
698
- class MyClass2 extends MyClass1 {
699
- constructor(){
700
- super(10);
701
-
702
- // Ensure ControlFlowFlattening applies here
703
- var filler1;
704
- var filler2;
705
- var filler3;
706
- }
707
- }
708
-
709
- var myObject = new MyClass2();
710
- TEST_OUTPUT = myObject.val; // 10
711
- `,
712
- { target: "node", controlFlowFlattening: true }
713
- );
714
-
715
- var TEST_OUTPUT;
716
- eval(output);
717
-
718
- expect(TEST_OUTPUT).toStrictEqual(10);
719
- });
720
-
721
- test("Variant #24: Nested function-calls with labeled breaks/continues", async () => {
722
- var code = `
723
- function myFunction(){
724
- function x( STOP_VALUE ){
725
- function y(){
726
- function dead(){
727
- var STOP_VALUE = 3;
728
- }
729
- function z(){
730
- a: for(var i = 0; i < 10; i++) {
731
- if (i == STOP_VALUE) {
732
- var counter = 0;
733
- b: for ( var j = 0; j < 10; j++ ) {
734
- if(j == 4) {
735
- counter -= 50;
736
- continue b;
737
- }
738
- counter++;
739
- if(j == 8) {
740
- break a;
741
- }
742
- }
743
- }
744
- }
745
-
746
- var filler1;
747
- var filler2;
748
- var filler3;
749
- return i + j + counter;
750
- }
751
-
752
- var filler1;
753
- var filler2;
754
- var filler3;
755
- return z();
756
- }
757
-
758
- var filler1;
759
- var filler2;
760
- var filler3;
761
- return y();
762
- }
763
-
764
- var filler1;
765
- var filler2;
766
- var filler3;
767
- return x( 1 );
768
- }
769
-
770
- var x = myFunction();
771
-
772
- TEST_OUTPUT = x;`;
773
-
774
- var output = await JsConfuser(code, {
775
- target: "node",
776
- controlFlowFlattening: true,
777
- renameVariables: true,
778
- identifierGenerator: "mangled",
779
- stack: true,
780
- });
781
-
782
- var TEST_OUTPUT;
783
- eval(output);
784
-
785
- expect(TEST_OUTPUT).toStrictEqual(-33);
786
- });
787
-
788
- test("Variant #25: Don't break call expressions to bound functions", async () => {
789
- var code = `
790
- var array = [];
791
- array.push(1);
792
- array.push(2);
793
- array.push(3);
794
- array.push(4);
795
- array.push(5);
796
-
797
- TEST_OUTPUT = array;
798
- `;
799
-
800
- var output = await JsConfuser(code, {
801
- target: "node",
802
- controlFlowFlattening: true,
803
- });
804
-
805
- // Ensure Control Flow Flattening applied
806
- expect(output).toContain("while");
807
-
808
- var TEST_OUTPUT;
809
- eval(output);
810
-
811
- expect(TEST_OUTPUT).toStrictEqual([1, 2, 3, 4, 5]);
812
- });
813
-
814
- test("Variant #26: Add opaque predicates and still work", async () => {
815
- var output = await JsConfuser(
816
- `
817
- TEST_OUTPUT = [];
818
- if(true) TEST_OUTPUT.push(1);
819
- else TEST_OUTPUT.push("Incorrect If Statement")
820
-
821
- switch(true){
822
- case true: TEST_OUTPUT.push(2); break;
823
- default:
824
- TEST_OUTPUT.push("Incorrect Switch")
825
- }
826
-
827
- TEST_OUTPUT.push( true ? 3 : "Incorrect Conditional Statement" );
828
- `,
829
- { target: "node", controlFlowFlattening: true }
830
- );
831
-
832
- expect(output).toContain("while");
833
- var TEST_OUTPUT = [];
834
-
835
- eval(output);
836
-
837
- expect(TEST_OUTPUT).toStrictEqual([1, 2, 3]);
838
- });
839
-
840
- test("Variant #27: Work on async/generator functions", async () => {
841
- var output = await JsConfuser(
842
- `
843
- "use strict";
844
- async function myAsyncFunction(){
845
- await (1);
846
- }
847
-
848
- function* myGeneratorFunction(){
849
- yield "Correct Value";
850
- }
851
-
852
- var x = myAsyncFunction();
853
- var generatorObject = myGeneratorFunction();
854
-
855
- TEST_OUTPUT = generatorObject.next().value;
856
-
857
- var fillerVar1;
858
- var fillerVar2;
859
- var fillerVar3;
860
- `,
861
- { target: "node", controlFlowFlattening: true }
862
- );
863
-
864
- // Ensure Control Flow Flattening applied
865
- expect(output).toContain("while");
866
-
867
- var TEST_OUTPUT;
868
- eval(output);
869
-
870
- expect(TEST_OUTPUT).toStrictEqual("Correct Value");
871
- });
872
-
873
- test("Variant #28: Don't break update expressions", async () => {
874
- var code = `
875
- var counter = 0;
876
-
877
- counter++; // 1
878
- counter++; // 2
879
- counter++; // 3
880
- counter++; // 4
881
- counter++; // 5
882
- counter++; // 6
883
- counter++; // 7
884
- counter++; // 8
885
- counter++; // 9
886
- counter++; // 10
887
-
888
- TEST_OUTPUT = counter;
889
- `;
890
-
891
- var output = await JsConfuser(code, {
892
- target: "node",
893
- controlFlowFlattening: true,
894
- });
895
-
896
- // Ensure Control Flow Flattening applied
897
- expect(output).toContain("while");
898
-
899
- var TEST_OUTPUT;
900
- eval(output);
901
-
902
- expect(TEST_OUTPUT).toStrictEqual(10);
903
- });
904
-
905
- test("Variant #29: Nested labeled break and continue statements with RGF enabled", async () => {
906
- var code = `
907
- function labeledBreaksAndContinues() {
908
- var flag = true;
909
-
910
- label_1: for (var i = 0; i < 20; i++) {
911
- b: switch (i) {
912
- case 15:
913
- c: do {
914
- if (i !== 15) {
915
- break c;
916
- }
917
- flag = true;
918
-
919
- break label_1;
920
-
921
- var fillerVar1;
922
- var fillerVar2;
923
- var fillerVar3;
924
- } while (i == 15);
925
-
926
- break;
927
-
928
- case 10:
929
- continue label_1;
930
-
931
- default:
932
- flag = false;
933
- break b;
934
- }
935
-
936
- var fillerVar1;
937
- var fillerVar2;
938
- var fillerVar3;
939
- }
940
-
941
- var fillerVar1;
942
- var fillerVar2;
943
- var fillerVar3;
944
-
945
- if (flag) {
946
- return i;
947
- }
948
- }
949
-
950
- var fillerVar1;
951
- var fillerVar2;
952
- var fillerVar3;
953
-
954
- TEST_OUTPUT = labeledBreaksAndContinues();
955
- `; // This complex code produces the value of 15
956
-
957
- var output = await JsConfuser(code, {
958
- target: "node",
959
- controlFlowFlattening: true,
960
- rgf: true,
961
- renameVariables: true,
962
- identifierGenerator: "mangled",
963
- });
964
-
965
- // Run the code
966
- var TEST_OUTPUT;
967
- eval(output);
968
-
969
- expect(TEST_OUTPUT).toStrictEqual(15);
970
- });
971
-
972
- test("Variant #30: Obfuscate switch statements", async () => {
973
- var output = await JsConfuser(
974
- `
975
- switch("DON'T CHANGE ME"){} // Empty switch for testing
976
-
977
- switch(true){
978
- case 0:
979
- TEST_OUTPUT = "Incorrect Value (1)";
980
- break
981
-
982
- case true:
983
- TEST_OUTPUT = "First Correct Value";
984
- break;
985
-
986
- case 1:
987
- case 2:
988
- case 3:
989
- case false:
990
- TEST_OUTPUT = "Incorrect Value (2)";
991
- break;
992
- };
993
-
994
- switch(TEST_OUTPUT){
995
- case true:
996
- TEST_OUTPUT = "Incorrect Value (3)";
997
- break;
998
-
999
- case false:
1000
- TEST_OUTPUT = "Incorrect Value (4)";
1001
- break;
1002
-
1003
- default:
1004
- TEST_OUTPUT = "Second Correct Value";
1005
- }
1006
-
1007
- switch(true){
1008
- case false:
1009
- throw new Error();
1010
- break;
1011
-
1012
- default:
1013
- TEST_OUTPUT = "Incorrect Value";
1014
-
1015
- case true:
1016
- TEST_OUTPUT = "Third Correct Value";
1017
- // Fall-through test
1018
- case 10:
1019
- TEST_OUTPUT = "Fourth Correct Value";
1020
-
1021
- }
1022
-
1023
- switch(true){
1024
- default:
1025
- throw new Error("NO");
1026
- break;
1027
- case true:
1028
-
1029
- break;
1030
- }
1031
-
1032
- var hitDefault = false;
1033
-
1034
- switch(true){
1035
- case 1:
1036
- case 2:
1037
-
1038
- default:
1039
- hitDefault = true;
1040
- break;
1041
-
1042
- case 3:
1043
- case 4:
1044
- break;
1045
- }
1046
-
1047
- if(!hitDefault) {
1048
- throw new Error("Did not hit default case");
1049
- }
1050
-
1051
- var filler1;
1052
- var filler2;
1053
- var filler3;
1054
- `,
1055
- {
1056
- target: "node",
1057
- controlFlowFlattening: true,
1058
- }
1059
- );
1060
-
1061
- // Ensure Control Flow Flattening applied
1062
- expect(output).toContain("while");
1063
-
1064
- // Ensure switch-statements got changed
1065
- expect(output).not.toContain("switch(true)");
1066
- expect(output).not.toContain("switch(TEST_OUTPUT)");
1067
-
1068
- var TEST_OUTPUT;
1069
- eval(output);
1070
-
1071
- expect(TEST_OUTPUT).toStrictEqual("Fourth Correct Value");
1072
- });
1073
-
1074
- test("Variant #31: Don't break nested function calls", async () => {
1075
- var output = await JsConfuser(
1076
- `
1077
- var i;
1078
- var counter = 0;
1079
- for(i = 0; i < 10;) {
1080
- function logger(x){
1081
- counter++;
1082
- }
1083
-
1084
- logger("Hello World");
1085
- i++
1086
- }
1087
-
1088
- TEST_OUTPUT = counter;
1089
- `,
1090
- { target: "node", controlFlowFlattening: true }
1091
- );
1092
-
1093
- expect(output).toContain("while");
1094
-
1095
- var TEST_OUTPUT;
1096
- eval(output);
1097
-
1098
- expect(TEST_OUTPUT).toStrictEqual(10);
1099
- });
1100
-
1101
- test("Variant #32: Don't break same name function calls", async () => {
1102
- var output = await JsConfuser(
1103
- `
1104
- var counter = 0;
1105
-
1106
- function a(){
1107
- // Outer a called
1108
- counter *= 2;
1109
- }
1110
-
1111
- var i;
1112
-
1113
- for(i = 0; i < 10;) {
1114
- function a(){
1115
- // Inner a called
1116
- counter += 1;
1117
- }
1118
-
1119
- a(); // Inner a
1120
- i++;
1121
- }
1122
-
1123
- a(); // Inner a, Outer a got renamed
1124
-
1125
- TEST_OUTPUT = counter;
1126
- `,
1127
- { target: "node", controlFlowFlattening: true }
1128
- );
1129
-
1130
- expect(output).toContain("while");
1131
-
1132
- var TEST_OUTPUT;
1133
- eval(output);
1134
-
1135
- expect(TEST_OUTPUT).toStrictEqual(11);
1136
- });
1137
-
1138
- test("Variant #33: Don't break same name function declarations that are not ran", async () => {
1139
- var output = await JsConfuser(
1140
- `
1141
- var counter = 0;
1142
-
1143
- function a(){
1144
- // Outer a called
1145
- counter += 1;
1146
- }
1147
-
1148
- for(var i = 0; i < 10;) {
1149
- if(false){
1150
- function a(){
1151
- // Inner a called
1152
- counter = 0;
1153
- }
1154
- }
1155
-
1156
-
1157
- a(); // Outer a
1158
- i++;
1159
- }
1160
-
1161
- a(); // Outer a
1162
-
1163
- TEST_OUTPUT = counter;
1164
- `,
1165
- { target: "node", controlFlowFlattening: true }
1166
- );
1167
-
1168
- expect(output).toContain("while");
1169
-
1170
- var TEST_OUTPUT;
1171
- eval(output);
1172
-
1173
- expect(TEST_OUTPUT).toStrictEqual(11);
1174
- });
1175
-
1176
- test("Variant #34: Flatten If, For, While, Do-while, and Switch statements multiple times", async () => {
1177
- var code = `
1178
- var counter = -1;
1179
-
1180
- function incrementCounter(){
1181
- counter++;
1182
- }
1183
-
1184
- if(false) {
1185
-
1186
- } else {
1187
- counter = 0;
1188
- }
1189
-
1190
- if(true){
1191
- for(var i = 0; i < 10; i++) {
1192
- switch(i){
1193
- default:
1194
- i++;
1195
- break;
1196
-
1197
- case 6:
1198
- if(false){
1199
- function incrementCounter(){
1200
- throw new Error("Fake counter function");
1201
- }
1202
- }
1203
-
1204
- while(i != 10) {
1205
- incrementCounter();
1206
- if(counter > 10) break;
1207
- }
1208
-
1209
- do {
1210
- counter--;
1211
- } while (counter > 5)
1212
- // Fall-through
1213
- case 8:
1214
- counter *= 2;
1215
- break;
1216
- }
1217
- }
1218
- } else {
1219
- counter = "Incorrect Value";
1220
- }
1221
- if(false){
1222
- counter = "Incorrect Value";
1223
- }
1224
-
1225
- TEST_OUTPUT = counter;
1226
- `;
1227
-
1228
- var firstObfuscation = await JsConfuser(code, {
1229
- target: "node",
1230
- controlFlowFlattening: true,
1231
- });
1232
- var secondObfuscation = await JsConfuser(firstObfuscation, {
1233
- target: "node",
1234
- controlFlowFlattening: true,
1235
- });
1236
-
1237
- var TEST_OUTPUT;
1238
- eval(secondObfuscation);
1239
-
1240
- expect(TEST_OUTPUT).toStrictEqual(10);
1241
- });
1242
-
1243
- test("Variant #35: Redefined function declaration + variable declaration", async () => {
1244
- var code = `
1245
- function push(str){
1246
- TEST_OUTPUT.push(str);
1247
- }
1248
-
1249
- x();
1250
-
1251
- var x = ()=>push("Top x");
1252
-
1253
- x()
1254
-
1255
- function x(){ push("Bottom x") }
1256
-
1257
- if(true){
1258
-
1259
- x();
1260
-
1261
- function x(){ push("Nested x") }
1262
- }
1263
- `;
1264
-
1265
- var output = await JsConfuser(code, {
1266
- target: "node",
1267
- controlFlowFlattening: true,
1268
- });
1269
-
1270
- var TEST_OUTPUT = [];
1271
- eval(output);
1272
-
1273
- expect(TEST_OUTPUT).toStrictEqual(["Bottom x", "Top x", "Nested x"]);
1274
- });