js-confuser 2.0.0-alpha.5 → 2.0.1

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 (113) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +43 -43
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  3. package/.github/workflows/node.js.yml +28 -28
  4. package/.prettierrc +4 -4
  5. package/CHANGELOG.md +1015 -989
  6. package/CODE_OF_CONDUCT.md +131 -131
  7. package/CONTRIBUTING.md +52 -52
  8. package/LICENSE +21 -21
  9. package/Migration.md +72 -71
  10. package/README.md +86 -78
  11. package/dist/constants.js +43 -43
  12. package/dist/index.js +14 -23
  13. package/dist/obfuscator.js +31 -25
  14. package/dist/order.js +4 -4
  15. package/dist/presets.js +31 -31
  16. package/dist/templates/integrityTemplate.js +4 -4
  17. package/dist/templates/template.js +1 -2
  18. package/dist/transforms/astScrambler.js +1 -2
  19. package/dist/transforms/calculator.js +1 -2
  20. package/dist/transforms/controlFlowFlattening.js +93 -63
  21. package/dist/transforms/deadCode.js +1 -2
  22. package/dist/transforms/dispatcher.js +4 -5
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +1 -2
  24. package/dist/transforms/extraction/objectExtraction.js +1 -2
  25. package/dist/transforms/finalizer.js +1 -2
  26. package/dist/transforms/flatten.js +1 -2
  27. package/dist/transforms/identifier/globalConcealing.js +15 -2
  28. package/dist/transforms/identifier/movedDeclarations.js +8 -7
  29. package/dist/transforms/identifier/renameVariables.js +7 -7
  30. package/dist/transforms/lock/integrity.js +11 -10
  31. package/dist/transforms/lock/lock.js +2 -3
  32. package/dist/transforms/minify.js +11 -29
  33. package/dist/transforms/opaquePredicates.js +1 -2
  34. package/dist/transforms/pack.js +5 -2
  35. package/dist/transforms/plugin.js +18 -19
  36. package/dist/transforms/preparation.js +16 -16
  37. package/dist/transforms/renameLabels.js +1 -2
  38. package/dist/transforms/rgf.js +8 -9
  39. package/dist/transforms/shuffle.js +1 -2
  40. package/dist/transforms/string/encoding.js +1 -2
  41. package/dist/transforms/string/stringCompression.js +3 -4
  42. package/dist/transforms/string/stringConcealing.js +8 -3
  43. package/dist/transforms/string/stringEncoding.js +1 -2
  44. package/dist/transforms/variableMasking.js +1 -2
  45. package/dist/utils/NameGen.js +2 -2
  46. package/dist/utils/PredicateGen.js +1 -2
  47. package/dist/utils/ast-utils.js +87 -88
  48. package/dist/utils/function-utils.js +8 -8
  49. package/dist/utils/node.js +5 -6
  50. package/dist/utils/object-utils.js +4 -4
  51. package/dist/utils/random-utils.js +20 -20
  52. package/dist/utils/static-utils.js +1 -2
  53. package/dist/validateOptions.js +4 -7
  54. package/index.d.ts +17 -17
  55. package/package.json +61 -59
  56. package/src/constants.ts +168 -168
  57. package/src/index.ts +118 -118
  58. package/src/obfuscationResult.ts +49 -49
  59. package/src/obfuscator.ts +501 -497
  60. package/src/options.ts +407 -407
  61. package/src/order.ts +54 -54
  62. package/src/presets.ts +125 -125
  63. package/src/templates/bufferToStringTemplate.ts +57 -57
  64. package/src/templates/deadCodeTemplates.ts +1185 -1185
  65. package/src/templates/getGlobalTemplate.ts +76 -76
  66. package/src/templates/integrityTemplate.ts +64 -64
  67. package/src/templates/setFunctionLengthTemplate.ts +11 -11
  68. package/src/templates/stringCompressionTemplate.ts +20 -20
  69. package/src/templates/tamperProtectionTemplates.ts +120 -120
  70. package/src/templates/template.ts +224 -224
  71. package/src/transforms/astScrambler.ts +99 -99
  72. package/src/transforms/calculator.ts +99 -99
  73. package/src/transforms/controlFlowFlattening.ts +1716 -1664
  74. package/src/transforms/deadCode.ts +82 -82
  75. package/src/transforms/dispatcher.ts +450 -450
  76. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +156 -158
  77. package/src/transforms/extraction/objectExtraction.ts +186 -186
  78. package/src/transforms/finalizer.ts +74 -74
  79. package/src/transforms/flatten.ts +421 -420
  80. package/src/transforms/identifier/globalConcealing.ts +315 -295
  81. package/src/transforms/identifier/movedDeclarations.ts +252 -251
  82. package/src/transforms/identifier/renameVariables.ts +328 -321
  83. package/src/transforms/lock/integrity.ts +117 -114
  84. package/src/transforms/lock/lock.ts +418 -425
  85. package/src/transforms/minify.ts +615 -629
  86. package/src/transforms/opaquePredicates.ts +100 -100
  87. package/src/transforms/pack.ts +239 -231
  88. package/src/transforms/plugin.ts +173 -173
  89. package/src/transforms/preparation.ts +349 -347
  90. package/src/transforms/renameLabels.ts +175 -175
  91. package/src/transforms/rgf.ts +322 -322
  92. package/src/transforms/shuffle.ts +82 -82
  93. package/src/transforms/string/encoding.ts +144 -144
  94. package/src/transforms/string/stringCompression.ts +128 -128
  95. package/src/transforms/string/stringConcealing.ts +312 -298
  96. package/src/transforms/string/stringEncoding.ts +80 -80
  97. package/src/transforms/string/stringSplitting.ts +77 -77
  98. package/src/transforms/variableMasking.ts +257 -257
  99. package/src/utils/IntGen.ts +33 -33
  100. package/src/utils/NameGen.ts +116 -116
  101. package/src/utils/PredicateGen.ts +61 -61
  102. package/src/utils/ast-utils.ts +663 -663
  103. package/src/utils/function-utils.ts +50 -50
  104. package/src/utils/gen-utils.ts +48 -48
  105. package/src/utils/node.ts +78 -78
  106. package/src/utils/object-utils.ts +21 -21
  107. package/src/utils/random-utils.ts +93 -93
  108. package/src/utils/static-utils.ts +66 -66
  109. package/src/validateOptions.ts +256 -259
  110. package/tsconfig.json +13 -14
  111. package/dist/probability.js +0 -1
  112. package/dist/transforms/functionOutlining.js +0 -230
  113. package/dist/utils/ControlObject.js +0 -125
@@ -1,321 +1,328 @@
1
- import { NodePath } from "@babel/traverse";
2
- import { Visitor } from "@babel/traverse";
3
- import { PluginArg, PluginObject } from "../plugin";
4
- import * as t from "@babel/types";
5
- import { Order } from "../../order";
6
- import {
7
- noRenameVariablePrefix,
8
- placeholderVariablePrefix,
9
- } from "../../constants";
10
- import {
11
- getParentFunctionOrProgram,
12
- isDefiningIdentifier,
13
- isExportedIdentifier,
14
- isVariableIdentifier,
15
- } from "../../utils/ast-utils";
16
- import { isVariableFunctionIdentifier } from "../../utils/function-utils";
17
-
18
- const RENAMED = Symbol("Renamed");
19
-
20
- const reusePreviousNames = true;
21
-
22
- export default ({ Plugin }: PluginArg): PluginObject => {
23
- const me = Plugin(Order.RenameVariables, {
24
- changeData: {
25
- variables: 0,
26
- },
27
- });
28
-
29
- const definedMap = new Map<t.Node, Set<string>>();
30
- const referencedMap = new Map<t.Node, Set<string>>();
31
- const paramMap = new Map<t.Node, Set<string>>(); // Used for default function parameter special case
32
- const bindingMap = new Map<t.Node, Map<string, NodePath<t.Identifier>>>();
33
-
34
- const renamedVariables = new Map<t.Node, Map<string, string>>();
35
- me.obfuscator.globalState.renamedVariables = renamedVariables;
36
-
37
- const generated = Array.from(me.obfuscator.nameGen.generatedNames);
38
-
39
- const VariableAnalysisVisitor: Visitor = {
40
- Program: {
41
- enter(path) {
42
- // Analyze all scopes
43
- path.traverse({
44
- Identifier(path) {
45
- if (!isVariableIdentifier(path)) return;
46
-
47
- let contextPaths: NodePath<t.Node>[] = [
48
- getParentFunctionOrProgram(path),
49
- ];
50
-
51
- let isDefined = false;
52
- let isParameter = false;
53
-
54
- if (path.isBindingIdentifier() && isDefiningIdentifier(path)) {
55
- isDefined = true;
56
- const binding = path.scope.getBinding(path.node.name);
57
- if (binding?.kind === "param") isParameter = true;
58
-
59
- // Function ID is defined in the parent's function declaration
60
- if (
61
- path.key === "id" &&
62
- path.parentPath.isFunctionDeclaration()
63
- ) {
64
- contextPaths = [getParentFunctionOrProgram(path.parentPath)];
65
- }
66
- }
67
-
68
- contextPaths.forEach((contextPath) => {
69
- // console.log(contextPath.node.type, path.node.name, isDefined);
70
-
71
- if (isDefined) {
72
- // Add to defined map
73
- if (!definedMap.has(contextPath.node)) {
74
- definedMap.set(contextPath.node, new Set());
75
- }
76
- definedMap.get(contextPath.node).add(path.node.name);
77
-
78
- if (!bindingMap.has(contextPath.node)) {
79
- bindingMap.set(contextPath.node, new Map());
80
- }
81
- bindingMap.get(contextPath.node).set(path.node.name, path);
82
- } else {
83
- // Add to reference map
84
- if (!referencedMap.has(contextPath.node)) {
85
- referencedMap.set(contextPath.node, new Set());
86
- }
87
- referencedMap.get(contextPath.node).add(path.node.name);
88
- }
89
- });
90
- },
91
- });
92
-
93
- //
94
- },
95
- },
96
- };
97
-
98
- const VariableRenamingVisitor: Visitor = {
99
- Identifier(identifierPath) {
100
- if (!isVariableIdentifier(identifierPath)) return;
101
- const node = identifierPath.node;
102
- const identifierName = node.name;
103
-
104
- if (node[RENAMED]) {
105
- return;
106
- }
107
-
108
- var contextPaths: NodePath[] = identifierPath.getAncestry();
109
-
110
- // A Function ID is not in the same context as it's body
111
- if (
112
- identifierPath.key === "id" &&
113
- identifierPath.parentPath.isFunctionDeclaration()
114
- ) {
115
- contextPaths = contextPaths.filter(
116
- (x) => x !== identifierPath.parentPath
117
- );
118
- }
119
-
120
- var newName = null;
121
-
122
- const skippedPaths = new Set();
123
-
124
- for (let contextPath of contextPaths) {
125
- if (skippedPaths.has(contextPath)) continue;
126
-
127
- if (contextPath.isFunction()) {
128
- var assignmentPattern = contextPath.find(
129
- (p) => p.listKey === "params" && p.parentPath.isFunction()
130
- );
131
-
132
- if (assignmentPattern?.isAssignmentPattern()) {
133
- var functionPath = assignmentPattern.getFunctionParent();
134
-
135
- if (functionPath) {
136
- // The parameters can be still accessed...
137
- const params = paramMap.get(functionPath.node);
138
- if (params?.has(identifierName)) {
139
- } else {
140
- skippedPaths.add(functionPath);
141
- }
142
- }
143
- }
144
- }
145
-
146
- const { node } = contextPath;
147
-
148
- const defined = definedMap.get(node);
149
- if (defined?.has(identifierName)) {
150
- const renamed = renamedVariables.get(node);
151
- if (renamed?.has(identifierName)) {
152
- newName = renamed.get(identifierName);
153
- break;
154
- }
155
- }
156
- }
157
-
158
- if (newName && typeof newName === "string") {
159
- // __JS_CONFUSER_VAR__ function
160
- if (isVariableFunctionIdentifier(identifierPath)) {
161
- identifierPath.parentPath.replaceWith(t.stringLiteral(newName));
162
- return;
163
- }
164
-
165
- // 5. Update Identifier node's 'name' property
166
- node.name = newName;
167
- node[RENAMED] = true;
168
-
169
- // 6. Additional parameter mapping
170
- const binding = identifierPath.scope.getBinding(identifierName);
171
- if (binding?.kind === "param") {
172
- var mapNode = binding.scope.path.node;
173
- if (!paramMap.has(mapNode)) {
174
- paramMap.set(mapNode, new Set([identifierName]));
175
- } else {
176
- paramMap.get(mapNode).add(identifierName);
177
- }
178
- }
179
- }
180
- },
181
-
182
- Scopable(scopePath: NodePath<t.Scopable>) {
183
- // 2. Notice this is on 'onEnter' (top-down)
184
- const isGlobal = scopePath.isProgram();
185
- const { node } = scopePath.scope.path;
186
- if (renamedVariables.has(node)) return;
187
-
188
- const defined = definedMap.get(node) || new Set();
189
- const references = referencedMap.get(node) || new Set();
190
- const bindings = bindingMap.get(node);
191
-
192
- // No changes needed here
193
- if (!defined && !renamedVariables.has(node)) {
194
- renamedVariables.set(node, Object.create(null));
195
- return;
196
- }
197
-
198
- const newNames = new Map<string, string>();
199
-
200
- // Names possible to be re-used here
201
- var possible = new Set<string>();
202
-
203
- // 3. Try to re-use names when possible
204
- if (reusePreviousNames && generated.length && !isGlobal) {
205
- var allReferences = new Set<string>();
206
- var nope = new Set(defined);
207
-
208
- scopePath.traverse({
209
- Scopable(path) {
210
- const { node } = path.scope.path;
211
-
212
- var ref = referencedMap.get(node);
213
- if (ref) {
214
- ref.forEach((x) => allReferences.add(x));
215
- }
216
-
217
- var def = definedMap.get(node);
218
- if (def) {
219
- def.forEach((x) => allReferences.add(x));
220
- }
221
- },
222
- });
223
-
224
- var passed = new Set<string>();
225
-
226
- const parentPaths = scopePath.getAncestry();
227
- parentPaths.forEach((p) => {
228
- if (p === scopePath) return;
229
-
230
- let changes = renamedVariables.get(p.node);
231
- if (changes) {
232
- for (let [oldName, newName] of changes) {
233
- if (!allReferences.has(oldName) && !references.has(oldName)) {
234
- passed.add(newName);
235
- } else {
236
- nope.add(newName);
237
- }
238
- }
239
- }
240
- });
241
-
242
- nope.forEach((x) => passed.delete(x));
243
-
244
- possible = passed;
245
- }
246
-
247
- function shouldRename(name: string) {
248
- // __NO_JS_CONFUSER_RENAME__
249
- if (name.startsWith(noRenameVariablePrefix)) return false;
250
-
251
- // Placeholder variables should always be renamed
252
- if (name.startsWith(placeholderVariablePrefix)) return true;
253
-
254
- const binding = bindings?.get(name);
255
-
256
- if (binding) {
257
- // Do not rename exports
258
- if (isExportedIdentifier(binding)) return false;
259
- }
260
-
261
- if (name === me.obfuscator.getStringCompressionLibraryName())
262
- return false;
263
-
264
- // Global variables are additionally checked against user option
265
- if (isGlobal) {
266
- if (!me.computeProbabilityMap(me.options.renameGlobals, name))
267
- return false;
268
- }
269
-
270
- if (
271
- !me.computeProbabilityMap(me.options.renameVariables, name, isGlobal)
272
- )
273
- return false;
274
-
275
- return true;
276
- }
277
-
278
- // 4. Defined names to new names
279
- for (var name of defined) {
280
- let newName = name;
281
-
282
- if (shouldRename(name)) {
283
- me.changeData.variables++;
284
-
285
- // Create a new name from (1) or (2) methods
286
- do {
287
- if (possible.size) {
288
- // (1) Re-use previously generated name
289
- var first = possible.values().next().value;
290
- possible.delete(first);
291
- newName = first;
292
- } else {
293
- // (2) Create a new name with global `nameGen`
294
- var generatedName = me.obfuscator.nameGen.generate();
295
-
296
- newName = generatedName;
297
- generated.push(generatedName);
298
- }
299
- } while (
300
- scopePath.scope.hasGlobal(newName) ||
301
- me.obfuscator.nameGen.notSafeForReuseNames.has(newName)
302
- );
303
- // Ensure global names aren't overridden
304
- }
305
-
306
- newNames.set(name, newName);
307
- }
308
-
309
- // console.log(node.type, newNames);
310
- renamedVariables.set(node, newNames);
311
- },
312
- };
313
-
314
- return {
315
- visitor: {
316
- ...VariableAnalysisVisitor,
317
-
318
- ...VariableRenamingVisitor,
319
- },
320
- };
321
- };
1
+ import { NodePath } from "@babel/traverse";
2
+ import { Visitor } from "@babel/traverse";
3
+ import { PluginArg, PluginObject } from "../plugin";
4
+ import * as t from "@babel/types";
5
+ import { Order } from "../../order";
6
+ import {
7
+ noRenameVariablePrefix,
8
+ placeholderVariablePrefix,
9
+ WITH_STATEMENT,
10
+ } from "../../constants";
11
+ import {
12
+ getParentFunctionOrProgram,
13
+ isDefiningIdentifier,
14
+ isExportedIdentifier,
15
+ isVariableIdentifier,
16
+ } from "../../utils/ast-utils";
17
+ import { isVariableFunctionIdentifier } from "../../utils/function-utils";
18
+
19
+ const RENAMED = Symbol("Renamed");
20
+
21
+ const reusePreviousNames = true;
22
+
23
+ export default ({ Plugin }: PluginArg): PluginObject => {
24
+ const me = Plugin(Order.RenameVariables, {
25
+ changeData: {
26
+ variables: 0,
27
+ },
28
+ });
29
+
30
+ const definedMap = new Map<t.Node, Set<string>>();
31
+ const referencedMap = new Map<t.Node, Set<string>>();
32
+ const paramMap = new Map<t.Node, Set<string>>(); // Used for default function parameter special case
33
+ const bindingMap = new Map<t.Node, Map<string, NodePath<t.Identifier>>>();
34
+
35
+ const renamedVariables = new Map<t.Node, Map<string, string>>();
36
+ me.obfuscator.globalState.renamedVariables = renamedVariables;
37
+
38
+ const generated = Array.from(me.obfuscator.nameGen.generatedNames);
39
+
40
+ const VariableAnalysisVisitor: Visitor = {
41
+ Program: {
42
+ enter(path) {
43
+ // Analyze all scopes
44
+ path.traverse({
45
+ Identifier(path) {
46
+ if (!isVariableIdentifier(path)) return;
47
+
48
+ let contextPaths: NodePath<t.Node>[] = [
49
+ getParentFunctionOrProgram(path),
50
+ ];
51
+
52
+ let isDefined = false;
53
+
54
+ if (path.isBindingIdentifier() && isDefiningIdentifier(path)) {
55
+ isDefined = true;
56
+ const binding = path.scope.getBinding(path.node.name);
57
+
58
+ // Function ID is defined in the parent's function declaration
59
+ if (
60
+ path.key === "id" &&
61
+ path.parentPath.isFunctionDeclaration()
62
+ ) {
63
+ contextPaths = [getParentFunctionOrProgram(path.parentPath)];
64
+ }
65
+
66
+ if (
67
+ binding &&
68
+ binding.kind === "let" &&
69
+ binding.path.key === "handler" &&
70
+ binding.path.isCatchClause()
71
+ ) {
72
+ contextPaths = [path];
73
+ }
74
+ }
75
+
76
+ contextPaths.forEach((contextPath) => {
77
+ // console.log(contextPath.node.type, path.node.name, isDefined);
78
+
79
+ if (isDefined) {
80
+ // Add to defined map
81
+ if (!definedMap.has(contextPath.node)) {
82
+ definedMap.set(contextPath.node, new Set());
83
+ }
84
+ definedMap.get(contextPath.node).add(path.node.name);
85
+
86
+ if (!bindingMap.has(contextPath.node)) {
87
+ bindingMap.set(contextPath.node, new Map());
88
+ }
89
+ bindingMap.get(contextPath.node).set(path.node.name, path);
90
+ } else {
91
+ // Add to reference map
92
+ if (!referencedMap.has(contextPath.node)) {
93
+ referencedMap.set(contextPath.node, new Set());
94
+ }
95
+ referencedMap.get(contextPath.node).add(path.node.name);
96
+ }
97
+ });
98
+ },
99
+ });
100
+
101
+ //
102
+ },
103
+ },
104
+ };
105
+
106
+ const VariableRenamingVisitor: Visitor = {
107
+ Identifier(identifierPath) {
108
+ if (!isVariableIdentifier(identifierPath)) return;
109
+ const node = identifierPath.node;
110
+ const identifierName = node.name;
111
+
112
+ if (node[RENAMED]) return;
113
+ if (node[WITH_STATEMENT]) return; // Exclude CFF identifiers
114
+
115
+ var contextPaths: NodePath[] = identifierPath.getAncestry();
116
+
117
+ // A Function ID is not in the same context as it's body
118
+ if (
119
+ identifierPath.key === "id" &&
120
+ identifierPath.parentPath.isFunctionDeclaration()
121
+ ) {
122
+ contextPaths = contextPaths.filter(
123
+ (x) => x !== identifierPath.parentPath
124
+ );
125
+ }
126
+
127
+ var newName = null;
128
+
129
+ const skippedPaths = new Set();
130
+
131
+ for (let contextPath of contextPaths) {
132
+ if (skippedPaths.has(contextPath)) continue;
133
+
134
+ if (contextPath.isFunction()) {
135
+ var assignmentPattern = contextPath.find(
136
+ (p) => p.listKey === "params" && p.parentPath.isFunction()
137
+ );
138
+
139
+ if (assignmentPattern?.isAssignmentPattern()) {
140
+ var functionPath = assignmentPattern.getFunctionParent();
141
+
142
+ if (functionPath) {
143
+ // The parameters can be still accessed...
144
+ const params = paramMap.get(functionPath.node);
145
+ if (params?.has(identifierName)) {
146
+ } else {
147
+ skippedPaths.add(functionPath);
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ const { node } = contextPath;
154
+
155
+ const defined = definedMap.get(node);
156
+ if (defined?.has(identifierName)) {
157
+ const renamed = renamedVariables.get(node);
158
+ if (renamed?.has(identifierName)) {
159
+ newName = renamed.get(identifierName);
160
+ break;
161
+ }
162
+ }
163
+ }
164
+
165
+ if (newName && typeof newName === "string") {
166
+ // __JS_CONFUSER_VAR__ function
167
+ if (isVariableFunctionIdentifier(identifierPath)) {
168
+ identifierPath.parentPath.replaceWith(t.stringLiteral(newName));
169
+ return;
170
+ }
171
+
172
+ // 5. Update Identifier node's 'name' property
173
+ node.name = newName;
174
+ node[RENAMED] = true;
175
+
176
+ // 6. Additional parameter mapping
177
+ const binding = identifierPath.scope.getBinding(identifierName);
178
+ if (binding?.kind === "param") {
179
+ var mapNode = binding.scope.path.node;
180
+ if (!paramMap.has(mapNode)) {
181
+ paramMap.set(mapNode, new Set([identifierName]));
182
+ } else {
183
+ paramMap.get(mapNode).add(identifierName);
184
+ }
185
+ }
186
+ }
187
+ },
188
+
189
+ Scopable(scopePath: NodePath<t.Scopable>) {
190
+ // 2. Notice this is on 'onEnter' (top-down)
191
+ const isGlobal = scopePath.isProgram();
192
+ const { node } = scopePath.scope.path;
193
+ if (renamedVariables.has(node)) return;
194
+
195
+ const defined = definedMap.get(node) || new Set();
196
+ const references = referencedMap.get(node) || new Set();
197
+ const bindings = bindingMap.get(node);
198
+
199
+ // No changes needed here
200
+ if (!defined && !renamedVariables.has(node)) {
201
+ renamedVariables.set(node, Object.create(null));
202
+ return;
203
+ }
204
+
205
+ const newNames = new Map<string, string>();
206
+
207
+ // Names possible to be re-used here
208
+ var possible = new Set<string>();
209
+
210
+ // 3. Try to re-use names when possible
211
+ if (reusePreviousNames && generated.length && !isGlobal) {
212
+ var allReferences = new Set<string>();
213
+ var nope = new Set(defined);
214
+
215
+ scopePath.traverse({
216
+ Scopable(path) {
217
+ const { node } = path.scope.path;
218
+
219
+ var ref = referencedMap.get(node);
220
+ if (ref) {
221
+ ref.forEach((x) => allReferences.add(x));
222
+ }
223
+
224
+ var def = definedMap.get(node);
225
+ if (def) {
226
+ def.forEach((x) => allReferences.add(x));
227
+ }
228
+ },
229
+ });
230
+
231
+ var passed = new Set<string>();
232
+
233
+ const parentPaths = scopePath.getAncestry();
234
+ parentPaths.forEach((p) => {
235
+ if (p === scopePath) return;
236
+
237
+ let changes = renamedVariables.get(p.node);
238
+ if (changes) {
239
+ for (let [oldName, newName] of changes) {
240
+ if (!allReferences.has(oldName) && !references.has(oldName)) {
241
+ passed.add(newName);
242
+ } else {
243
+ nope.add(newName);
244
+ }
245
+ }
246
+ }
247
+ });
248
+
249
+ nope.forEach((x) => passed.delete(x));
250
+
251
+ possible = passed;
252
+ }
253
+
254
+ function shouldRename(name: string) {
255
+ // __NO_JS_CONFUSER_RENAME__
256
+ if (name.startsWith(noRenameVariablePrefix)) return false;
257
+
258
+ // Placeholder variables should always be renamed
259
+ if (name.startsWith(placeholderVariablePrefix)) return true;
260
+
261
+ const binding = bindings?.get(name);
262
+
263
+ if (binding) {
264
+ // Do not rename exports
265
+ if (isExportedIdentifier(binding)) return false;
266
+ }
267
+
268
+ if (name === me.obfuscator.getStringCompressionLibraryName())
269
+ return false;
270
+
271
+ // Global variables are additionally checked against user option
272
+ if (isGlobal) {
273
+ if (!me.computeProbabilityMap(me.options.renameGlobals, name))
274
+ return false;
275
+ }
276
+
277
+ if (
278
+ !me.computeProbabilityMap(me.options.renameVariables, name, isGlobal)
279
+ )
280
+ return false;
281
+
282
+ return true;
283
+ }
284
+
285
+ // 4. Defined names to new names
286
+ for (var name of defined) {
287
+ let newName = name;
288
+
289
+ if (shouldRename(name)) {
290
+ me.changeData.variables++;
291
+
292
+ // Create a new name from (1) or (2) methods
293
+ do {
294
+ if (possible.size) {
295
+ // (1) Re-use previously generated name
296
+ var first = possible.values().next().value;
297
+ possible.delete(first);
298
+ newName = first;
299
+ } else {
300
+ // (2) Create a new name with global `nameGen`
301
+ var generatedName = me.obfuscator.nameGen.generate();
302
+
303
+ newName = generatedName;
304
+ generated.push(generatedName);
305
+ }
306
+ } while (
307
+ scopePath.scope.hasGlobal(newName) ||
308
+ me.obfuscator.nameGen.notSafeForReuseNames.has(newName)
309
+ );
310
+ // Ensure global names aren't overridden
311
+ }
312
+
313
+ newNames.set(name, newName);
314
+ }
315
+
316
+ // console.log(node.type, newNames);
317
+ renamedVariables.set(node, newNames);
318
+ },
319
+ };
320
+
321
+ return {
322
+ visitor: {
323
+ ...VariableAnalysisVisitor,
324
+
325
+ ...VariableRenamingVisitor,
326
+ },
327
+ };
328
+ };