webfuscator 1.2.1 → 1.3.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.
- package/README.md +3 -3
- package/dist/analysis/constant.d.ts.map +1 -1
- package/dist/analysis/constant.js +10 -27
- package/dist/analysis/constant.js.map +1 -1
- package/dist/analysis/inlineability.d.ts.map +1 -1
- package/dist/analysis/inlineability.js +5 -13
- package/dist/analysis/inlineability.js.map +1 -1
- package/dist/analysis/purity.d.ts +3 -3
- package/dist/analysis/purity.d.ts.map +1 -1
- package/dist/analysis/purity.js +28 -75
- package/dist/analysis/purity.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/obfuscator.d.ts +2 -1
- package/dist/obfuscator.d.ts.map +1 -1
- package/dist/obfuscator.js +47 -12
- package/dist/obfuscator.js.map +1 -1
- package/dist/options.d.ts +17 -4
- package/dist/options.d.ts.map +1 -1
- package/dist/preparation/expand-destructuring.d.ts +2 -3
- package/dist/preparation/expand-destructuring.d.ts.map +1 -1
- package/dist/preparation/expand-destructuring.js +2 -8
- package/dist/preparation/expand-destructuring.js.map +1 -1
- package/dist/transforms/arguments-to-parameters.d.ts +5 -4
- package/dist/transforms/arguments-to-parameters.d.ts.map +1 -1
- package/dist/transforms/arguments-to-parameters.js +5 -4
- package/dist/transforms/arguments-to-parameters.js.map +1 -1
- package/dist/transforms/arrow-to-function.d.ts +4 -3
- package/dist/transforms/arrow-to-function.d.ts.map +1 -1
- package/dist/transforms/arrow-to-function.js +6 -10
- package/dist/transforms/arrow-to-function.js.map +1 -1
- package/dist/transforms/collapse-single-use-temps.d.ts +2 -1
- package/dist/transforms/collapse-single-use-temps.d.ts.map +1 -1
- package/dist/transforms/collapse-single-use-temps.js +12 -20
- package/dist/transforms/collapse-single-use-temps.js.map +1 -1
- package/dist/transforms/conceal-strings.d.ts +56 -0
- package/dist/transforms/conceal-strings.d.ts.map +1 -0
- package/dist/transforms/conceal-strings.js +356 -0
- package/dist/transforms/conceal-strings.js.map +1 -0
- package/dist/transforms/const-let-to-var.d.ts +4 -3
- package/dist/transforms/const-let-to-var.d.ts.map +1 -1
- package/dist/transforms/const-let-to-var.js +8 -67
- package/dist/transforms/const-let-to-var.js.map +1 -1
- package/dist/transforms/const-to-let.d.ts +1 -3
- package/dist/transforms/const-to-let.d.ts.map +1 -1
- package/dist/transforms/const-to-let.js +1 -8
- package/dist/transforms/const-to-let.js.map +1 -1
- package/dist/transforms/drop-console.d.ts.map +1 -1
- package/dist/transforms/drop-console.js +3 -5
- package/dist/transforms/drop-console.js.map +1 -1
- package/dist/transforms/expand-binary-assignment.d.ts.map +1 -1
- package/dist/transforms/expand-binary-assignment.js +0 -5
- package/dist/transforms/expand-binary-assignment.js.map +1 -1
- package/dist/transforms/expand-logical-assignment.d.ts.map +1 -1
- package/dist/transforms/expand-logical-assignment.js +0 -5
- package/dist/transforms/expand-logical-assignment.js.map +1 -1
- package/dist/transforms/extract-object-properties.js +5 -12
- package/dist/transforms/extract-object-properties.js.map +1 -1
- package/dist/transforms/fold-builtin-methods.d.ts.map +1 -1
- package/dist/transforms/fold-builtin-methods.js +44 -14
- package/dist/transforms/fold-builtin-methods.js.map +1 -1
- package/dist/transforms/fold-constants.js +5 -2
- package/dist/transforms/fold-constants.js.map +1 -1
- package/dist/transforms/function-declaration-to-expression.d.ts +5 -6
- package/dist/transforms/function-declaration-to-expression.d.ts.map +1 -1
- package/dist/transforms/function-declaration-to-expression.js +5 -6
- package/dist/transforms/function-declaration-to-expression.js.map +1 -1
- package/dist/transforms/hoist-variables.d.ts +29 -0
- package/dist/transforms/hoist-variables.d.ts.map +1 -0
- package/dist/transforms/hoist-variables.js +215 -0
- package/dist/transforms/hoist-variables.js.map +1 -0
- package/dist/transforms/inline-functions.js +11 -40
- package/dist/transforms/inline-functions.js.map +1 -1
- package/dist/transforms/logical-to-ternary.d.ts +1 -1
- package/dist/transforms/logical-to-ternary.js +5 -9
- package/dist/transforms/logical-to-ternary.js.map +1 -1
- package/dist/transforms/mangle-properties.d.ts +2 -5
- package/dist/transforms/mangle-properties.d.ts.map +1 -1
- package/dist/transforms/mangle-properties.js +9 -9
- package/dist/transforms/mangle-properties.js.map +1 -1
- package/dist/transforms/merge-variable-declarations.d.ts +17 -0
- package/dist/transforms/merge-variable-declarations.d.ts.map +1 -0
- package/dist/transforms/merge-variable-declarations.js +68 -0
- package/dist/transforms/merge-variable-declarations.js.map +1 -0
- package/dist/transforms/nullish-coalescing-to-ternary.d.ts +4 -5
- package/dist/transforms/nullish-coalescing-to-ternary.d.ts.map +1 -1
- package/dist/transforms/nullish-coalescing-to-ternary.js +7 -12
- package/dist/transforms/nullish-coalescing-to-ternary.js.map +1 -1
- package/dist/transforms/numbers-to-strings.d.ts.map +1 -1
- package/dist/transforms/numbers-to-strings.js +1 -8
- package/dist/transforms/numbers-to-strings.js.map +1 -1
- package/dist/transforms/object-method-to-property.d.ts +1 -1
- package/dist/transforms/object-method-to-property.js +1 -1
- package/dist/transforms/optional-chaining-to-ternary.d.ts +4 -3
- package/dist/transforms/optional-chaining-to-ternary.d.ts.map +1 -1
- package/dist/transforms/optional-chaining-to-ternary.js +9 -9
- package/dist/transforms/optional-chaining-to-ternary.js.map +1 -1
- package/dist/transforms/pack-declarations-into-parameters.d.ts.map +1 -1
- package/dist/transforms/pack-declarations-into-parameters.js +5 -21
- package/dist/transforms/pack-declarations-into-parameters.js.map +1 -1
- package/dist/transforms/pack.d.ts +4 -13
- package/dist/transforms/pack.d.ts.map +1 -1
- package/dist/transforms/pack.js +9 -29
- package/dist/transforms/pack.js.map +1 -1
- package/dist/transforms/remove-anonymous-function-names.d.ts +2 -4
- package/dist/transforms/remove-anonymous-function-names.d.ts.map +1 -1
- package/dist/transforms/remove-anonymous-function-names.js +2 -40
- package/dist/transforms/remove-anonymous-function-names.js.map +1 -1
- package/dist/transforms/remove-unreachable-code.js +2 -21
- package/dist/transforms/remove-unreachable-code.js.map +1 -1
- package/dist/transforms/remove-unused-code.d.ts.map +1 -1
- package/dist/transforms/remove-unused-code.js +12 -49
- package/dist/transforms/remove-unused-code.js.map +1 -1
- package/dist/transforms/rename-identifiers.d.ts +3 -3
- package/dist/transforms/rename-identifiers.d.ts.map +1 -1
- package/dist/transforms/rename-identifiers.js +31 -35
- package/dist/transforms/rename-identifiers.js.map +1 -1
- package/dist/transforms/reorder-function-declarations.d.ts +24 -0
- package/dist/transforms/reorder-function-declarations.d.ts.map +1 -0
- package/dist/transforms/reorder-function-declarations.js +62 -0
- package/dist/transforms/reorder-function-declarations.js.map +1 -0
- package/dist/transforms/specials-to-strings.d.ts.map +1 -1
- package/dist/transforms/specials-to-strings.js +2 -3
- package/dist/transforms/specials-to-strings.js.map +1 -1
- package/dist/transforms/switch-to-if.js +5 -15
- package/dist/transforms/switch-to-if.js.map +1 -1
- package/dist/transforms/ternary-to-if.d.ts.map +1 -1
- package/dist/transforms/ternary-to-if.js +5 -9
- package/dist/transforms/ternary-to-if.js.map +1 -1
- package/dist/transforms/update-to-assignment.d.ts.map +1 -1
- package/dist/transforms/update-to-assignment.js +6 -23
- package/dist/transforms/update-to-assignment.js.map +1 -1
- package/dist/transforms/yodify-conditions.d.ts +3 -4
- package/dist/transforms/yodify-conditions.d.ts.map +1 -1
- package/dist/transforms/yodify-conditions.js +3 -4
- package/dist/transforms/yodify-conditions.js.map +1 -1
- package/dist/utils/ast.d.ts +1 -3
- package/dist/utils/ast.d.ts.map +1 -1
- package/dist/utils/ast.js +4 -60
- package/dist/utils/ast.js.map +1 -1
- package/dist/utils/evaluation-order.js +1 -1
- package/dist/utils/evaluation-order.js.map +1 -1
- package/dist/utils/literal.d.ts.map +1 -1
- package/dist/utils/literal.js +74 -2
- package/dist/utils/literal.js.map +1 -1
- package/dist/utils/logical-lowering.d.ts.map +1 -1
- package/dist/utils/logical-lowering.js +7 -9
- package/dist/utils/logical-lowering.js.map +1 -1
- package/dist/utils/nullish.d.ts +4 -0
- package/dist/utils/nullish.d.ts.map +1 -0
- package/dist/utils/nullish.js +8 -0
- package/dist/utils/nullish.js.map +1 -0
- package/dist/utils/paths.d.ts +0 -2
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +0 -28
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/statement-lists.d.ts +9 -0
- package/dist/utils/statement-lists.d.ts.map +1 -0
- package/dist/utils/statement-lists.js +27 -0
- package/dist/utils/statement-lists.js.map +1 -0
- package/package.json +6 -2
- package/src/analysis/constant.ts +12 -33
- package/src/analysis/inlineability.ts +5 -13
- package/src/analysis/purity.ts +29 -92
- package/src/index.ts +1 -0
- package/src/obfuscator.ts +51 -14
- package/src/options.ts +21 -3
- package/src/preparation/expand-destructuring.ts +2 -10
- package/src/transforms/arguments-to-parameters.ts +5 -4
- package/src/transforms/arrow-to-function.ts +6 -10
- package/src/transforms/collapse-single-use-temps.ts +12 -23
- package/src/transforms/conceal-strings.ts +525 -0
- package/src/transforms/const-let-to-var.ts +9 -72
- package/src/transforms/const-to-let.ts +1 -8
- package/src/transforms/drop-console.ts +3 -5
- package/src/transforms/expand-binary-assignment.ts +0 -5
- package/src/transforms/expand-logical-assignment.ts +0 -5
- package/src/transforms/extract-object-properties.ts +5 -14
- package/src/transforms/fold-builtin-methods.ts +63 -17
- package/src/transforms/fold-constants.ts +5 -2
- package/src/transforms/function-declaration-to-expression.ts +5 -6
- package/src/transforms/hoist-variables.ts +262 -0
- package/src/transforms/inline-functions.ts +16 -47
- package/src/transforms/logical-to-ternary.ts +5 -10
- package/src/transforms/mangle-properties.ts +9 -12
- package/src/transforms/merge-variable-declarations.ts +91 -0
- package/src/transforms/nullish-coalescing-to-ternary.ts +7 -13
- package/src/transforms/numbers-to-strings.ts +2 -12
- package/src/transforms/object-method-to-property.ts +1 -1
- package/src/transforms/optional-chaining-to-ternary.ts +9 -9
- package/src/transforms/pack-declarations-into-parameters.ts +11 -21
- package/src/transforms/pack.ts +9 -30
- package/src/transforms/remove-anonymous-function-names.ts +3 -46
- package/src/transforms/remove-unreachable-code.ts +2 -22
- package/src/transforms/remove-unused-code.ts +14 -74
- package/src/transforms/rename-identifiers.ts +44 -35
- package/src/transforms/reorder-function-declarations.ts +78 -0
- package/src/transforms/specials-to-strings.ts +2 -3
- package/src/transforms/switch-to-if.ts +5 -22
- package/src/transforms/ternary-to-if.ts +5 -9
- package/src/transforms/update-to-assignment.ts +6 -24
- package/src/transforms/yodify-conditions.ts +3 -4
- package/src/utils/ast.ts +4 -69
- package/src/utils/evaluation-order.ts +1 -1
- package/src/utils/literal.ts +91 -2
- package/src/utils/logical-lowering.ts +7 -11
- package/src/utils/nullish.ts +23 -0
- package/src/utils/paths.ts +0 -32
- package/src/utils/statement-lists.ts +45 -0
package/src/obfuscator.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { wrapSingleStatements } from './preparation/wrap-single-statements'
|
|
|
14
14
|
import { argumentsToParameters } from './transforms/arguments-to-parameters'
|
|
15
15
|
import { arrowToFunction } from './transforms/arrow-to-function'
|
|
16
16
|
import { collapseSingleUseTemps } from './transforms/collapse-single-use-temps'
|
|
17
|
+
import { concealStrings } from './transforms/conceal-strings'
|
|
17
18
|
import { constLetToVar } from './transforms/const-let-to-var'
|
|
18
19
|
import { constToLet } from './transforms/const-to-let'
|
|
19
20
|
import { doWhileToWhile } from './transforms/do-while-to-while'
|
|
@@ -26,9 +27,11 @@ import { foldBuiltinMethods } from './transforms/fold-builtin-methods'
|
|
|
26
27
|
import { foldConstants } from './transforms/fold-constants'
|
|
27
28
|
import { forToWhile } from './transforms/for-to-while'
|
|
28
29
|
import { functionDeclarationToExpression } from './transforms/function-declaration-to-expression'
|
|
30
|
+
import { hoistVariables } from './transforms/hoist-variables'
|
|
29
31
|
import { inlineFunctions } from './transforms/inline-functions'
|
|
30
32
|
import { logicalToTernary } from './transforms/logical-to-ternary'
|
|
31
33
|
import { mangleProperties } from './transforms/mangle-properties'
|
|
34
|
+
import { mergeVariableDeclarations } from './transforms/merge-variable-declarations'
|
|
32
35
|
import { nullishCoalescingToTernary } from './transforms/nullish-coalescing-to-ternary'
|
|
33
36
|
import { numbersToStrings } from './transforms/numbers-to-strings'
|
|
34
37
|
import { objectMethodToProperty } from './transforms/object-method-to-property'
|
|
@@ -39,6 +42,7 @@ import { removeAnonymousFunctionNames } from './transforms/remove-anonymous-func
|
|
|
39
42
|
import { removeUnreachableCode } from './transforms/remove-unreachable-code'
|
|
40
43
|
import { removeUnusedCode } from './transforms/remove-unused-code'
|
|
41
44
|
import { renameIdentifiers } from './transforms/rename-identifiers'
|
|
45
|
+
import { reorderFunctionDeclarations } from './transforms/reorder-function-declarations'
|
|
42
46
|
import { specialsToStrings } from './transforms/specials-to-strings'
|
|
43
47
|
import { switchToIf } from './transforms/switch-to-if'
|
|
44
48
|
import { ternaryToIf } from './transforms/ternary-to-if'
|
|
@@ -48,8 +52,6 @@ import type { StringGeneratorModeOption } from './utils/string-generator'
|
|
|
48
52
|
|
|
49
53
|
const parserOptions: ParserOptions = { sourceType: 'unambiguous' }
|
|
50
54
|
|
|
51
|
-
const PRESERVED_COMMENT_RE = /^!|@(?:license|preserve)\b|^#\s*source(?:Mapping)?URL=/iu
|
|
52
|
-
|
|
53
55
|
const DEFAULT_STRING_GENERATOR_MODE: StringGeneratorModeOption = 'mangled'
|
|
54
56
|
const DEFAULT_SEED = 0
|
|
55
57
|
|
|
@@ -76,11 +78,10 @@ const PREPARATION: readonly Phase[] = [
|
|
|
76
78
|
['dotToBracket', asBoolean(dotToBracket)],
|
|
77
79
|
]
|
|
78
80
|
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
// `ObjectMethod` makes extraction refuse the whole literal.
|
|
81
|
+
// `constLetToVar` must precede the fixed point because folds need function-scoped
|
|
82
|
+
// bindings. `argumentsToParameters` must precede parameter renaming.
|
|
83
|
+
// `objectMethodToProperty` must precede extraction because one `ObjectMethod`
|
|
84
|
+
// blocks the whole object literal.
|
|
84
85
|
const PRE_LOOP: readonly ConfigurablePhase[] = [
|
|
85
86
|
['dropDebugger', dropDebugger],
|
|
86
87
|
['dropConsole', dropConsole],
|
|
@@ -124,15 +125,25 @@ const LOWERING: readonly ConfigurablePhase[] = [
|
|
|
124
125
|
['ternaryToIf', ternaryToIf],
|
|
125
126
|
]
|
|
126
127
|
|
|
127
|
-
//
|
|
128
|
-
//
|
|
128
|
+
// `packDeclarationsIntoParameters` must precede declaration motion and merging.
|
|
129
|
+
// `reorderFunctionDeclarations` follows `functionDeclarationToExpression`, so it
|
|
130
|
+
// moves only declarations still needed for hoisting. `hoistVariables` must run
|
|
131
|
+
// before `mergeVariableDeclarations`. `numbersToStrings` follows the fixed point,
|
|
132
|
+
// yodification, and `specialsToStrings` because they need or create numbers.
|
|
129
133
|
const POST_PROCESS: readonly ConfigurablePhase[] = [
|
|
130
134
|
['packDeclarationsIntoParameters', packDeclarationsIntoParameters],
|
|
135
|
+
['reorderFunctionDeclarations', reorderFunctionDeclarations],
|
|
136
|
+
['hoistVariables', hoistVariables],
|
|
137
|
+
['mergeVariableDeclarations', mergeVariableDeclarations],
|
|
131
138
|
['yodifyConditions', yodifyConditions],
|
|
132
139
|
['specialsToStrings', specialsToStrings],
|
|
133
140
|
['numbersToStrings', numbersToStrings],
|
|
134
141
|
]
|
|
135
142
|
|
|
143
|
+
// Conceal strings after every string-producing pass, but before renaming so the
|
|
144
|
+
// generated vault bindings use the caller's name generator.
|
|
145
|
+
const PROTECTION: readonly ConfigurablePhase[] = [['concealStrings', concealStrings]]
|
|
146
|
+
|
|
136
147
|
// Renaming runs last because later transforms depend on recognizable bindings.
|
|
137
148
|
const RENAME: readonly ConfigurablePhase[] = [['renameIdentifiers', renameIdentifiers]]
|
|
138
149
|
|
|
@@ -141,6 +152,19 @@ const RENAME: readonly ConfigurablePhase[] = [['renameIdentifiers', renameIdenti
|
|
|
141
152
|
// every other rewrite, including renaming.
|
|
142
153
|
const PACK: readonly ConfigurablePhase[] = [['pack', pack]]
|
|
143
154
|
|
|
155
|
+
// Tests derive their all-transforms setup from this list. The phase tables remain
|
|
156
|
+
// the only source of pipeline order.
|
|
157
|
+
export const CONFIGURABLE_TRANSFORM_NAMES: readonly TransformName[] = [
|
|
158
|
+
...BEFORE_PREPARATION,
|
|
159
|
+
...PRE_LOOP,
|
|
160
|
+
...FIXED_POINT,
|
|
161
|
+
...LOWERING,
|
|
162
|
+
...POST_PROCESS,
|
|
163
|
+
...PROTECTION,
|
|
164
|
+
...RENAME,
|
|
165
|
+
...PACK,
|
|
166
|
+
].map(([name]) => name)
|
|
167
|
+
|
|
144
168
|
/** Parses, transforms, and prints JavaScript without mutating external state. */
|
|
145
169
|
export function obfuscate(code: string, options: ObfuscatorOptions = {}): string {
|
|
146
170
|
const log = options.verbose ? makeLogger() : null
|
|
@@ -184,6 +208,13 @@ export function obfuscate(code: string, options: ObfuscatorOptions = {}): string
|
|
|
184
208
|
run(log, name, () => fn(ast, ctxFor(name, options, baseCtx)))
|
|
185
209
|
}
|
|
186
210
|
|
|
211
|
+
for (const [name, fn] of PROTECTION) {
|
|
212
|
+
if (!isEnabled(name, options)) {
|
|
213
|
+
continue
|
|
214
|
+
}
|
|
215
|
+
run(log, name, () => fn(ast, ctxFor(name, options, baseCtx)))
|
|
216
|
+
}
|
|
217
|
+
|
|
187
218
|
for (const [name, fn] of RENAME) {
|
|
188
219
|
if (!isEnabled(name, options)) {
|
|
189
220
|
continue
|
|
@@ -201,7 +232,13 @@ export function obfuscate(code: string, options: ObfuscatorOptions = {}): string
|
|
|
201
232
|
return run(
|
|
202
233
|
log,
|
|
203
234
|
'generate',
|
|
204
|
-
() =>
|
|
235
|
+
() =>
|
|
236
|
+
generate(ast, {
|
|
237
|
+
comments: false,
|
|
238
|
+
minified: options.minify ?? false,
|
|
239
|
+
// `comments: false` still allows @license and @preserve.
|
|
240
|
+
shouldPrintComment: () => false,
|
|
241
|
+
}).code,
|
|
205
242
|
)
|
|
206
243
|
}
|
|
207
244
|
|
|
@@ -216,6 +253,10 @@ function ctxFor(
|
|
|
216
253
|
options: ObfuscatorOptions,
|
|
217
254
|
base: TransformContext,
|
|
218
255
|
): TransformContext {
|
|
256
|
+
if (name === 'concealStrings') {
|
|
257
|
+
const entry = options.transforms?.concealStrings
|
|
258
|
+
return entry && typeof entry === 'object' ? { ...base, concealStrings: entry } : base
|
|
259
|
+
}
|
|
219
260
|
const entry = options.transforms?.[name]
|
|
220
261
|
let context = base
|
|
221
262
|
if (entry && typeof entry === 'object' && entry.stringGeneratorMode !== undefined) {
|
|
@@ -261,10 +302,6 @@ function asBoolean(fn: (ast: File) => unknown): TransformFn {
|
|
|
261
302
|
}
|
|
262
303
|
}
|
|
263
304
|
|
|
264
|
-
function shouldPrintComment(value: string): boolean {
|
|
265
|
-
return PRESERVED_COMMENT_RE.test(value)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
305
|
type Logger = <T>(name: string, fn: () => T) => T
|
|
269
306
|
|
|
270
307
|
function run<T>(log: Logger | null, name: string, fn: () => T): T {
|
package/src/options.ts
CHANGED
|
@@ -21,6 +21,9 @@ export type TransformName =
|
|
|
21
21
|
| 'collapseSingleUseTemps'
|
|
22
22
|
| 'arrowToFunction'
|
|
23
23
|
| 'functionDeclarationToExpression'
|
|
24
|
+
| 'reorderFunctionDeclarations'
|
|
25
|
+
| 'hoistVariables'
|
|
26
|
+
| 'mergeVariableDeclarations'
|
|
24
27
|
| 'switchToIf'
|
|
25
28
|
| 'forToWhile'
|
|
26
29
|
| 'doWhileToWhile'
|
|
@@ -35,6 +38,7 @@ export type TransformName =
|
|
|
35
38
|
| 'yodifyConditions'
|
|
36
39
|
| 'specialsToStrings'
|
|
37
40
|
| 'numbersToStrings'
|
|
41
|
+
| 'concealStrings'
|
|
38
42
|
| 'mangleProperties'
|
|
39
43
|
| 'renameIdentifiers'
|
|
40
44
|
| 'pack'
|
|
@@ -61,8 +65,8 @@ export interface ManglePropertiesOptions {
|
|
|
61
65
|
/** Custom property-name generator. It takes precedence over `stringGeneratorMode`. */
|
|
62
66
|
nameGenerator?: PropertyNameGenerator
|
|
63
67
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
68
|
+
* Mangle only names with an exact standalone `/*@__MANGLE_PROP__*\/` or
|
|
69
|
+
* `/*#__MANGLE_PROP__*\/` annotation. Default `false`.
|
|
66
70
|
*/
|
|
67
71
|
onlyAnnotated?: boolean
|
|
68
72
|
/** Only names already present in `cache` may be mangled. Default `false`. */
|
|
@@ -95,12 +99,25 @@ export interface PackOptions {
|
|
|
95
99
|
stringGeneratorMode?: StringGeneratorModeOption
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
/** Options for the string vault generated by `concealStrings`. */
|
|
103
|
+
export interface ConcealStringsOptions {
|
|
104
|
+
/** Cache each decoded string in its vault. Default `true`. */
|
|
105
|
+
cache?: boolean
|
|
106
|
+
/** Choose how much of the UTF-16 range pads each pool. Default `'regional'`. */
|
|
107
|
+
cover?: 'full' | 'regional' | 'used'
|
|
108
|
+
/** Reuse one vault entry for equal strings. Default `true`. */
|
|
109
|
+
deduplicate?: boolean
|
|
110
|
+
/** Use one program vault or a separate vault per function. Default `'program'`. */
|
|
111
|
+
scope?: 'function' | 'program'
|
|
112
|
+
}
|
|
113
|
+
|
|
98
114
|
type SimpleTransform = Exclude<
|
|
99
115
|
TransformName,
|
|
100
|
-
'mangleProperties' | 'pack' | 'renameIdentifiers' | 'specialsToStrings'
|
|
116
|
+
'concealStrings' | 'mangleProperties' | 'pack' | 'renameIdentifiers' | 'specialsToStrings'
|
|
101
117
|
>
|
|
102
118
|
|
|
103
119
|
type TransformsMap = Partial<Record<SimpleTransform, boolean>> & {
|
|
120
|
+
concealStrings?: boolean | ConcealStringsOptions
|
|
104
121
|
mangleProperties?: boolean | ManglePropertiesOptions
|
|
105
122
|
pack?: boolean | PackOptions
|
|
106
123
|
renameIdentifiers?: TransformEntry
|
|
@@ -129,6 +146,7 @@ export interface ObfuscatorOptions {
|
|
|
129
146
|
|
|
130
147
|
// Resolved per-call defaults handed to every transform.
|
|
131
148
|
export interface TransformContext {
|
|
149
|
+
concealStrings?: ConcealStringsOptions
|
|
132
150
|
mangleProperties?: ManglePropertiesOptions
|
|
133
151
|
pack?: PackOptions
|
|
134
152
|
seed: number
|
|
@@ -3,8 +3,6 @@ import type { NodePath, Scope } from '@babel/traverse'
|
|
|
3
3
|
import * as t from '@babel/types'
|
|
4
4
|
import type { File } from '@babel/types'
|
|
5
5
|
|
|
6
|
-
import { enclosingScopeHasDirectEval, isInsideWith } from '../utils/ast'
|
|
7
|
-
|
|
8
6
|
type Kind = t.VariableDeclaration['kind']
|
|
9
7
|
|
|
10
8
|
// Babel 8 omits `AssignmentPattern` from `LVal`, so list these targets directly.
|
|
@@ -18,9 +16,8 @@ type BindingTarget = t.Identifier | t.ObjectPattern | t.ArrayPattern | t.Assignm
|
|
|
18
16
|
* The source, computed keys, and getters keep their original evaluation counts.
|
|
19
17
|
* Defaults compare against `void 0` because `undefined` can be shadowed.
|
|
20
18
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* computed key, matching ObjectBindingPattern evaluation order.
|
|
19
|
+
* The `RequireObjectCoercible` guard runs before computed keys to preserve
|
|
20
|
+
* ObjectBindingPattern evaluation order.
|
|
24
21
|
*
|
|
25
22
|
* @example
|
|
26
23
|
* // ◀️ before
|
|
@@ -42,11 +39,6 @@ const visitor = {
|
|
|
42
39
|
if (typeof path.listKey !== 'string') {
|
|
43
40
|
return
|
|
44
41
|
}
|
|
45
|
-
// Babel cannot prove a generated name hidden from `with` or direct `eval`.
|
|
46
|
-
if (isInsideWith(path) || enclosingScopeHasDirectEval(path)) {
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
42
|
const kind = path.node.kind
|
|
51
43
|
const replacement: t.Statement[] = []
|
|
52
44
|
let changed = false
|
|
@@ -8,10 +8,11 @@ import type { ChangeState } from '../utils/change-tracking'
|
|
|
8
8
|
import { isInStrictContext } from '../utils/paths'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Replaces `arguments[i]` reads with
|
|
12
|
-
* with simple parameter lists.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Replaces numeric `arguments[i]` reads with the corresponding parameter in
|
|
12
|
+
* sloppy functions with simple parameter lists. It leaves a read unchanged when
|
|
13
|
+
* that index is written or its parameter is reassigned. Reassigning, deleting,
|
|
14
|
+
* or passing around `arguments` disables the rewrite. Missing parameters are
|
|
15
|
+
* never added because that would change `fn.length`.
|
|
15
16
|
*
|
|
16
17
|
* @example
|
|
17
18
|
* // ◀️ before
|
|
@@ -2,14 +2,14 @@ import type { NodePath, Visitor } from '@babel/traverse'
|
|
|
2
2
|
import * as t from '@babel/types'
|
|
3
3
|
import type { File } from '@babel/types'
|
|
4
4
|
|
|
5
|
-
import { enclosingScopeHasDirectEval, isInsideWith } from '../utils/ast'
|
|
6
5
|
import { traverseForChanges } from '../utils/change-tracking'
|
|
7
6
|
import type { ChangeState } from '../utils/change-tracking'
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
11
|
-
* that
|
|
12
|
-
*
|
|
9
|
+
* Converts arrows with Babel's capture-aware `arrowFunctionToExpression`.
|
|
10
|
+
* Arrows that use `super` stay unchanged. An arrow also stays unchanged unless
|
|
11
|
+
* every use is an immediate call or a discarded expression, because a normal
|
|
12
|
+
* function can be constructed with `new` and has a `prototype`.
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* // ◀️ before
|
|
@@ -64,11 +64,7 @@ const visitor: Visitor<ChangeState> = {
|
|
|
64
64
|
!valueStaysInView(path) ||
|
|
65
65
|
arrowReferencesSuper(path) ||
|
|
66
66
|
inUnsafeCaptureContext(path) ||
|
|
67
|
-
usesReassignedArguments(path)
|
|
68
|
-
// `with` can shadow capture aliases, and direct eval can inspect the changed
|
|
69
|
-
// runtime meaning of `this` or `arguments`.
|
|
70
|
-
isInsideWith(path) ||
|
|
71
|
-
enclosingScopeHasDirectEval(path)
|
|
67
|
+
usesReassignedArguments(path)
|
|
72
68
|
) {
|
|
73
69
|
return
|
|
74
70
|
}
|
|
@@ -142,7 +138,7 @@ function valueStaysInView(valuePath: NodePath): boolean {
|
|
|
142
138
|
return false
|
|
143
139
|
}
|
|
144
140
|
const binding = valuePath.scope.getBinding(parent.node.id.name)
|
|
145
|
-
if (!binding || !binding.constant) {
|
|
141
|
+
if (!binding || (binding.kind !== 'const' && !binding.constant)) {
|
|
146
142
|
return false
|
|
147
143
|
}
|
|
148
144
|
return binding.referencePaths.every(
|
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
readCrossesFunctionBoundary,
|
|
11
11
|
} from '../analysis/document-order'
|
|
12
12
|
import { isPure } from '../analysis/purity'
|
|
13
|
-
import { isInsideWith } from '../utils/ast'
|
|
14
13
|
import { reorderableToStatement } from '../utils/evaluation-order'
|
|
15
14
|
import { valueToLiteral } from '../utils/literal'
|
|
16
15
|
import { isCalleeOrTagOf } from '../utils/paths'
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Drops single-use temporaries through substitution, direct branch writes, or
|
|
20
|
-
* constant replacement.
|
|
19
|
+
* constant replacement. It repeats these rewrites so one removal can expose
|
|
20
|
+
* another.
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
23
|
* // ◀️ before
|
|
@@ -94,21 +94,9 @@ function resolveSingleUseBinding(path: NodePath<t.VariableDeclarator>): Binding
|
|
|
94
94
|
if (binding.references === 0) {
|
|
95
95
|
return null
|
|
96
96
|
}
|
|
97
|
-
// `with` can redirect the temporary or its consumer outside Babel's scope table.
|
|
98
|
-
if (bindingTouchesWith(binding)) {
|
|
99
|
-
return null
|
|
100
|
-
}
|
|
101
97
|
return binding
|
|
102
98
|
}
|
|
103
99
|
|
|
104
|
-
function bindingTouchesWith(binding: Binding): boolean {
|
|
105
|
-
return (
|
|
106
|
-
isInsideWith(binding.path) ||
|
|
107
|
-
binding.referencePaths.some((ref) => isInsideWith(ref)) ||
|
|
108
|
-
binding.constantViolations.some((violation) => isInsideWith(violation))
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
100
|
function findProgramScope(ast: File): Scope | undefined {
|
|
113
101
|
let result: Scope | undefined
|
|
114
102
|
traverse(ast, {
|
|
@@ -145,7 +133,7 @@ function trySubstituteSingleUse(
|
|
|
145
133
|
let removeWriteStmt: boolean
|
|
146
134
|
|
|
147
135
|
if (init) {
|
|
148
|
-
if (binding.constantViolations.length > 0) {
|
|
136
|
+
if (binding.kind !== 'const' && binding.constantViolations.length > 0) {
|
|
149
137
|
return false
|
|
150
138
|
}
|
|
151
139
|
writeStmt = declStmt
|
|
@@ -333,8 +321,9 @@ function tryRenameWritesToReader(
|
|
|
333
321
|
return false
|
|
334
322
|
}
|
|
335
323
|
|
|
336
|
-
//
|
|
337
|
-
|
|
324
|
+
// A later `var` initializer can overwrite a redirected write. Writes before
|
|
325
|
+
// lexical initialization are intentionally ignored.
|
|
326
|
+
if (yBinding.kind === 'var' && !declarationReaches(yBinding.path, violation)) {
|
|
338
327
|
return false
|
|
339
328
|
}
|
|
340
329
|
}
|
|
@@ -662,7 +651,7 @@ function spanStatementIsInert(path: NodePath, tempBinding: Binding): boolean {
|
|
|
662
651
|
}
|
|
663
652
|
if (t.isIfStatement(node)) {
|
|
664
653
|
const test = path.get('test') as NodePath
|
|
665
|
-
if (!isPure(test.node, test.scope
|
|
654
|
+
if (!isPure(test.node, test.scope)) {
|
|
666
655
|
return false
|
|
667
656
|
}
|
|
668
657
|
if (!spanStatementIsInert(path.get('consequent') as NodePath, tempBinding)) {
|
|
@@ -675,9 +664,9 @@ function spanStatementIsInert(path: NodePath, tempBinding: Binding): boolean {
|
|
|
675
664
|
const expr = path.get('expression') as NodePath
|
|
676
665
|
if (isTempWrite(expr.node, tempBinding)) {
|
|
677
666
|
const rhs = expr.get('right') as NodePath
|
|
678
|
-
return isPure(rhs.node, rhs.scope
|
|
667
|
+
return isPure(rhs.node, rhs.scope)
|
|
679
668
|
}
|
|
680
|
-
return isPure(expr.node, expr.scope
|
|
669
|
+
return isPure(expr.node, expr.scope)
|
|
681
670
|
}
|
|
682
671
|
return false
|
|
683
672
|
}
|
|
@@ -723,7 +712,7 @@ function tryPropagateConstant(
|
|
|
723
712
|
let writeSourcePath: NodePath
|
|
724
713
|
|
|
725
714
|
if (init) {
|
|
726
|
-
if (binding.constantViolations.length > 0) {
|
|
715
|
+
if (binding.kind !== 'const' && binding.constantViolations.length > 0) {
|
|
727
716
|
return false
|
|
728
717
|
}
|
|
729
718
|
if (!isUnconditionallyExecuted(declStmt, declaratorPath.scope)) {
|
|
@@ -890,10 +879,10 @@ function isStatementMovementSafe(path: NodePath): boolean {
|
|
|
890
879
|
if (t.isEmptyStatement(node)) {
|
|
891
880
|
return true
|
|
892
881
|
}
|
|
893
|
-
//
|
|
882
|
+
// Only inert expression statements are safe to cross.
|
|
894
883
|
if (t.isExpressionStatement(node)) {
|
|
895
884
|
const expr = path.get('expression') as NodePath
|
|
896
|
-
return isPure(expr.node, expr.scope
|
|
885
|
+
return isPure(expr.node, expr.scope)
|
|
897
886
|
}
|
|
898
887
|
return false
|
|
899
888
|
}
|