@@ -6,6 +6,7 @@ import { walk } from "../traverse";
6
6
import {
7
7
AssignmentExpression ,
8
8
BinaryExpression ,
9
+ CallExpression ,
9
10
ExpressionStatement ,
10
11
Identifier ,
11
12
IfStatement ,
@@ -18,6 +19,7 @@ import {
18
19
} from "../util/gen" ;
19
20
import { getIdentifierInfo } from "../util/identifiers" ;
20
21
import {
22
+ computeFunctionLength ,
21
23
getBlockBody ,
22
24
getDefiningContext ,
23
25
getReferencingContexts ,
@@ -28,10 +30,14 @@ import {
28
30
} from "../util/insert" ;
29
31
import { chance , choice , getRandomInteger } from "../util/random" ;
30
32
import Transform from "./transform" ;
33
+ import { noRenameVariablePrefix } from "../constants" ;
34
+ import { FunctionLengthTemplate } from "../templates/functionLength" ;
31
35
32
36
export default class Stack extends Transform {
33
37
mangledExpressionsMade : number ;
34
38
39
+ functionLengthName : string ;
40
+
35
41
constructor ( o ) {
36
42
super ( o , ObfuscateOrder . Stack ) ;
37
43
@@ -111,8 +117,14 @@ export default class Stack extends Transform {
111
117
} ) ;
112
118
113
119
var startingSize = subscripts . size ;
120
+ var isIllegal = false ;
114
121
115
122
walk ( object . body , [ object , ...parents ] , ( o , p ) => {
123
+ if ( o . type === "Identifier" && o . name === "arguments" ) {
124
+ isIllegal = true ;
125
+ return "EXIT" ;
126
+ }
127
+
116
128
if ( o . type == "Identifier" ) {
117
129
var info = getIdentifierInfo ( o , p ) ;
118
130
if ( ! info . spec . isReferenced || info . spec . isExported ) {
@@ -128,6 +140,10 @@ export default class Stack extends Transform {
128
140
illegal . add ( o . name ) ;
129
141
}
130
142
143
+ if ( o . name . startsWith ( noRenameVariablePrefix ) ) {
144
+ illegal . add ( o . name ) ;
145
+ }
146
+
131
147
if (
132
148
info . isClauseParameter ||
133
149
info . isFunctionParameter ||
@@ -200,6 +216,8 @@ export default class Stack extends Transform {
200
216
}
201
217
} ) ;
202
218
219
+ if ( isIllegal ) return ;
220
+
203
221
illegal . forEach ( ( name ) => {
204
222
defined . delete ( name ) ;
205
223
referenced . delete ( name ) ;
@@ -467,6 +485,9 @@ export default class Stack extends Transform {
467
485
object . body . body . splice ( parseInt ( index ) + i , 0 , rotateNodes [ index ] ) ;
468
486
} ) ;
469
487
488
+ // Preserve function.length property
489
+ var originalFunctionLength = computeFunctionLength ( object . params ) ;
490
+
470
491
// Set the params for this function to be the stack array
471
492
object . params = [ RestElement ( Identifier ( stackName ) ) ] ;
472
493
@@ -475,6 +496,47 @@ export default class Stack extends Transform {
475
496
object . body ,
476
497
Template ( `${ stackName } ["length"] = ${ startingSize } ` ) . single ( )
477
498
) ;
499
+
500
+ if ( originalFunctionLength !== 0 ) {
501
+ if ( ! this . functionLengthName ) {
502
+ this . functionLengthName = this . getPlaceholder ( ) ;
503
+ prepend (
504
+ parents [ parents . length - 1 ] || object ,
505
+ FunctionLengthTemplate . single ( { name : this . functionLengthName } )
506
+ ) ;
507
+ }
508
+
509
+ if ( object . type === "FunctionDeclaration" ) {
510
+ var body = parents [ 0 ] ;
511
+ if ( Array . isArray ( body ) ) {
512
+ var index = body . indexOf ( object ) ;
513
+
514
+ body . splice (
515
+ index ,
516
+ 0 ,
517
+ ExpressionStatement (
518
+ CallExpression ( Identifier ( this . functionLengthName ) , [
519
+ Identifier ( object . id . name ) ,
520
+ Literal ( originalFunctionLength ) ,
521
+ ] )
522
+ )
523
+ ) ;
524
+ }
525
+ } else {
526
+ ok (
527
+ object . type === "FunctionExpression" ||
528
+ object . type === "ArrowFunctionExpression"
529
+ ) ;
530
+
531
+ this . replace (
532
+ object ,
533
+ CallExpression ( Identifier ( this . functionLengthName ) , [
534
+ { ...object } ,
535
+ Literal ( originalFunctionLength ) ,
536
+ ] )
537
+ ) ;
538
+ }
539
+ }
478
540
} ;
479
541
}
480
542
}
0 commit comments