mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge pull request #280 from javascript-obfuscator/block-statement-instead-transformer-identifier
Block statement instead transformer identifier
This commit is contained in:
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -126,7 +126,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
*/
|
||||
public obfuscate (sourceCode: string): IObfuscationResult {
|
||||
const timeStart: number = Date.now();
|
||||
this.logger.info(LoggingMessage.Version, '0.16.0');
|
||||
this.logger.info(LoggingMessage.Version, process.env.VERSION);
|
||||
this.logger.info(LoggingMessage.ObfuscationStarted);
|
||||
this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getSeed());
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ export class StackTraceAnalyzer implements IStackTraceAnalyzer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (blockScopeBodyNode.parentNode !== NodeUtils.getBlockScopesOfNode(node)[0]) {
|
||||
if (blockScopeBodyNode.parentNode !== NodeUtils.getBlockScopeOfNode(node)) {
|
||||
return estraverse.VisitorOption.Skip;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataEx
|
||||
}
|
||||
|
||||
const calleeBlockStatement: ESTree.BlockStatement | null = this.getCalleeBlockStatement(
|
||||
NodeUtils.getBlockScopesOfNode(blockScopeBody[0])[0],
|
||||
NodeUtils.getBlockScopeOfNode(blockScopeBody[0]),
|
||||
callee.name
|
||||
);
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExt
|
||||
|
||||
if (NodeGuards.isIdentifierNode(callee)) {
|
||||
calleeBlockStatement = this.getCalleeBlockStatement(
|
||||
NodeUtils.getBlockScopesOfNode(blockScopeBody[0])[0],
|
||||
NodeUtils.getBlockScopeOfNode(blockScopeBody[0]),
|
||||
callee.name
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtra
|
||||
|
||||
const functionExpressionName: string | number | null = objectMembersCallsChain[objectMembersCallsChain.length - 1];
|
||||
const calleeBlockStatement: ESTree.BlockStatement | null = this.getCalleeBlockStatement(
|
||||
NodeUtils.getBlockScopesOfNode(blockScopeBody[0])[0],
|
||||
NodeUtils.getBlockScopeOfNode(blockScopeBody[0]),
|
||||
objectMembersCallsChain
|
||||
);
|
||||
|
||||
|
||||
+6
-4
@@ -1,17 +1,19 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../../../../types/node/TNodeWithBlockScope';
|
||||
|
||||
import { IObfuscatingReplacer } from './IObfuscatingReplacer';
|
||||
|
||||
export interface IIdentifierObfuscatingReplacer extends IObfuscatingReplacer <ESTree.Identifier> {
|
||||
/**
|
||||
* @param {string} nodeValue
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
storeGlobalName (nodeValue: string, nodeIdentifier: number): void;
|
||||
storeGlobalName (nodeValue: string, blockScopeNode: TNodeWithBlockScope): void;
|
||||
|
||||
/**
|
||||
* @param {string} nodeValue
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
storeLocalName (nodeValue: string, nodeIdentifier: number): void;
|
||||
storeLocalName (nodeValue: string, blockScopeNode: TNodeWithBlockScope): void;
|
||||
}
|
||||
|
||||
+5
-2
@@ -1,10 +1,13 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../../../../types/node/TNodeWithBlockScope';
|
||||
|
||||
export interface IObfuscatingReplacer <T = ESTree.Node> {
|
||||
/**
|
||||
* @param {SimpleLiteral['value']} nodeValue
|
||||
* @param {SimpleLiteral["value"]} nodeValue
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @returns {T}
|
||||
*/
|
||||
replace (nodeValue: ESTree.SimpleLiteral['value'], nodeIdentifier?: number): T;
|
||||
replace (nodeValue: ESTree.SimpleLiteral['value'], blockScopeNode?: TNodeWithBlockScope, nodeIdentifier?: number): T;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,18 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
|
||||
|
||||
import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { IInitializable } from '../interfaces/IInitializable';
|
||||
import { INodeTransformer } from '../interfaces/node-transformers/INodeTransformer';
|
||||
import { IOptions } from '../interfaces/options/IOptions';
|
||||
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
|
||||
import { IVisitor } from '../interfaces/node-transformers/IVisitor';
|
||||
|
||||
import { initializable } from '../decorators/Initializable';
|
||||
|
||||
import { TransformationStage } from '../enums/node-transformers/TransformationStage';
|
||||
|
||||
@injectable()
|
||||
export abstract class AbstractNodeTransformer implements INodeTransformer, IInitializable {
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
@initializable()
|
||||
protected nodeIdentifier!: number;
|
||||
|
||||
export abstract class AbstractNodeTransformer implements INodeTransformer {
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
@@ -44,11 +35,6 @@ export abstract class AbstractNodeTransformer implements INodeTransformer, IInit
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
public initialize (): void {
|
||||
this.nodeIdentifier = this.randomGenerator.getRandomInteger(0, 10000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TransformationStage} transformationStage
|
||||
* @returns {IVisitor | null}
|
||||
|
||||
+2
-2
@@ -205,7 +205,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
const blockScopeOfBlockStatementNode: TNodeWithBlockScope = NodeUtils
|
||||
.getBlockScopesOfNode(blockStatementNode)[0];
|
||||
.getBlockScopeOfNode(blockStatementNode);
|
||||
|
||||
return blockScopeOfBlockStatementNode.type !== NodeType.Program;
|
||||
}
|
||||
@@ -345,7 +345,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
* @param {BlockStatement} clonedBlockStatementNode
|
||||
* @returns {BlockStatement}
|
||||
*/
|
||||
private makeClonedBlockStatementNodeUnique(clonedBlockStatementNode: ESTree.BlockStatement): ESTree.BlockStatement {
|
||||
private makeClonedBlockStatementNodeUnique (clonedBlockStatementNode: ESTree.BlockStatement): ESTree.BlockStatement {
|
||||
return this.transformersRunner.transform(
|
||||
clonedBlockStatementNode,
|
||||
DeadCodeInjectionTransformer.transformersToRenameBlockScopeIdentifiers,
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
|
||||
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -17,6 +18,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -77,34 +79,40 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (catchClauseNode: ESTree.CatchClause, parentNode: ESTree.Node): ESTree.Node {
|
||||
const nodeIdentifier: number = this.nodeIdentifier++;
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(catchClauseNode);
|
||||
|
||||
this.storeCatchClauseParam(catchClauseNode, nodeIdentifier);
|
||||
this.replaceCatchClauseParam(catchClauseNode, nodeIdentifier);
|
||||
this.storeCatchClauseParam(catchClauseNode, blockScopeNode);
|
||||
this.replaceCatchClauseParam(catchClauseNode, blockScopeNode);
|
||||
|
||||
return catchClauseNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CatchClause} catchClauseNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause, nodeIdentifier: number): void {
|
||||
private storeCatchClauseParam (
|
||||
catchClauseNode: ESTree.CatchClause,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
): void {
|
||||
if (NodeGuards.isIdentifierNode(catchClauseNode.param)) {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(catchClauseNode.param.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(catchClauseNode.param.name, blockScopeNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CatchClause} catchClauseNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private replaceCatchClauseParam (catchClauseNode: ESTree.CatchClause, nodeIdentifier: number): void {
|
||||
private replaceCatchClauseParam (
|
||||
catchClauseNode: ESTree.CatchClause,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
): void {
|
||||
estraverse.replace(catchClauseNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (parentNode && NodeGuards.isReplaceableIdentifierNode(node, parentNode)) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, nodeIdentifier);
|
||||
.replace(node.name, blockScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
|
||||
@@ -90,21 +90,20 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (classDeclarationNode: ESTree.ClassDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const nodeIdentifier: number = this.nodeIdentifier++;
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(classDeclarationNode)[0];
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(classDeclarationNode);
|
||||
const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
|
||||
|
||||
if (!this.options.renameGlobals && isGlobalDeclaration) {
|
||||
return classDeclarationNode;
|
||||
}
|
||||
|
||||
this.storeClassName(classDeclarationNode, isGlobalDeclaration, nodeIdentifier);
|
||||
this.storeClassName(classDeclarationNode, blockScopeNode, isGlobalDeclaration);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(blockScopeNode, nodeIdentifier);
|
||||
this.replaceScopeCachedIdentifiers(blockScopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(blockScopeNode, nodeIdentifier);
|
||||
this.replaceScopeIdentifiers(blockScopeNode);
|
||||
}
|
||||
|
||||
return classDeclarationNode;
|
||||
@@ -112,31 +111,31 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {ClassDeclaration} classDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private storeClassName (
|
||||
classDeclarationNode: ESTree.ClassDeclaration,
|
||||
isGlobalDeclaration: boolean,
|
||||
nodeIdentifier: number
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
isGlobalDeclaration: boolean
|
||||
): void {
|
||||
if (isGlobalDeclaration) {
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(classDeclarationNode.id.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(classDeclarationNode.id.name, blockScopeNode);
|
||||
} else {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(classDeclarationNode.id.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(classDeclarationNode.id.name, blockScopeNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (blockScopeNode: TNodeWithBlockScope, nodeIdentifier: number): void {
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] = <ESTree.Identifier[]>this.replaceableIdentifiers.get(blockScopeNode);
|
||||
private replaceScopeCachedIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] =
|
||||
<ESTree.Identifier[]>this.replaceableIdentifiers.get(blockScopeNode);
|
||||
|
||||
cachedReplaceableIdentifiers.forEach((replaceableIdentifier: ESTree.Identifier) => {
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, nodeIdentifier);
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -145,9 +144,8 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope, nodeIdentifier: number): void {
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
const storedReplaceableIdentifiers: ESTree.Identifier[] = [];
|
||||
|
||||
estraverse.replace(blockScopeNode, {
|
||||
@@ -158,7 +156,7 @@ export class ClassDeclarationTransformer extends AbstractNodeTransformer {
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, nodeIdentifier);
|
||||
.replace(node.name, blockScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
|
||||
@@ -92,21 +92,20 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const nodeIdentifier: number = this.nodeIdentifier++;
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(functionDeclarationNode)[0];
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(functionDeclarationNode);
|
||||
const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
|
||||
|
||||
if (!this.options.renameGlobals && isGlobalDeclaration) {
|
||||
return functionDeclarationNode;
|
||||
}
|
||||
|
||||
this.storeFunctionName(functionDeclarationNode, isGlobalDeclaration, nodeIdentifier);
|
||||
this.storeFunctionName(functionDeclarationNode, blockScopeNode, isGlobalDeclaration);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(functionDeclarationNode, blockScopeNode, nodeIdentifier);
|
||||
this.replaceScopeCachedIdentifiers(functionDeclarationNode, blockScopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(blockScopeNode, nodeIdentifier);
|
||||
this.replaceScopeIdentifiers(blockScopeNode);
|
||||
}
|
||||
|
||||
return functionDeclarationNode;
|
||||
@@ -114,32 +113,31 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {FunctionDeclaration} functionDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private storeFunctionName (
|
||||
functionDeclarationNode: ESTree.FunctionDeclaration,
|
||||
isGlobalDeclaration: boolean,
|
||||
nodeIdentifier: number
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
isGlobalDeclaration: boolean
|
||||
): void {
|
||||
if (isGlobalDeclaration) {
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(functionDeclarationNode.id.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(functionDeclarationNode.id.name, blockScopeNode);
|
||||
} else {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(functionDeclarationNode.id.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(functionDeclarationNode.id.name, blockScopeNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FunctionDeclaration} functionDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (
|
||||
functionDeclarationNode: ESTree.FunctionDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
nodeIdentifier: number
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
): void {
|
||||
const cachedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames | undefined = this.replaceableIdentifiers.get(blockScopeNode);
|
||||
const cachedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames | undefined =
|
||||
this.replaceableIdentifiers.get(blockScopeNode);
|
||||
|
||||
if (!cachedReplaceableIdentifiersNamesMap) {
|
||||
return;
|
||||
@@ -157,7 +155,7 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
for (let i: number = 0; i < cachedReplaceableIdentifierLength; i++) {
|
||||
const replaceableIdentifier: ESTree.Identifier = cachedReplaceableIdentifiers[i];
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, nodeIdentifier);
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -166,9 +164,8 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope, nodeIdentifier: number): void {
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
const storedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames = new Map();
|
||||
|
||||
estraverse.replace(blockScopeNode, {
|
||||
@@ -179,14 +176,15 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, nodeIdentifier);
|
||||
.replace(node.name, blockScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
node.name = newIdentifierName;
|
||||
NodeMetadata.set(node, { renamedIdentifier: true });
|
||||
} else {
|
||||
const storedReplaceableIdentifiers: ESTree.Identifier[] = storedReplaceableIdentifiersNamesMap.get(node.name) || [];
|
||||
const storedReplaceableIdentifiers: ESTree.Identifier[] =
|
||||
storedReplaceableIdentifiersNamesMap.get(node.name) || [];
|
||||
|
||||
storedReplaceableIdentifiers.push(node);
|
||||
storedReplaceableIdentifiersNamesMap.set(node.name, storedReplaceableIdentifiers);
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as estraverse from 'estraverse';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
|
||||
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
@@ -17,6 +18,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { NodeMetadata } from '../../node/NodeMetadata';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -83,19 +85,21 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (functionNode: ESTree.Function, parentNode: ESTree.Node): ESTree.Node {
|
||||
const nodeIdentifier: number = this.nodeIdentifier++;
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeGuards.isBlockStatementNode(functionNode.body)
|
||||
? functionNode.body
|
||||
: NodeUtils.getBlockScopeOfNode(functionNode.body);
|
||||
|
||||
this.storeFunctionParams(functionNode, nodeIdentifier);
|
||||
this.replaceFunctionParams(functionNode, nodeIdentifier);
|
||||
this.storeFunctionParams(functionNode, blockScopeNode);
|
||||
this.replaceFunctionParams(functionNode, blockScopeNode);
|
||||
|
||||
return functionNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} functionNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private storeFunctionParams (functionNode: ESTree.Function, nodeIdentifier: number): void {
|
||||
private storeFunctionParams (functionNode: ESTree.Function, blockScopeNode: TNodeWithBlockScope): void {
|
||||
functionNode.params
|
||||
.forEach((paramsNode: ESTree.Node) => {
|
||||
estraverse.traverse(paramsNode, {
|
||||
@@ -105,13 +109,13 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
if (NodeGuards.isAssignmentPatternNode(node) && NodeGuards.isIdentifierNode(node.left)) {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.left.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.left.name, blockScopeNode);
|
||||
|
||||
return estraverse.VisitorOption.Skip;
|
||||
}
|
||||
|
||||
if (NodeGuards.isIdentifierNode(node)) {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(node.name, blockScopeNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -137,9 +141,9 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {Function} functionNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private replaceFunctionParams (functionNode: ESTree.Function, nodeIdentifier: number): void {
|
||||
private replaceFunctionParams (functionNode: ESTree.Function, blockScopeNode: TNodeWithBlockScope): void {
|
||||
const ignoredIdentifierNamesSet: Set<string> = new Set();
|
||||
|
||||
const replaceVisitor: estraverse.Visitor = {
|
||||
@@ -153,7 +157,8 @@ export class FunctionTransformer extends AbstractNodeTransformer {
|
||||
NodeGuards.isReplaceableIdentifierNode(node, parentNode) &&
|
||||
!ignoredIdentifierNamesSet.has(node.name)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer.replace(node.name, nodeIdentifier);
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
|
||||
@@ -95,45 +95,47 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {Node}
|
||||
*/
|
||||
public transformNode (importDeclarationNode: ESTree.ImportDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const nodeIdentifier: number = this.nodeIdentifier++;
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(importDeclarationNode)[0];
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(importDeclarationNode);
|
||||
|
||||
this.storeImportSpecifierNames(importDeclarationNode, nodeIdentifier);
|
||||
this.storeImportSpecifierNames(importDeclarationNode, blockScopeNode);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(blockScopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(blockScopeNode, nodeIdentifier);
|
||||
this.replaceScopeCachedIdentifiers(blockScopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(blockScopeNode, nodeIdentifier);
|
||||
this.replaceScopeIdentifiers(blockScopeNode);
|
||||
}
|
||||
|
||||
return importDeclarationNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ImportDefaultSpecifier | ImportNamespaceSpecifier} importDeclarationNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {ImportDeclaration} importDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private storeImportSpecifierNames (importDeclarationNode: ESTree.ImportDeclaration, nodeIdentifier: number): void {
|
||||
private storeImportSpecifierNames (
|
||||
importDeclarationNode: ESTree.ImportDeclaration,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
): void {
|
||||
importDeclarationNode.specifiers.forEach((importSpecifierNode: TImportSpecifier) => {
|
||||
if (ImportDeclarationTransformer.isProhibitedImportSpecifierNode(importSpecifierNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(importSpecifierNode.local.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(importSpecifierNode.local.name, blockScopeNode);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (blockScopeNode: TNodeWithBlockScope, nodeIdentifier: number): void {
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] = <ESTree.Identifier[]>this.replaceableIdentifiers.get(blockScopeNode);
|
||||
private replaceScopeCachedIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] =
|
||||
<ESTree.Identifier[]>this.replaceableIdentifiers.get(blockScopeNode);
|
||||
|
||||
cachedReplaceableIdentifiers.forEach((replaceableIdentifier: ESTree.Identifier) => {
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, nodeIdentifier);
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -142,9 +144,8 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope, nodeIdentifier: number): void {
|
||||
private replaceScopeIdentifiers (blockScopeNode: TNodeWithBlockScope): void {
|
||||
const storedReplaceableIdentifiers: ESTree.Identifier[] = [];
|
||||
|
||||
estraverse.replace(blockScopeNode, {
|
||||
@@ -155,7 +156,7 @@ export class ImportDeclarationTransformer extends AbstractNodeTransformer {
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, nodeIdentifier);
|
||||
.replace(node.name, blockScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
|
||||
@@ -16,6 +16,8 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
/**
|
||||
* replaces:
|
||||
@@ -84,32 +86,38 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (labeledStatementNode: ESTree.LabeledStatement, parentNode: ESTree.Node): ESTree.Node {
|
||||
const nodeIdentifier: number = this.nodeIdentifier++;
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(labeledStatementNode);
|
||||
|
||||
this.storeLabeledStatementName(labeledStatementNode, nodeIdentifier);
|
||||
this.replaceLabeledStatementName(labeledStatementNode, nodeIdentifier);
|
||||
this.storeLabeledStatementName(labeledStatementNode, blockScopeNode);
|
||||
this.replaceLabeledStatementName(labeledStatementNode, blockScopeNode);
|
||||
|
||||
return labeledStatementNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LabeledStatement} labeledStatementNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement, nodeIdentifier: number): void {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(labeledStatementNode.label.name, nodeIdentifier);
|
||||
private storeLabeledStatementName (
|
||||
labeledStatementNode: ESTree.LabeledStatement,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
): void {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(labeledStatementNode.label.name, blockScopeNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LabeledStatement} labeledStatementNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private replaceLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement, nodeIdentifier: number): void {
|
||||
private replaceLabeledStatementName (
|
||||
labeledStatementNode: ESTree.LabeledStatement,
|
||||
blockScopeNode: TNodeWithBlockScope
|
||||
): void {
|
||||
estraverse.replace(labeledStatementNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (parentNode && NodeGuards.isLabelIdentifierNode(node, parentNode)) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, nodeIdentifier);
|
||||
.replace(node.name, blockScopeNode);
|
||||
|
||||
node.name = newIdentifier.name;
|
||||
}
|
||||
|
||||
@@ -93,25 +93,24 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
* @returns {NodeGuards}
|
||||
*/
|
||||
public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): ESTree.Node {
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopesOfNode(variableDeclarationNode)[0];
|
||||
const blockScopeNode: TNodeWithBlockScope = NodeUtils.getBlockScopeOfNode(variableDeclarationNode);
|
||||
const isGlobalDeclaration: boolean = blockScopeNode.type === NodeType.Program;
|
||||
|
||||
if (!this.options.renameGlobals && isGlobalDeclaration) {
|
||||
return variableDeclarationNode;
|
||||
}
|
||||
|
||||
const nodeIdentifier: number = this.nodeIdentifier++;
|
||||
const scopeNode: ESTree.Node = variableDeclarationNode.kind === 'var'
|
||||
? blockScopeNode
|
||||
: parentNode;
|
||||
|
||||
this.storeVariableNames(variableDeclarationNode, isGlobalDeclaration, nodeIdentifier);
|
||||
this.storeVariableNames(variableDeclarationNode, blockScopeNode, isGlobalDeclaration);
|
||||
|
||||
// check for cached identifiers for current scope node. If exist - loop through them.
|
||||
if (this.replaceableIdentifiers.has(scopeNode)) {
|
||||
this.replaceScopeCachedIdentifiers(variableDeclarationNode, scopeNode, nodeIdentifier);
|
||||
this.replaceScopeCachedIdentifiers(variableDeclarationNode, blockScopeNode, scopeNode);
|
||||
} else {
|
||||
this.replaceScopeIdentifiers(scopeNode, nodeIdentifier);
|
||||
this.replaceScopeIdentifiers(scopeNode, blockScopeNode);
|
||||
}
|
||||
|
||||
return variableDeclarationNode;
|
||||
@@ -119,34 +118,35 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
|
||||
/**
|
||||
* @param {VariableDeclaration} variableDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {boolean} isGlobalDeclaration
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private storeVariableNames (
|
||||
variableDeclarationNode: ESTree.VariableDeclaration,
|
||||
isGlobalDeclaration: boolean,
|
||||
nodeIdentifier: number
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
isGlobalDeclaration: boolean
|
||||
): void {
|
||||
this.traverseDeclarationIdentifiers(variableDeclarationNode, (identifierNode: ESTree.Identifier) => {
|
||||
if (isGlobalDeclaration) {
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(identifierNode.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeGlobalName(identifierNode.name, blockScopeNode);
|
||||
} else {
|
||||
this.identifierObfuscatingReplacer.storeLocalName(identifierNode.name, nodeIdentifier);
|
||||
this.identifierObfuscatingReplacer.storeLocalName(identifierNode.name, blockScopeNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {VariableDeclaration} variableDeclarationNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {Node} scopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
*/
|
||||
private replaceScopeCachedIdentifiers (
|
||||
variableDeclarationNode: ESTree.VariableDeclaration,
|
||||
scopeNode: ESTree.Node,
|
||||
nodeIdentifier: number
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
scopeNode: ESTree.Node
|
||||
): void {
|
||||
const cachedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames | undefined = this.replaceableIdentifiers.get(scopeNode);
|
||||
const cachedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames | undefined =
|
||||
this.replaceableIdentifiers.get(scopeNode);
|
||||
|
||||
if (!cachedReplaceableIdentifiersNamesMap) {
|
||||
return;
|
||||
@@ -159,7 +159,8 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
});
|
||||
|
||||
identifierNames.forEach((identifierName: string) => {
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] | undefined = cachedReplaceableIdentifiersNamesMap.get(identifierName);
|
||||
const cachedReplaceableIdentifiers: ESTree.Identifier[] | undefined =
|
||||
cachedReplaceableIdentifiersNamesMap.get(identifierName);
|
||||
|
||||
if (!cachedReplaceableIdentifiers) {
|
||||
return;
|
||||
@@ -175,7 +176,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
const newReplaceableIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(replaceableIdentifier.name, nodeIdentifier);
|
||||
.replace(replaceableIdentifier.name, blockScopeNode);
|
||||
|
||||
replaceableIdentifier.name = newReplaceableIdentifier.name;
|
||||
NodeMetadata.set(replaceableIdentifier, { renamedIdentifier: true });
|
||||
@@ -184,27 +185,29 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeGuards} blockScopeNode
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {Node} scopeNode
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
private replaceScopeIdentifiers (blockScopeNode: ESTree.Node, nodeIdentifier: number): void {
|
||||
private replaceScopeIdentifiers (scopeNode: ESTree.Node, blockScopeNode: TNodeWithBlockScope): void {
|
||||
const storedReplaceableIdentifiersNamesMap: TReplaceableIdentifiersNames = new Map();
|
||||
|
||||
estraverse.replace(blockScopeNode, {
|
||||
estraverse.replace(scopeNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
|
||||
if (
|
||||
parentNode
|
||||
&& NodeGuards.isReplaceableIdentifierNode(node, parentNode)
|
||||
&& !NodeMetadata.isRenamedIdentifier(node)
|
||||
) {
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer.replace(node.name, nodeIdentifier);
|
||||
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
|
||||
.replace(node.name, blockScopeNode);
|
||||
const newIdentifierName: string = newIdentifier.name;
|
||||
|
||||
if (node.name !== newIdentifierName) {
|
||||
node.name = newIdentifierName;
|
||||
NodeMetadata.set(node, { renamedIdentifier: true });
|
||||
} else {
|
||||
const storedReplaceableIdentifiers: ESTree.Identifier[] = storedReplaceableIdentifiersNamesMap.get(node.name) || [];
|
||||
const storedReplaceableIdentifiers: ESTree.Identifier[] =
|
||||
storedReplaceableIdentifiersNamesMap.get(node.name) || [];
|
||||
|
||||
storedReplaceableIdentifiers.push(node);
|
||||
storedReplaceableIdentifiersNamesMap.set(node.name, storedReplaceableIdentifiers);
|
||||
@@ -213,7 +216,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
});
|
||||
|
||||
this.replaceableIdentifiers.set(blockScopeNode, storedReplaceableIdentifiersNamesMap);
|
||||
this.replaceableIdentifiers.set(scopeNode, storedReplaceableIdentifiersNamesMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
-3
@@ -3,6 +3,8 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TNodeWithBlockScope } from '../../../types/node/TNodeWithBlockScope';
|
||||
|
||||
import { IObfuscatingReplacer } from '../../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IObfuscatingReplacer';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
|
||||
@@ -23,9 +25,9 @@ export abstract class AbstractObfuscatingReplacer implements IObfuscatingReplace
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SimpleLiteral['value']} nodeValue
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {SimpleLiteral["value"]} nodeValue
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @returns {Node}
|
||||
*/
|
||||
public abstract replace (nodeValue: ESTree.SimpleLiteral['value'], nodeIdentifier?: number): ESTree.Node;
|
||||
public abstract replace (nodeValue: ESTree.SimpleLiteral['value'], blockScopeNode?: TNodeWithBlockScope): ESTree.Node;
|
||||
}
|
||||
|
||||
+28
-13
@@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../../../container/ServiceIdentifiers';
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
import { TNodeWithBlockScope } from '../../../../types/node/TNodeWithBlockScope';
|
||||
|
||||
import { IIdentifierNamesGenerator } from '../../../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
|
||||
import { IIdentifierObfuscatingReplacer } from '../../../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
|
||||
@@ -20,9 +21,9 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
private readonly identifierNamesGenerator: IIdentifierNamesGenerator;
|
||||
|
||||
/**
|
||||
* @type {Map<string, string>}
|
||||
* @type {Map<TNodeWithBlockScope, Map<string, string>>}
|
||||
*/
|
||||
private readonly namesMap: Map<string, string> = new Map();
|
||||
private readonly blockScopesMap: Map<TNodeWithBlockScope, Map<string, string>> = new Map();
|
||||
|
||||
/**
|
||||
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
|
||||
@@ -40,14 +41,16 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
|
||||
/**
|
||||
* @param {string} nodeValue
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @returns {Identifier}
|
||||
*/
|
||||
public replace (nodeValue: string, nodeIdentifier: number): ESTree.Identifier {
|
||||
const mapKey: string = `${nodeValue}-${String(nodeIdentifier)}`;
|
||||
public replace (nodeValue: string, blockScopeNode: TNodeWithBlockScope): ESTree.Identifier {
|
||||
if (this.blockScopesMap.has(blockScopeNode)) {
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(blockScopeNode);
|
||||
|
||||
if (this.namesMap.has(mapKey)) {
|
||||
nodeValue = <string>this.namesMap.get(mapKey);
|
||||
if (namesMap.has(nodeValue)) {
|
||||
nodeValue = <string>namesMap.get(nodeValue);
|
||||
}
|
||||
}
|
||||
|
||||
return NodeFactory.identifierNode(nodeValue);
|
||||
@@ -58,16 +61,22 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
* Reserved name will be ignored.
|
||||
*
|
||||
* @param {string} nodeName
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
public storeGlobalName (nodeName: string, nodeIdentifier: number): void {
|
||||
public storeGlobalName (nodeName: string, blockScopeNode: TNodeWithBlockScope): void {
|
||||
if (this.isReservedName(nodeName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const identifierName: string = this.identifierNamesGenerator.generateWithPrefix();
|
||||
|
||||
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, identifierName);
|
||||
if (!this.blockScopesMap.has(blockScopeNode)) {
|
||||
this.blockScopesMap.set(blockScopeNode, new Map());
|
||||
}
|
||||
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(blockScopeNode);
|
||||
|
||||
namesMap.set(nodeName, identifierName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,16 +84,22 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
|
||||
* Reserved name will be ignored.
|
||||
*
|
||||
* @param {string} nodeName
|
||||
* @param {number} nodeIdentifier
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
*/
|
||||
public storeLocalName (nodeName: string, nodeIdentifier: number): void {
|
||||
public storeLocalName (nodeName: string, blockScopeNode: TNodeWithBlockScope): void {
|
||||
if (this.isReservedName(nodeName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const identifierName: string = this.identifierNamesGenerator.generate();
|
||||
|
||||
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, identifierName);
|
||||
if (!this.blockScopesMap.has(blockScopeNode)) {
|
||||
this.blockScopesMap.set(blockScopeNode, new Map());
|
||||
}
|
||||
|
||||
const namesMap: Map<string, string> = <Map<string, string>>this.blockScopesMap.get(blockScopeNode);
|
||||
|
||||
namesMap.set(nodeName, identifierName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+16
-2
@@ -69,6 +69,14 @@ export class NodeUtils {
|
||||
}, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithBlockScope}
|
||||
*/
|
||||
public static getBlockScopeOfNode (node: ESTree.Node): TNodeWithBlockScope {
|
||||
return NodeUtils.getBlockScopesOfNodeRecursive(node, 1)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {TNodeWithBlockScope[]}
|
||||
@@ -206,17 +214,23 @@ export class NodeUtils {
|
||||
return <T>copy;
|
||||
}
|
||||
|
||||
/**
|
||||
/***
|
||||
* @param {Node} node
|
||||
* @param {number} maxSize
|
||||
* @param {TNodeWithBlockScope[]} blockScopes
|
||||
* @param {number} depth
|
||||
* @returns {TNodeWithBlockScope[]}
|
||||
*/
|
||||
private static getBlockScopesOfNodeRecursive (
|
||||
node: ESTree.Node,
|
||||
maxSize: number = Infinity,
|
||||
blockScopes: TNodeWithBlockScope[] = [],
|
||||
depth: number = 0
|
||||
): TNodeWithBlockScope[] {
|
||||
if (blockScopes.length >= maxSize) {
|
||||
return blockScopes;
|
||||
}
|
||||
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
@@ -248,7 +262,7 @@ export class NodeUtils {
|
||||
}
|
||||
|
||||
if (node !== parentNode) {
|
||||
return NodeUtils.getBlockScopesOfNodeRecursive(parentNode, blockScopes, ++depth);
|
||||
return NodeUtils.getBlockScopesOfNodeRecursive(parentNode, maxSize, blockScopes, ++depth);
|
||||
}
|
||||
|
||||
return blockScopes;
|
||||
|
||||
@@ -181,6 +181,101 @@ describe('NodeUtils', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getBlockScopeOfNode', () => {
|
||||
let functionDeclarationBlockStatementNode: ESTree.BlockStatement,
|
||||
ifStatementBlockStatementNode1: ESTree.BlockStatement,
|
||||
ifStatementBlockStatementNode2: ESTree.BlockStatement,
|
||||
ifStatementNode1: ESTree.IfStatement,
|
||||
ifStatementNode2: ESTree.IfStatement,
|
||||
expressionStatementNode3: ESTree.ExpressionStatement,
|
||||
expressionStatementNode2: ESTree.ExpressionStatement,
|
||||
expressionStatementNode1: ESTree.ExpressionStatement,
|
||||
functionDeclarationNode: ESTree.FunctionDeclaration,
|
||||
programNode: ESTree.Program;
|
||||
|
||||
before(() => {
|
||||
expressionStatementNode1 = NodeFactory.expressionStatementNode(NodeFactory.identifierNode('identifier'));
|
||||
expressionStatementNode2 = NodeFactory.expressionStatementNode(NodeFactory.identifierNode('identifier'));
|
||||
expressionStatementNode3 = NodeFactory.expressionStatementNode(NodeFactory.identifierNode('identifier'));
|
||||
|
||||
ifStatementBlockStatementNode2 = NodeFactory.blockStatementNode([
|
||||
expressionStatementNode2,
|
||||
expressionStatementNode3
|
||||
]);
|
||||
|
||||
ifStatementNode2 = NodeFactory.ifStatementNode(
|
||||
NodeFactory.literalNode(true),
|
||||
ifStatementBlockStatementNode2
|
||||
);
|
||||
|
||||
ifStatementBlockStatementNode1 = NodeFactory.blockStatementNode([
|
||||
ifStatementNode2
|
||||
]);
|
||||
|
||||
ifStatementNode1 = NodeFactory.ifStatementNode(
|
||||
NodeFactory.literalNode(true),
|
||||
ifStatementBlockStatementNode1
|
||||
);
|
||||
|
||||
functionDeclarationBlockStatementNode = NodeFactory.blockStatementNode([
|
||||
expressionStatementNode1,
|
||||
ifStatementNode1
|
||||
]);
|
||||
|
||||
functionDeclarationNode = NodeFactory.functionDeclarationNode('test', [], functionDeclarationBlockStatementNode);
|
||||
|
||||
programNode = NodeFactory.programNode([
|
||||
functionDeclarationNode
|
||||
]);
|
||||
|
||||
programNode.parentNode = programNode;
|
||||
functionDeclarationNode.parentNode = programNode;
|
||||
functionDeclarationBlockStatementNode.parentNode = functionDeclarationNode;
|
||||
expressionStatementNode1.parentNode = functionDeclarationBlockStatementNode;
|
||||
ifStatementNode1.parentNode = functionDeclarationBlockStatementNode;
|
||||
ifStatementBlockStatementNode1.parentNode = ifStatementNode1;
|
||||
ifStatementNode2.parentNode = ifStatementBlockStatementNode1;
|
||||
ifStatementBlockStatementNode2.parentNode = ifStatementNode2;
|
||||
expressionStatementNode3.parentNode = ifStatementBlockStatementNode2;
|
||||
});
|
||||
|
||||
it('should return block-scope node for `program` node child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(programNode), programNode);
|
||||
});
|
||||
|
||||
it('should return block-scope node for `functionDeclaration` node child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(functionDeclarationNode), programNode);
|
||||
});
|
||||
|
||||
it('should return block-scope node for `functionDeclaration blockStatement` node child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(functionDeclarationBlockStatementNode), programNode);
|
||||
});
|
||||
|
||||
it('should return block-scope node for `expressionStatement` node #1 child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(expressionStatementNode1), functionDeclarationBlockStatementNode);
|
||||
});
|
||||
|
||||
it('should return block-scope node for `ifStatement` node child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(ifStatementNode1), functionDeclarationBlockStatementNode);
|
||||
});
|
||||
|
||||
it('should return block-scope node for `ifStatement blockStatement` node #1 child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(ifStatementBlockStatementNode1), functionDeclarationBlockStatementNode);
|
||||
});
|
||||
|
||||
it('should return block-scope node for `ifStatement blockStatement` node #2 child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(ifStatementBlockStatementNode2), functionDeclarationBlockStatementNode);
|
||||
});
|
||||
|
||||
it('should return block-scope node for `expressionStatement` node #3 child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopeOfNode(expressionStatementNode3), functionDeclarationBlockStatementNode);
|
||||
});
|
||||
|
||||
it('should throw a `ReferenceError` if node has no `parentNode` property', () => {
|
||||
assert.throws(() => NodeUtils.getBlockScopeOfNode(expressionStatementNode2), ReferenceError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getBlockScopesOfNode', () => {
|
||||
let functionDeclarationBlockStatementNode: ESTree.BlockStatement,
|
||||
ifStatementBlockStatementNode1: ESTree.BlockStatement,
|
||||
@@ -239,7 +334,7 @@ describe('NodeUtils', () => {
|
||||
expressionStatementNode3.parentNode = ifStatementBlockStatementNode2;
|
||||
});
|
||||
|
||||
it('should return block-scope node for `program` node child', () => {
|
||||
it('should return block-scope node for `program` node child node', () => {
|
||||
assert.deepEqual(NodeUtils.getBlockScopesOfNode(programNode)[0], programNode);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user