@@ -8,9 +8,14 @@ import {
8
8
isContext ,
9
9
isLexContext ,
10
10
clone ,
11
+ isFunction ,
11
12
} from "../../util/insert" ;
12
13
import Transform from "../transform" ;
13
- import { reservedIdentifiers } from "../../constants" ;
14
+ import {
15
+ noRenameVariablePrefix ,
16
+ placeholderVariablePrefix ,
17
+ reservedIdentifiers ,
18
+ } from "../../constants" ;
14
19
import { ComputeProbabilityMap } from "../../probability" ;
15
20
import VariableAnalysis from "./variableAnalysis" ;
16
21
@@ -33,6 +38,9 @@ export default class RenameVariables extends Transform {
33
38
// Ref to VariableAnalysis data
34
39
variableAnalysis : VariableAnalysis ;
35
40
41
+ // Option to re-use previously generated names
42
+ reusePreviousNames = true ;
43
+
36
44
constructor ( o ) {
37
45
super ( o , ObfuscateOrder . RenameVariables ) ;
38
46
@@ -45,10 +53,10 @@ export default class RenameVariables extends Transform {
45
53
}
46
54
47
55
match ( object : Node , parents : Node [ ] ) {
48
- return isContext ( object ) ;
56
+ return isContext ( object ) || object . type === "Identifier" ;
49
57
}
50
58
51
- transform ( object : Node , parents : Node [ ] ) {
59
+ transformContext ( object : Node , parents : Node [ ] ) {
52
60
// 2. Notice this is on 'onEnter' (top-down)
53
61
var isGlobal = object . type == "Program" ;
54
62
var type = isGlobal
@@ -76,7 +84,7 @@ export default class RenameVariables extends Transform {
76
84
var possible = new Set < string > ( ) ;
77
85
78
86
// 3. Try to re-use names when possible
79
- if ( this . generated . length && ! isGlobal ) {
87
+ if ( this . reusePreviousNames && this . generated . length && ! isGlobal ) {
80
88
var allReferences = new Set < string > ( ) ;
81
89
var nope = new Set ( defined ) ;
82
90
walk ( object , [ ] , ( o , p ) => {
@@ -115,8 +123,8 @@ export default class RenameVariables extends Transform {
115
123
// 4. Defined names to new names
116
124
for ( var name of defined ) {
117
125
if (
118
- ! name . startsWith ( "__NO_JS_CONFUSER_RENAME__" ) && // Variables prefixed with '__NO_JS_CONFUSER_RENAME__' are never renamed
119
- ( isGlobal && ! name . startsWith ( "__p_" ) // Variables prefixed with '__p_' are created by the obfuscator, always renamed
126
+ ! name . startsWith ( noRenameVariablePrefix ) && // Variables prefixed with '__NO_JS_CONFUSER_RENAME__' are never renamed
127
+ ( isGlobal && ! name . startsWith ( placeholderVariablePrefix ) // Variables prefixed with '__p_' are created by the obfuscator, always renamed
120
128
? ComputeProbabilityMap ( this . options . renameGlobals , ( x ) => x , name )
121
129
: true ) &&
122
130
ComputeProbabilityMap (
@@ -151,71 +159,127 @@ export default class RenameVariables extends Transform {
151
159
}
152
160
}
153
161
162
+ // console.log(object.type, newNames);
154
163
this . changed . set ( object , newNames ) ;
164
+ }
155
165
156
- // 5. Update Identifier node's 'name' property
157
- walk ( object , parents , ( o , p ) => {
158
- if ( o . type == "Identifier" ) {
159
- if (
160
- reservedIdentifiers . has ( o . name ) ||
161
- this . options . globalVariables . has ( o . name )
162
- ) {
163
- return ;
164
- }
166
+ transformIdentifier ( object : Node , parents : Node [ ] ) {
167
+ const identifierName = object . name ;
168
+ if (
169
+ reservedIdentifiers . has ( identifierName ) ||
170
+ this . options . globalVariables . has ( identifierName )
171
+ ) {
172
+ return ;
173
+ }
165
174
166
- if ( o . $renamed ) {
167
- return ;
168
- }
175
+ if ( object . $renamed ) {
176
+ return ;
177
+ }
169
178
170
- var info = getIdentifierInfo ( o , p ) ;
179
+ var info = getIdentifierInfo ( object , parents ) ;
171
180
172
- if ( info . spec . isExported ) {
173
- return ;
174
- }
181
+ if ( info . spec . isExported ) {
182
+ return ;
183
+ }
175
184
176
- if ( ! info . spec . isReferenced ) {
177
- return ;
178
- }
185
+ if ( ! info . spec . isReferenced ) {
186
+ return ;
187
+ }
188
+
189
+ var contexts = [ object , ...parents ] . filter ( ( x ) => isContext ( x ) ) ;
190
+ var newName = null ;
191
+
192
+ // Function default parameter check!
193
+ var functionIndices = [ ] ;
194
+ for ( var i in parents ) {
195
+ if ( isFunction ( parents [ i ] ) ) {
196
+ functionIndices . push ( i ) ;
197
+ }
198
+ }
199
+
200
+ for ( var functionIndex of functionIndices ) {
201
+ if ( parents [ functionIndex ] . id === object ) {
202
+ // This context is not referenced, so remove it
203
+ contexts = contexts . filter (
204
+ ( context ) => context != parents [ functionIndex ]
205
+ ) ;
206
+ continue ;
207
+ }
208
+ if ( parents [ functionIndex ] . params === parents [ functionIndex - 1 ] ) {
209
+ var isReferencedHere = true ;
179
210
180
- var contexts = [ o , ...p ] . filter ( ( x ) => isContext ( x ) ) ;
181
- var newName = null ;
211
+ var slicedParents = parents . slice ( 0 , functionIndex ) ;
212
+ var forIndex = 0 ;
213
+ for ( var parent of slicedParents ) {
214
+ var childNode = slicedParents [ forIndex - 1 ] || object ;
182
215
183
- for ( var check of contexts ) {
184
216
if (
185
- this . variableAnalysis . defined . has ( check ) &&
186
- this . variableAnalysis . defined . get ( check ) . has ( o . name )
217
+ parent . type === "AssignmentPattern" &&
218
+ parent . right === childNode
187
219
) {
188
- if ( this . changed . has ( check ) && this . changed . get ( check ) [ o . name ] ) {
189
- newName = this . changed . get ( check ) [ o . name ] ;
190
- break ;
191
- }
220
+ isReferencedHere = false ;
221
+ break ;
192
222
}
223
+
224
+ forIndex ++ ;
193
225
}
194
226
195
- if ( newName && typeof newName === "string" ) {
196
- // Strange behavior where the `local` and `imported` objects are the same
197
- if ( info . isImportSpecifier ) {
198
- var importSpecifierIndex = p . findIndex (
199
- ( x ) => x . type === "ImportSpecifier"
200
- ) ;
201
- if (
202
- importSpecifierIndex != - 1 &&
203
- p [ importSpecifierIndex ] . imported ===
204
- ( p [ importSpecifierIndex - 1 ] || o ) &&
205
- p [ importSpecifierIndex ] . imported &&
206
- p [ importSpecifierIndex ] . imported . type === "Identifier"
207
- ) {
208
- p [ importSpecifierIndex ] . imported = clone (
209
- p [ importSpecifierIndex - 1 ] || o
210
- ) ;
211
- }
212
- }
227
+ if ( ! isReferencedHere ) {
228
+ // This context is not referenced, so remove it
229
+ contexts = contexts . filter (
230
+ ( context ) => context != parents [ functionIndex ]
231
+ ) ;
232
+ }
233
+ }
234
+ }
213
235
214
- // console.log(o.name, "->", newName);
215
- o . name = newName ;
216
- o . $renamed = true ;
236
+ for ( var check of contexts ) {
237
+ if (
238
+ this . variableAnalysis . defined . has ( check ) &&
239
+ this . variableAnalysis . defined . get ( check ) . has ( identifierName )
240
+ ) {
241
+ if (
242
+ this . changed . has ( check ) &&
243
+ this . changed . get ( check ) [ identifierName ]
244
+ ) {
245
+ newName = this . changed . get ( check ) [ identifierName ] ;
246
+ break ;
217
247
}
218
248
}
219
- } ) ;
249
+ }
250
+
251
+ if ( newName && typeof newName === "string" ) {
252
+ // Strange behavior where the `local` and `imported` objects are the same
253
+ if ( info . isImportSpecifier ) {
254
+ var importSpecifierIndex = parents . findIndex (
255
+ ( x ) => x . type === "ImportSpecifier"
256
+ ) ;
257
+ if (
258
+ importSpecifierIndex != - 1 &&
259
+ parents [ importSpecifierIndex ] . imported ===
260
+ ( parents [ importSpecifierIndex - 1 ] || object ) &&
261
+ parents [ importSpecifierIndex ] . imported &&
262
+ parents [ importSpecifierIndex ] . imported . type === "Identifier"
263
+ ) {
264
+ parents [ importSpecifierIndex ] . imported = clone (
265
+ parents [ importSpecifierIndex - 1 ] || object
266
+ ) ;
267
+ }
268
+ }
269
+
270
+ // console.log(o.name, "->", newName);
271
+ // 5. Update Identifier node's 'name' property
272
+ object . name = newName ;
273
+ object . $renamed = true ;
274
+ }
275
+ }
276
+
277
+ transform ( object : Node , parents : Node [ ] ) {
278
+ var matchType = object . type === "Identifier" ? "Identifier" : "Context" ;
279
+ if ( matchType === "Identifier" ) {
280
+ this . transformIdentifier ( object , parents ) ;
281
+ } else {
282
+ this . transformContext ( object , parents ) ;
283
+ }
220
284
}
221
285
}
0 commit comments