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
@@ -2,7 +2,6 @@ import Transform from "./transform";
2
2
  import { ObfuscateOrder } from "../order";
3
3
  import {
4
4
  Node,
5
- Location,
6
5
  VariableDeclaration,
7
6
  BinaryExpression,
8
7
  ExpressionStatement,
@@ -21,10 +20,9 @@ import {
21
20
  getBlockBody,
22
21
  clone,
23
22
  isForInitialize,
24
- isLexContext,
25
- getFunction,
26
- prepend,
27
23
  append,
24
+ isVarContext,
25
+ computeFunctionLength,
28
26
  } from "../util/insert";
29
27
  import { isValidIdentifier, isEquivalent } from "../util/compare";
30
28
  import { walk, isBlock } from "../traverse";
@@ -97,7 +95,7 @@ export default class Minify extends Transform {
97
95
  var sequences: { index: number; exprs: Node[] }[] = [];
98
96
 
99
97
  body.forEach((stmt, i) => {
100
- if (stmt.type == "ExpressionStatement") {
98
+ if (stmt.type == "ExpressionStatement" && !stmt.directive) {
101
99
  exprs.push(stmt.expression);
102
100
  if (startIndex == -1) {
103
101
  startIndex = i;
@@ -129,51 +127,52 @@ export default class Minify extends Transform {
129
127
  });
130
128
  }
131
129
 
132
- if (object.type != "SwitchCase") {
133
- // Unnecessary return
134
- if (body.length && body[body.length - 1]) {
135
- var last = body[body.length - 1];
136
- if (last.type == "ReturnStatement") {
137
- var isUndefined = last.argument == null;
138
-
139
- if (isUndefined) {
140
- if (getFunction(object, parents).body == object) {
141
- body.pop();
142
- }
143
- }
130
+ // Unnecessary return
131
+ if (
132
+ parents[0] &&
133
+ isVarContext(parents[0]) &&
134
+ body.length &&
135
+ body[body.length - 1]
136
+ ) {
137
+ var last = body[body.length - 1];
138
+ if (last.type == "ReturnStatement") {
139
+ var isUndefined = last.argument == null;
140
+
141
+ if (isUndefined) {
142
+ body.pop();
144
143
  }
145
144
  }
145
+ }
146
146
 
147
- // Variable declaration grouping
148
- // var a = 1;
149
- // var b = 1;
150
- // var c = 1;
151
- //
152
- // var a=1,b=1,c=1;
153
- var lastDec = null;
154
-
155
- var remove = [];
156
- body.forEach((x, i) => {
157
- if (x.type === "VariableDeclaration") {
158
- if (
159
- !lastDec ||
160
- lastDec.kind !== x.kind ||
161
- !lastDec.declarations.length
162
- ) {
163
- lastDec = x;
164
- } else {
165
- lastDec.declarations.push(...clone(x.declarations));
166
- remove.unshift(i);
167
- }
147
+ // Variable declaration grouping
148
+ // var a = 1;
149
+ // var b = 1;
150
+ // var c = 1;
151
+ //
152
+ // var a=1,b=1,c=1;
153
+ var lastDec = null;
154
+
155
+ var remove = [];
156
+ body.forEach((x, i) => {
157
+ if (x.type === "VariableDeclaration") {
158
+ if (
159
+ !lastDec ||
160
+ lastDec.kind !== x.kind ||
161
+ !lastDec.declarations.length
162
+ ) {
163
+ lastDec = x;
168
164
  } else {
169
- lastDec = null;
165
+ lastDec.declarations.push(...clone(x.declarations));
166
+ remove.unshift(i);
170
167
  }
171
- });
168
+ } else {
169
+ lastDec = null;
170
+ }
171
+ });
172
172
 
173
- remove.forEach((x) => {
174
- body.splice(x, 1);
175
- });
176
- }
173
+ remove.forEach((x) => {
174
+ body.splice(x, 1);
175
+ });
177
176
  };
178
177
  }
179
178
 
@@ -203,28 +202,38 @@ export default class Minify extends Transform {
203
202
  }
204
203
  }
205
204
 
206
- var blockIndex = parents.findIndex((x) => isLexContext(x));
207
- if (blockIndex !== -1) {
208
- var block = parents[blockIndex];
209
- var body = block.body;
205
+ if (object.type === "FunctionDeclaration") {
206
+ var body = parents[0];
210
207
  if (!Array.isArray(body)) {
211
208
  return;
212
209
  }
213
210
 
214
- var stmt = parents[blockIndex - 2] || object;
215
-
216
- var index = body.indexOf(stmt);
211
+ var index = body.indexOf(object);
217
212
  if (index == -1) {
218
213
  return;
219
214
  }
220
215
 
221
216
  var before = body.slice(0, index);
222
- ok(!before.includes(stmt));
217
+ ok(!before.includes(object));
223
218
 
224
- var set = new Set(before.map((x) => x.type));
225
- set.delete("FunctionDeclaration");
219
+ var beforeTypes = new Set(before.map((x) => x.type));
220
+ beforeTypes.delete("FunctionDeclaration");
226
221
 
227
- if (set.size) {
222
+ if (beforeTypes.size > 0) {
223
+ return;
224
+ }
225
+
226
+ // Test Variant #25: Don't break redefined function declaration
227
+ if (
228
+ object.id &&
229
+ body.find(
230
+ (x) =>
231
+ x.type === "FunctionDeclaration" &&
232
+ x !== object &&
233
+ x.id &&
234
+ x.id.name === object.id.name
235
+ )
236
+ ) {
228
237
  return;
229
238
  }
230
239
  }
@@ -250,8 +259,15 @@ export default class Minify extends Transform {
250
259
  append(
251
260
  parents[parents.length - 1] || object,
252
261
  Template(`
253
- function ${this.arrowFunctionName}(arrowFn){
254
- return function(){ return arrowFn(...arguments) }
262
+ function ${this.arrowFunctionName}(arrowFn, functionLength){
263
+ var functionObject = function(){ return arrowFn(...arguments) };
264
+
265
+ Object["defineProperty"](functionObject, "length", {
266
+ "value": functionLength,
267
+ "configurable": true
268
+ });
269
+
270
+ return functionObject;
255
271
  }
256
272
  `).single()
257
273
  );
@@ -260,6 +276,7 @@ export default class Minify extends Transform {
260
276
  const wrap = (object: Node) => {
261
277
  return CallExpression(Identifier(this.arrowFunctionName), [
262
278
  clone(object),
279
+ Literal(computeFunctionLength(object.params)),
263
280
  ]);
264
281
  };
265
282
 
@@ -298,7 +315,7 @@ export default class Minify extends Transform {
298
315
 
299
316
  if (body.length == 1 && stmt1.type == "ReturnStatement") {
300
317
  // x=>{a: 1} // Invalid syntax
301
- if (stmt1.argument.type != "ObjectExpression") {
318
+ if (stmt1.argument && stmt1.argument.type != "ObjectExpression") {
302
319
  object.body = stmt1.argument;
303
320
  object.expression = true;
304
321
  }
@@ -544,16 +561,16 @@ export default class Minify extends Transform {
544
561
  object.property.type = "Identifier";
545
562
  object.property.name = clone(object.property.value);
546
563
 
547
- obj.name &&
548
- this.log(
549
- obj.name +
550
- "['" +
551
- object.property.name +
552
- "'] -> " +
553
- obj.name +
554
- "." +
555
- object.property.name
556
- );
564
+ // obj.name &&
565
+ // this.log(
566
+ // obj.name +
567
+ // "['" +
568
+ // object.property.name +
569
+ // "'] -> " +
570
+ // obj.name +
571
+ // "." +
572
+ // object.property.name
573
+ // );
557
574
  }
558
575
  }
559
576
 
@@ -572,7 +589,7 @@ export default class Minify extends Transform {
572
589
  }
573
590
 
574
591
  // { "x": 1 } -> {x: 1}
575
- if (object.type == "Property") {
592
+ if (object.type === "Property" || object.type === "MethodDefinition") {
576
593
  if (
577
594
  object.key.type == "SequenceExpression" &&
578
595
  object.key.expressions.length == 1
@@ -581,15 +598,14 @@ export default class Minify extends Transform {
581
598
  object.computed = true;
582
599
  }
583
600
 
584
- if (object.key.type == "Literal" && isValidIdentifier(object.key.value)) {
601
+ if (
602
+ object.key.type == "Literal" &&
603
+ typeof object.key.value === "string" &&
604
+ isValidIdentifier(object.key.value)
605
+ ) {
585
606
  object.key.type = "Identifier";
586
607
  object.key.name = object.key.value;
587
608
  object.computed = false;
588
- } else if (
589
- object.key.type == "Identifier" &&
590
- !isValidIdentifier(object.key.name)
591
- ) {
592
- object.key = Literal(object.key.name);
593
609
  }
594
610
  }
595
611
 
@@ -64,14 +64,14 @@ export default class OpaquePredicates extends Transform {
64
64
  predicate: Node;
65
65
  predicates: { [name: string]: Node };
66
66
 
67
- gen: any;
67
+ gen: ReturnType<Transform["getGenerator"]>;
68
68
  made: number;
69
69
 
70
70
  constructor(o) {
71
71
  super(o, ObfuscateOrder.OpaquePredicates);
72
72
 
73
73
  this.predicates = Object.create(null);
74
- this.gen = this.getGenerator(getRandomInteger(0, 20));
74
+ this.gen = this.getGenerator();
75
75
  this.made = 0;
76
76
  }
77
77
 
@@ -0,0 +1,238 @@
1
+ import Transform from "./transform";
2
+
3
+ import {
4
+ BlockStatement,
5
+ Identifier,
6
+ LabeledStatement,
7
+ Literal,
8
+ Node,
9
+ ReturnStatement,
10
+ } from "../util/gen";
11
+ import { ObfuscateOrder } from "../order";
12
+ import { clone, getFunction } from "../util/insert";
13
+ import { getIdentifierInfo } from "../util/identifiers";
14
+ import { isLoop } from "../util/compare";
15
+ import { ExitCallback, walk } from "../traverse";
16
+
17
+ /**
18
+ * Preparation arranges the user's code into an AST the obfuscator can easily transform.
19
+ *
20
+ * ExplicitIdentifiers
21
+ * - `object.IDENTIFIER` -> `object['IDENTIFIER']` // Now String Concealing can apply on it
22
+ * - `{ IDENTIFIER: ... }` -> `{ "IDENTIFIER": ... }`
23
+ *
24
+ * ExplicitDeclarations
25
+ * - `var a,b,c` -> `var a; var b; var c;` // Now Stack can apply on it
26
+ *
27
+ * Block
28
+ * - `x => x * 2` -> `x => { return x * 2 }` // Change into Block Statements
29
+ * - `if(true) return` -> `if (true) { return }`
30
+ * - `while(a) a--;` -> `while(a) { a-- }`
31
+ *
32
+ * Label
33
+ * - `for(...) { break; }` -> `_1: for(...) { break _1; }`
34
+ * - `switch(v) { case 1...break }` -> `_2: switch(v) { case 1...break _2; }`
35
+ * - // Control Flow Flattening can safely apply now
36
+ */
37
+ export default class Preparation extends Transform {
38
+ constructor(o) {
39
+ super(o, ObfuscateOrder.Preparation);
40
+ }
41
+
42
+ match(object: Node, parents: Node[]) {
43
+ return !!object.type;
44
+ }
45
+
46
+ transform(object: Node, parents: Node[]): void | ExitCallback {
47
+ // ExplicitIdentifiers
48
+ if (object.type === "Identifier") {
49
+ return this.transformExplicitIdentifiers(object, parents);
50
+ }
51
+
52
+ // ExplicitDeclarations
53
+ if (object.type === "VariableDeclaration") {
54
+ return this.transformExplicitDeclarations(object, parents);
55
+ }
56
+
57
+ // Block
58
+ switch (object.type) {
59
+ /**
60
+ * People use shortcuts and its harder to parse.
61
+ *
62
+ * - `if (a) b()` -> `if (a) { b() }`
63
+ * - Ensures all bodies are `BlockStatement`, not individual expression statements
64
+ */
65
+ case "IfStatement":
66
+ if (object.consequent.type != "BlockStatement") {
67
+ object.consequent = BlockStatement([clone(object.consequent)]);
68
+ }
69
+ if (object.alternate && object.alternate.type != "BlockStatement") {
70
+ object.alternate = BlockStatement([clone(object.alternate)]);
71
+ }
72
+ break;
73
+
74
+ case "WhileStatement":
75
+ case "WithStatement":
76
+ case "ForStatement":
77
+ case "ForOfStatement":
78
+ case "ForInStatement":
79
+ if (object.body.type != "BlockStatement") {
80
+ object.body = BlockStatement([clone(object.body)]);
81
+ }
82
+ break;
83
+
84
+ case "ArrowFunctionExpression":
85
+ if (object.body.type !== "BlockStatement" && object.expression) {
86
+ object.body = BlockStatement([ReturnStatement(clone(object.body))]);
87
+ object.expression = false;
88
+ }
89
+ break;
90
+ }
91
+
92
+ // Label
93
+ if (
94
+ isLoop(object) ||
95
+ (object.type == "BlockStatement" &&
96
+ parents[0] &&
97
+ parents[0].type == "LabeledStatement" &&
98
+ parents[0].body === object)
99
+ ) {
100
+ return this.transformLabel(object, parents);
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Ensures every break; statement has a label to point to.
106
+ *
107
+ * This is because Control Flow Flattening adds For Loops which label-less break statements point to the nearest,
108
+ * when they actually need to point to the original statement.
109
+ */
110
+ transformLabel(object: Node, parents: Node[]) {
111
+ return () => {
112
+ var currentLabel =
113
+ parents[0].type == "LabeledStatement" && parents[0].label.name;
114
+
115
+ var label = currentLabel || this.getPlaceholder();
116
+
117
+ walk(object, parents, (o, p) => {
118
+ if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
119
+ function isContinuableStatement(x) {
120
+ return isLoop(x) && x.type !== "SwitchStatement";
121
+ }
122
+ function isBreakableStatement(x) {
123
+ return isLoop(x) || (o.label && x.type == "BlockStatement");
124
+ }
125
+
126
+ var fn =
127
+ o.type == "ContinueStatement"
128
+ ? isContinuableStatement
129
+ : isBreakableStatement;
130
+
131
+ var loop = p.find(fn);
132
+ if (object == loop) {
133
+ if (!o.label) {
134
+ o.label = Identifier(label);
135
+ }
136
+ }
137
+ }
138
+ });
139
+
140
+ // Append label statement as this loop has none
141
+ if (!currentLabel) {
142
+ this.replace(object, LabeledStatement(label, { ...object }));
143
+ }
144
+ };
145
+ }
146
+
147
+ /**
148
+ * Transforms Identifiers (a.IDENTIFIER, {IDENTIFIER:...}) into string properties
149
+ */
150
+ transformExplicitIdentifiers(object: Node, parents: Node[]) {
151
+ // Mark functions containing 'eval'
152
+ // Some transformations avoid functions that have 'eval' to not break them
153
+ if (object.name === "eval") {
154
+ var fn = getFunction(object, parents);
155
+ if (fn) {
156
+ fn.$requiresEval = true;
157
+ }
158
+ }
159
+
160
+ var info = getIdentifierInfo(object, parents);
161
+ if (info.isPropertyKey || info.isAccessor) {
162
+ var propIndex = parents.findIndex(
163
+ (x) => x.type == "MethodDefinition" || x.type == "Property"
164
+ );
165
+
166
+ // Don't change constructor!
167
+ if (propIndex !== -1) {
168
+ if (
169
+ parents[propIndex].type == "MethodDefinition" &&
170
+ parents[propIndex].kind == "constructor"
171
+ ) {
172
+ return;
173
+ }
174
+ }
175
+
176
+ this.replace(object, Literal(object.name));
177
+ parents[0].computed = true;
178
+ parents[0].shorthand = false;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Transforms VariableDeclaration into single declarations.
184
+ */
185
+ transformExplicitDeclarations(object: Node, parents: Node[]) {
186
+ // for ( var x in ... ) {...}
187
+ var forIndex = parents.findIndex(
188
+ (x) => x.type == "ForInStatement" || x.type == "ForOfStatement"
189
+ );
190
+ if (
191
+ forIndex != -1 &&
192
+ parents[forIndex].left == (parents[forIndex - 1] || object)
193
+ ) {
194
+ object.declarations.forEach((x) => {
195
+ x.init = null;
196
+ });
197
+ return;
198
+ }
199
+
200
+ var body = parents[0];
201
+ if (isLoop(body) || body.type == "LabeledStatement") {
202
+ return;
203
+ }
204
+
205
+ if (body.type == "ExportNamedDeclaration") {
206
+ return;
207
+ }
208
+
209
+ if (!Array.isArray(body)) {
210
+ this.error(new Error("body is " + body.type));
211
+ }
212
+
213
+ if (object.declarations.length > 1) {
214
+ // Make singular
215
+
216
+ var index = body.indexOf(object);
217
+ if (index == -1) {
218
+ this.error(new Error("index is -1"));
219
+ }
220
+
221
+ var after = object.declarations.slice(1);
222
+
223
+ body.splice(
224
+ index + 1,
225
+ 0,
226
+ ...after.map((x) => {
227
+ return {
228
+ type: "VariableDeclaration",
229
+ declarations: [clone(x)],
230
+ kind: object.kind,
231
+ };
232
+ })
233
+ );
234
+
235
+ object.declarations.length = 1;
236
+ }
237
+ }
238
+ }
@@ -9,12 +9,12 @@ import Transform from "./transform";
9
9
  * Renames the labels to shorter names.
10
10
  */
11
11
  export default class RenameLabels extends Transform {
12
- gen: any;
12
+ gen: ReturnType<Transform["getGenerator"]>;
13
13
 
14
14
  constructor(o) {
15
15
  super(o, ObfuscateOrder.RenameLabels);
16
16
 
17
- this.gen = this.getGenerator();
17
+ this.gen = this.getGenerator("randomized");
18
18
  }
19
19
 
20
20
  match(object, parents) {