mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Added more tests. Updated NodeAppender class to work with all scope nodes.
This commit is contained in:
@@ -18,9 +18,9 @@ import { NodeUtils } from '../../node/NodeUtils';
|
||||
@injectable()
|
||||
export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {Map<VariableDeclarator, BlockStatement>}
|
||||
* @type {Map<VariableDeclarator, TNodeWithScope>}
|
||||
*/
|
||||
private cachedScopeNodesMap: Map <ESTree.VariableDeclarator, ESTree.BlockStatement> = new Map();
|
||||
private cachedScopeNodesMap: Map <ESTree.VariableDeclarator, TNodeWithScope> = new Map();
|
||||
|
||||
/**
|
||||
* @param {IRandomGenerator} randomGenerator
|
||||
@@ -34,27 +34,22 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BlockStatement} scopeNode
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @param {ExpressionStatement[]} expressionStatements
|
||||
* @param {Node} variableDeclarator
|
||||
*/
|
||||
private static appendExpressionStatements (
|
||||
scopeNode: ESTree.BlockStatement,
|
||||
scopeNode: TNodeWithScope,
|
||||
expressionStatements: ESTree.ExpressionStatement[],
|
||||
variableDeclarator: ESTree.Node
|
||||
): void {
|
||||
const variableDeclaration: ESTree.Node | undefined = variableDeclarator.parentNode;
|
||||
|
||||
if (
|
||||
!variableDeclaration
|
||||
|| !NodeGuards.isVariableDeclarationNode(variableDeclaration)
|
||||
) {
|
||||
if (!variableDeclaration || !NodeGuards.isVariableDeclarationNode(variableDeclaration)) {
|
||||
throw new Error('Cannot find variable declaration for variable declarator');
|
||||
}
|
||||
|
||||
const indexInBlockStatement: number = scopeNode.body.indexOf(variableDeclaration);
|
||||
|
||||
NodeAppender.insertNodeAtIndex(scopeNode, expressionStatements, indexInBlockStatement + 1);
|
||||
NodeAppender.insertNodeAfter(scopeNode, expressionStatements, variableDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +103,7 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
|
||||
|
||||
const scopeNode: TNodeWithScope | null = NodeUtils.getScopeOfNode(variableDeclarator);
|
||||
|
||||
if (!scopeNode || !NodeGuards.isBlockStatementNode(scopeNode)) {
|
||||
if (!scopeNode || !NodeGuards.isNodeHasScope(scopeNode)) {
|
||||
return objectExpressionNode;
|
||||
}
|
||||
|
||||
@@ -216,7 +211,7 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
|
||||
return objectExpressionNode;
|
||||
}
|
||||
|
||||
const scopeNode: ESTree.BlockStatement | undefined = this.cachedScopeNodesMap.get(variableDeclarator);
|
||||
const scopeNode: TNodeWithScope | undefined = this.cachedScopeNodesMap.get(variableDeclarator);
|
||||
|
||||
if (!scopeNode) {
|
||||
return objectExpressionNode;
|
||||
|
||||
+80
-54
@@ -4,6 +4,8 @@ import { TNodeWithBlockScope } from '../types/node/TNodeWithBlockScope';
|
||||
import { TStatement } from '../types/node/TStatement';
|
||||
|
||||
import { IStackTraceData } from '../interfaces/analyzers/stack-trace-analyzer/IStackTraceData';
|
||||
import { TNodeWithScope } from '../types/node/TNodeWithScope';
|
||||
import { NodeGuards } from './NodeGuards';
|
||||
|
||||
/**
|
||||
* This class appends node into a first deepest BlockStatement in order of function calls
|
||||
@@ -24,23 +26,20 @@ import { IStackTraceData } from '../interfaces/analyzers/stack-trace-analyzer/IS
|
||||
*/
|
||||
export class NodeAppender {
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TStatement[]} nodeBodyStatements
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @param {TStatement[]} scopeStatements
|
||||
*/
|
||||
public static appendNode (
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
nodeBodyStatements: TStatement[]
|
||||
): void {
|
||||
if (!NodeAppender.validateBodyStatements(nodeBodyStatements)) {
|
||||
nodeBodyStatements = [];
|
||||
public static appendNode (scopeNode: TNodeWithScope, scopeStatements: TStatement[]): void {
|
||||
if (!NodeAppender.validateScopeStatements(scopeStatements)) {
|
||||
scopeStatements = [];
|
||||
}
|
||||
|
||||
nodeBodyStatements = NodeAppender.parentizeBodyStatementsBeforeAppend(blockScopeNode, nodeBodyStatements);
|
||||
scopeStatements = NodeAppender.parentizeScopeStatementsBeforeAppend(scopeNode, scopeStatements);
|
||||
|
||||
blockScopeNode.body = [
|
||||
...blockScopeNode.body,
|
||||
...nodeBodyStatements
|
||||
];
|
||||
NodeAppender.setScopeNodeStatements(scopeNode, [
|
||||
...NodeAppender.getScopeNodeStatements(scopeNode),
|
||||
...scopeStatements
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,70 +95,97 @@ export class NodeAppender {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TStatement[]} nodeBodyStatements
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @param {TStatement[]} scopeStatements
|
||||
* @param {Node} targetStatement
|
||||
*/
|
||||
public static insertNodeAfter (scopeNode: TNodeWithScope, scopeStatements: TStatement[], targetStatement: ESTree.Statement): void {
|
||||
const indexInScopeStatement: number = NodeAppender
|
||||
.getScopeNodeStatements(scopeNode)
|
||||
.indexOf(targetStatement);
|
||||
|
||||
NodeAppender.insertNodeAtIndex(scopeNode, scopeStatements, indexInScopeStatement + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @param {TStatement[]} scopeStatements
|
||||
* @param {number} index
|
||||
*/
|
||||
public static insertNodeAtIndex (
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
nodeBodyStatements: TStatement[],
|
||||
index: number
|
||||
): void {
|
||||
if (!NodeAppender.validateBodyStatements(nodeBodyStatements)) {
|
||||
nodeBodyStatements = [];
|
||||
public static insertNodeAtIndex (scopeNode: TNodeWithScope, scopeStatements: TStatement[], index: number): void {
|
||||
if (!NodeAppender.validateScopeStatements(scopeStatements)) {
|
||||
scopeStatements = [];
|
||||
}
|
||||
|
||||
nodeBodyStatements = NodeAppender.parentizeBodyStatementsBeforeAppend(blockScopeNode, nodeBodyStatements);
|
||||
scopeStatements = NodeAppender.parentizeScopeStatementsBeforeAppend(scopeNode, scopeStatements);
|
||||
|
||||
blockScopeNode.body = [
|
||||
...blockScopeNode.body.slice(0, index),
|
||||
...nodeBodyStatements,
|
||||
...blockScopeNode.body.slice(index)
|
||||
];
|
||||
NodeAppender.setScopeNodeStatements(scopeNode, [
|
||||
...NodeAppender.getScopeNodeStatements(scopeNode).slice(0, index),
|
||||
...scopeStatements,
|
||||
...NodeAppender.getScopeNodeStatements(scopeNode).slice(index)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TStatement[]} nodeBodyStatements
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @param {TStatement[]} scopeStatements
|
||||
*/
|
||||
public static prependNode (
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
nodeBodyStatements: TStatement[]
|
||||
): void {
|
||||
if (!NodeAppender.validateBodyStatements(nodeBodyStatements)) {
|
||||
nodeBodyStatements = [];
|
||||
public static prependNode (scopeNode: TNodeWithScope, scopeStatements: TStatement[]): void {
|
||||
if (!NodeAppender.validateScopeStatements(scopeStatements)) {
|
||||
scopeStatements = [];
|
||||
}
|
||||
|
||||
nodeBodyStatements = NodeAppender.parentizeBodyStatementsBeforeAppend(blockScopeNode, nodeBodyStatements);
|
||||
scopeStatements = NodeAppender.parentizeScopeStatementsBeforeAppend(scopeNode, scopeStatements);
|
||||
|
||||
blockScopeNode.body = [
|
||||
...nodeBodyStatements,
|
||||
...blockScopeNode.body,
|
||||
];
|
||||
NodeAppender.setScopeNodeStatements(scopeNode, [
|
||||
...scopeStatements,
|
||||
...NodeAppender.getScopeNodeStatements(scopeNode),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithBlockScope} blockScopeNode
|
||||
* @param {TStatement[]} nodeBodyStatements
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
private static parentizeBodyStatementsBeforeAppend (
|
||||
blockScopeNode: TNodeWithBlockScope,
|
||||
nodeBodyStatements: TStatement[]
|
||||
): TStatement[] {
|
||||
nodeBodyStatements.forEach((statement: TStatement) => {
|
||||
statement.parentNode = blockScopeNode;
|
||||
});
|
||||
private static getScopeNodeStatements (scopeNode: TNodeWithScope): TStatement[] {
|
||||
if (NodeGuards.isSwitchCaseNode(scopeNode)) {
|
||||
return scopeNode.consequent;
|
||||
}
|
||||
|
||||
return nodeBodyStatements;
|
||||
return scopeNode.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TStatement[]} nodeBodyStatements
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @param {TStatement[]} scopeStatements
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
private static parentizeScopeStatementsBeforeAppend (scopeNode: TNodeWithScope, scopeStatements: TStatement[]): TStatement[] {
|
||||
scopeStatements.forEach((statement: TStatement) => {
|
||||
statement.parentNode = scopeNode;
|
||||
});
|
||||
|
||||
return scopeStatements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TNodeWithScope} scopeNode
|
||||
* @param {TStatement[]} statements
|
||||
*/
|
||||
private static setScopeNodeStatements (scopeNode: TNodeWithScope, statements: TStatement[]): void {
|
||||
if (NodeGuards.isSwitchCaseNode(scopeNode)) {
|
||||
scopeNode.consequent = <ESTree.Statement[]>statements;
|
||||
} else {
|
||||
scopeNode.body = statements;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TStatement[]} scopeStatement
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private static validateBodyStatements (nodeBodyStatements: TStatement[]): boolean {
|
||||
return nodeBodyStatements.every((statementNode: TStatement) => {
|
||||
private static validateScopeStatements (scopeStatement: TStatement[]): boolean {
|
||||
return scopeStatement.every((statementNode: TStatement) => {
|
||||
return !!statementNode && statementNode.hasOwnProperty('type');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ export class NodeGuards {
|
||||
const parentNode: ESTree.Node | undefined = node.parentNode;
|
||||
|
||||
if (!parentNode) {
|
||||
return false;
|
||||
throw new ReferenceError('`parentNode` property of given node is `undefined`');
|
||||
}
|
||||
|
||||
return NodeGuards.isProgramNode(node) || (
|
||||
@@ -271,7 +271,7 @@ export class NodeGuards {
|
||||
parentNode.key === node;
|
||||
const parentNodeIsMemberExpressionNode: boolean = (
|
||||
NodeGuards.isMemberExpressionNode(parentNode) &&
|
||||
parentNode.computed === false &&
|
||||
!parentNode.computed &&
|
||||
parentNode.property === node
|
||||
);
|
||||
const parentNodeIsMethodDefinitionNode: boolean = NodeGuards.isMethodDefinitionNode(parentNode) &&
|
||||
|
||||
@@ -305,6 +305,30 @@ export class Nodes {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression} key
|
||||
* @param {FunctionExpression} value
|
||||
* @param {"constructor" | "method" | "get" | "set"} kind
|
||||
* @param {boolean} computed
|
||||
* @returns {MethodDefinition}
|
||||
*/
|
||||
public static getMethodDefinitionNode (
|
||||
key: ESTree.Expression,
|
||||
value: ESTree.FunctionExpression,
|
||||
kind: 'constructor' | 'method' | 'get' | 'set',
|
||||
computed: boolean,
|
||||
): ESTree.MethodDefinition {
|
||||
return {
|
||||
type: NodeType.MethodDefinition,
|
||||
key,
|
||||
value,
|
||||
kind,
|
||||
computed,
|
||||
static: false,
|
||||
obfuscatedNode: false
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Property[]} properties
|
||||
* @returns {ObjectExpression}
|
||||
|
||||
Reference in New Issue
Block a user