Fixed conflict between control flow storage and mangled identifiers

This commit is contained in:
sanex3339
2018-01-16 00:49:51 +03:00
parent c00685c43d
commit e7e159d785
10 changed files with 74 additions and 62 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -48,21 +48,22 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
const structure: TStatement = Nodes.getFunctionDeclarationNode(
this.randomGenerator.getRandomString(3),
[
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
],
Nodes.getBlockStatementNode([
Nodes.getReturnStatementNode(
Nodes.getBinaryExpressionNode(
this.operator,
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
const structure: TStatement = Nodes.getExpressionStatementNode(
Nodes.getFunctionExpressionNode(
[
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
],
Nodes.getBlockStatementNode([
Nodes.getReturnStatementNode(
Nodes.getBinaryExpressionNode(
this.operator,
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
)
)
)
])
])
)
);
NodeUtils.parentize(structure);
@@ -56,20 +56,21 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
params.push(Nodes.getIdentifierNode(`param${i + 1}`));
}
const structure: TStatement = Nodes.getFunctionDeclarationNode(
this.randomGenerator.getRandomString(3),
[
calleeIdentifier,
...params
],
Nodes.getBlockStatementNode([
Nodes.getReturnStatementNode(
Nodes.getCallExpressionNode(
calleeIdentifier,
params
const structure: TStatement = Nodes.getExpressionStatementNode(
Nodes.getFunctionExpressionNode(
[
calleeIdentifier,
...params
],
Nodes.getBlockStatementNode([
Nodes.getReturnStatementNode(
Nodes.getCallExpressionNode(
calleeIdentifier,
params
)
)
)
])
])
)
);
NodeUtils.parentize(structure);
@@ -48,21 +48,22 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
const structure: TStatement = Nodes.getFunctionDeclarationNode(
this.randomGenerator.getRandomString(3),
[
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
],
Nodes.getBlockStatementNode([
Nodes.getReturnStatementNode(
Nodes.getLogicalExpressionNode(
this.operator,
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
const structure: TStatement = Nodes.getExpressionStatementNode(
Nodes.getFunctionExpressionNode(
[
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
],
Nodes.getBlockStatementNode([
Nodes.getReturnStatementNode(
Nodes.getLogicalExpressionNode(
this.operator,
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
)
)
)
])
])
)
);
NodeUtils.parentize(structure);
@@ -45,7 +45,9 @@ export class StringLiteralNode extends AbstractCustomNode {
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
const structure: TStatement = <any>Nodes.getLiteralNode(this.literalValue);
const structure: TStatement = Nodes.getExpressionStatementNode(
Nodes.getLiteralNode(this.literalValue)
);
return [structure];
}
@@ -14,6 +14,7 @@ import { IStorage } from '../../../interfaces/storages/IStorage';
import { initializable } from '../../../decorators/Initializable';
import { AbstractCustomNode } from '../../AbstractCustomNode';
import { NodeGuards } from '../../../node/NodeGuards';
import { Nodes } from '../../../node/Nodes';
import { NodeUtils } from '../../../node/NodeUtils';
@@ -50,19 +51,25 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
* @returns {TStatement[]}
*/
protected getNodeStructure (): TStatement[] {
const propertyNodes: ESTree.Property[] = Array
.from<[string, ICustomNode]>(this.controlFlowStorage.getStorage())
.map(([key, value]: [string, ICustomNode]) => {
const node: ESTree.Node = value.getNode()[0];
if (!NodeGuards.isExpressionStatementNode(node)) {
throw new Error('Function node for control flow storage object should be passed inside the `ExpressionStatement` node!');
}
return Nodes.getPropertyNode(
Nodes.getIdentifierNode(key),
node.expression
);
});
let structure: ESTree.Node = Nodes.getVariableDeclarationNode([
Nodes.getVariableDeclaratorNode(
Nodes.getIdentifierNode(this.controlFlowStorage.getStorageId()),
Nodes.getObjectExpressionNode(
Array
.from<[string, ICustomNode]>(this.controlFlowStorage.getStorage())
.map(([key, value]: [string, ICustomNode]) => {
return Nodes.getPropertyNode(
Nodes.getIdentifierNode(key),
<any>value.getNode()[0]
);
})
)
Nodes.getObjectExpressionNode(propertyNodes)
)
]);
@@ -244,7 +244,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
parentNode: ESTree.Node
): ESTree.BlockStatement {
/**
* we should wrap original random block statement node into the parent block statement node (ast root host node)
* Should wrap original random block statement node into the parent block statement node (ast root host node)
* with function declaration node. This function declaration node will create block scope for all identifiers
* inside random block statement node and this identifiers won't affect identifiers of the rest AST tree.
*/
@@ -257,7 +257,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
]);
/**
* we should store that host node and then extract random block statement node on the `finalizing` stage
* Should store that host node and then extract random block statement node on the `finalizing` stage
*/
this.deadCodeInjectionRootAstHostNodeSet.add(deadCodeInjectionRootAstHostNode);
@@ -14,14 +14,14 @@ describe('FunctionControlFlowTransformer', function () {
const variableMatch: string = '_0x([a-f0-9]){4,6}';
const rootControlFlowStorageNodeMatch: string = `` +
`var *${variableMatch} *= *\\{` +
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`return *${variableMatch} *\\+ *${variableMatch};` +
`\\}` +
`\\};` +
``;
const innerControlFlowStorageNodeMatch: string = `` +
`var *${variableMatch} *= *\\{` +
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`return *${variableMatch}\\['\\w{5}'\\]\\(${variableMatch}, *${variableMatch}\\);` +
`\\}` +
`\\};` +
@@ -107,10 +107,10 @@ describe('FunctionControlFlowTransformer', function () {
describe('variant #3 - single `control flow storage` node with multiple items', () => {
const regexp: RegExp = new RegExp(
`var *${variableMatch} *= *\\{` +
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`return *${variableMatch} *\\+ *${variableMatch};` +
`\\}, *` +
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`return *${variableMatch} *- *${variableMatch};` +
`\\}` +
`\\};`
@@ -167,7 +167,7 @@ describe('FunctionControlFlowTransformer', function () {
const regExp: RegExp = new RegExp(
`var *[a-zA-Z]{6} *= *\\{` +
`'\\w{5}' *: *function *_0x[0-9] *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`return *${variableMatch} *\\+ *${variableMatch};` +
`\\}` +
`\\};`
@@ -106,7 +106,7 @@ describe('ObjectExpressionKeysTransformer', () => {
describe('variant #4: correct integration with control flow flattening object', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['\\w{5}'] *= *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *{` +
`${variableMatch}\\['\\w{5}'] *= *function *\\(${variableMatch}, *${variableMatch}\\) *{` +
`return *${variableMatch} *\\+ *${variableMatch};` +
`};` +
`var *${variableMatch} *= *${variableMatch}\\['\\w{5}']\\(0x1, *0x2\\);` +
@@ -291,7 +291,7 @@ describe('EvalCallExpressionTransformer', () => {
const variableMatch: string = '_0x([a-f0-9]){4,6}';
const controlFlowStorageNodeMatch: string = `` +
`var *${variableMatch} *= *\\{` +
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
`return *${variableMatch} *\\+ *${variableMatch};` +
`\\}` +
`\\};` +