Merge pull request #269 from javascript-obfuscator/2018-refactoring-1

2018 refactoring 1
This commit is contained in:
Timofey Kachalov
2018-05-28 11:12:00 +03:00
committed by GitHub
11 changed files with 571 additions and 432 deletions
+4 -4
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+10 -10
View File
@@ -21,7 +21,7 @@
},
"types": "index.d.ts",
"dependencies": {
"@babel/runtime": "7.0.0-beta.47",
"@babel/runtime": "7.0.0-beta.49",
"chalk": "2.4.1",
"chance": "1.0.16",
"class-validator": "0.8.5",
@@ -41,10 +41,10 @@
"tslib": "1.9.1"
},
"devDependencies": {
"@babel/cli": "7.0.0-beta.47",
"@babel/core": "7.0.0-beta.47",
"@babel/plugin-transform-runtime": "7.0.0-beta.47",
"@babel/preset-env": "7.0.0-beta.47",
"@babel/cli": "7.0.0-beta.49",
"@babel/core": "7.0.0-beta.49",
"@babel/plugin-transform-runtime": "7.0.0-beta.49",
"@babel/preset-env": "7.0.0-beta.49",
"@types/chai": "4.1.3",
"@types/chance": "1.0.0",
"@types/escodegen": "0.0.6",
@@ -56,7 +56,7 @@
"@types/multimatch": "2.1.2",
"@types/node": "10.1.2",
"@types/rimraf": "2.0.2",
"@types/sinon": "4.3.3",
"@types/sinon": "5.0.0",
"@types/string-template": "1.0.2",
"@types/webpack-env": "1.13.6",
"awesome-typescript-loader": "5.0.0",
@@ -68,16 +68,16 @@
"pjson": "1.0.9",
"pre-commit": "1.2.2",
"rimraf": "2.6.2",
"sinon": "5.0.7",
"sinon": "5.0.10",
"threads": "0.11.0",
"ts-node": "6.0.3",
"ts-node": "6.0.5",
"tslint": "5.10.0",
"tslint-eslint-rules": "5.3.1",
"tslint-language-service": "0.9.9",
"tslint-microsoft-contrib": "5.0.3",
"tslint-webpack-plugin": "1.2.2",
"typescript": "2.8.3",
"webpack": "4.8.3",
"typescript": "3.0.0-dev.20180526",
"webpack": "4.9.1",
"webpack-cli": "2.1.4",
"webpack-node-externals": "1.7.2"
},
+2 -2
View File
@@ -157,7 +157,7 @@ function wrapInitializableProperty (target: IInitializable, propertyKey: string
initializablePropertiesSet.add(propertyKey);
const initializablePropertyMetadataKey: string = `_${propertyKey}`;
const initializablePropertyMetadataKey: string = `_${propertyKey.toString()}`;
const propertyDescriptor: PropertyDescriptor = Object
.getOwnPropertyDescriptor(target, initializablePropertyMetadataKey) || defaultDescriptor;
@@ -165,7 +165,7 @@ function wrapInitializableProperty (target: IInitializable, propertyKey: string
...propertyDescriptor,
get: function (): any {
if (this[initializablePropertyMetadataKey] === undefined) {
throw new Error(`Property \`${propertyKey}\` is not initialized! Initialize it first!`);
throw new Error(`Property \`${propertyKey.toString()}\` is not initialized! Initialize it first!`);
}
return this[initializablePropertyMetadataKey];
@@ -22,7 +22,12 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
/**
* @type {Map<ESTree.ObjectExpression, TNodeWithScope>}
*/
private readonly cachedObjectExpressionScopesMap: Map <ESTree.ObjectExpression, TNodeWithScope> = new Map();
private readonly cachedHostScopesMap: Map <ESTree.ObjectExpression, TNodeWithScope> = new Map();
/**
* @type {Map<ESTree.ObjectExpression, ESTree.Statement>}
*/
private readonly cachedHostStatementsMap: Map <ESTree.ObjectExpression, ESTree.Statement> = new Map();
/**
* @param {IRandomGenerator} randomGenerator
@@ -35,26 +40,6 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
super(randomGenerator, options);
}
/**
* Returns host statement of object expression node
*
* @param {NodeGuards} node
* @returns {Node}
*/
private static getHostStatement (node: ESTree.Node): ESTree.Statement {
const parentNode: ESTree.Node | undefined = node.parentNode;
if (!parentNode) {
throw new ReferenceError('`parentNode` property of given node is `undefined`');
}
if (!NodeGuards.isNodeHasScope(parentNode)) {
return ObjectExpressionKeysTransformer.getHostStatement(parentNode);
}
return <ESTree.Statement>node;
}
/**
* @param {Property} propertyNode
* @returns {string | null}
@@ -206,20 +191,42 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
/**
* @param {ObjectExpression} objectExpressionNode
* @param {Statement} hostStatement
* @returns {TNodeWithScope}
*/
private getScopeNode (objectExpressionNode: ESTree.ObjectExpression): TNodeWithScope {
if (this.cachedObjectExpressionScopesMap.has(objectExpressionNode)) {
return <TNodeWithScope>this.cachedObjectExpressionScopesMap.get(objectExpressionNode);
private getHostScopeNode (
objectExpressionNode: ESTree.ObjectExpression,
hostStatement: ESTree.Statement
): TNodeWithScope {
if (this.cachedHostScopesMap.has(objectExpressionNode)) {
return <TNodeWithScope>this.cachedHostScopesMap.get(objectExpressionNode);
}
const scopeNode: TNodeWithScope = NodeUtils.getScopeOfNode(objectExpressionNode);
const scopeNode: TNodeWithScope = NodeUtils.getScopeOfNode(hostStatement);
this.cachedObjectExpressionScopesMap.set(objectExpressionNode, scopeNode);
this.cachedHostScopesMap.set(objectExpressionNode, scopeNode);
return scopeNode;
}
/**
* Returns host statement of object expression node
*
* @param {NodeGuards} objectExpressionNode
* @returns {Node}
*/
private getHostStatement (objectExpressionNode: ESTree.ObjectExpression): ESTree.Statement {
if (this.cachedHostStatementsMap.has(objectExpressionNode)) {
return <ESTree.Statement>this.cachedHostStatementsMap.get(objectExpressionNode);
}
const hostStatement: ESTree.Statement = NodeUtils.getRootStatementOfNode(objectExpressionNode);
this.cachedHostStatementsMap.set(objectExpressionNode, hostStatement);
return hostStatement;
}
/**
* @param {ObjectExpression} objectExpressionNode
* @param {VariableDeclarator} hostNode
@@ -274,8 +281,9 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
const properties: ESTree.Property[] = objectExpressionNode.properties;
const [expressionStatements, removablePropertyIds]: [ESTree.ExpressionStatement[], number[]] = this
.extractPropertiesToExpressionStatements(properties, memberExpressionHostNode);
const hostStatement: ESTree.Statement = ObjectExpressionKeysTransformer.getHostStatement(objectExpressionNode);
const scopeNode: TNodeWithScope = this.getScopeNode(objectExpressionNode);
const hostStatement: ESTree.Statement = this.getHostStatement(objectExpressionNode);
const scopeNode: TNodeWithScope = this.getHostScopeNode(objectExpressionNode, hostStatement);
objectExpressionNode.properties = properties.filter((property: ESTree.Property, index: number) =>
!removablePropertyIds.includes(index)
+22
View File
@@ -93,6 +93,28 @@ export class NodeUtils {
return NodeUtils.getSiblingStatementByOffset(statement, -1);
}
/**
* @param {Node} node
* @returns {Statement}
*/
public static getRootStatementOfNode (node: ESTree.Node): ESTree.Statement {
if (NodeGuards.isProgramNode(node)) {
throw new Error('Unable to find root statement for `Program` node');
}
const parentNode: ESTree.Node | undefined = node.parentNode;
if (!parentNode) {
throw new ReferenceError('`parentNode` property of given node is `undefined`');
}
if (!NodeGuards.isNodeHasScope(parentNode)) {
return NodeUtils.getRootStatementOfNode(parentNode);
}
return <ESTree.Statement>node;
}
/**
* @param {NodeGuards} node
* @returns {TNodeWithScope}
+4 -1
View File
@@ -56,6 +56,8 @@ export class CryptUtils implements ICryptUtils {
// tslint:enable
/**
* Hides string inside a other random string with larger length
*
* @param {string} str
* @param {number} length
* @returns {[string , string]}
@@ -87,7 +89,8 @@ export class CryptUtils implements ICryptUtils {
let randomStringDiff: string = randomString.replace(
new RegExp(`[${escapeRegExp(str)}]`, 'g'),
'');
''
);
const randomStringDiffArray: string[] = randomStringDiff.split('');
@@ -466,6 +466,101 @@ describe('NodeUtils', () => {
});
});
describe('getRootStatementOfNode', () => {
let assignmentExpression: ESTree.AssignmentExpression,
expressionStatement: ESTree.ExpressionStatement,
identifierNode1: ESTree.Identifier,
identifierNode2: ESTree.Identifier,
identifierNode3: ESTree.Identifier,
identifierNode4: ESTree.Identifier,
identifierNode5: ESTree.Identifier,
functionDeclarationNode: ESTree.FunctionDeclaration,
functionDeclarationBlockStatementNode: ESTree.BlockStatement,
programNode: ESTree.Program,
variableDeclarationNode: ESTree.VariableDeclaration;
before(() => {
identifierNode1 = NodeFactory.identifierNode('identifier');
identifierNode2 = NodeFactory.identifierNode('identifier');
identifierNode3 = NodeFactory.identifierNode('identifier');
identifierNode4 = NodeFactory.identifierNode('foo');
identifierNode5 = NodeFactory.identifierNode('bar');
assignmentExpression = NodeFactory.assignmentExpressionNode(
'=',
identifierNode4,
identifierNode5
);
expressionStatement = NodeFactory.expressionStatementNode(
assignmentExpression
);
variableDeclarationNode = NodeFactory.variableDeclarationNode([
NodeFactory.variableDeclaratorNode(
identifierNode1,
NodeFactory.binaryExpressionNode(
'+',
identifierNode2,
identifierNode3
)
)
]);
functionDeclarationBlockStatementNode = NodeFactory.blockStatementNode([
variableDeclarationNode
]);
functionDeclarationNode = NodeFactory.functionDeclarationNode('test', [], functionDeclarationBlockStatementNode);
programNode = NodeFactory.programNode([
functionDeclarationNode,
NodeFactory.ifStatementNode(
NodeFactory.literalNode(true),
NodeFactory.blockStatementNode([
expressionStatement
])
)
]);
NodeUtils.parentizeAst(programNode);
identifierNode3.parentNode = undefined;
});
it('should return root statement in scope for `program` node child', () => {
assert.throws(() => NodeUtils.getRootStatementOfNode(programNode), Error);
});
it('should return root statement in scope for `functionDeclaration` node #1', () => {
assert.deepEqual(NodeUtils.getRootStatementOfNode(functionDeclarationNode), functionDeclarationNode);
});
it('should return root statement in scope for `functionDeclaration blockStatement` node #1', () => {
assert.deepEqual(NodeUtils.getRootStatementOfNode(functionDeclarationBlockStatementNode), functionDeclarationNode);
});
it('should return root statement in scope for `identifier` node #1', () => {
assert.deepEqual(NodeUtils.getRootStatementOfNode(identifierNode1), variableDeclarationNode);
});
it('should return root statement in scope for `identifier` node #2', () => {
assert.deepEqual(NodeUtils.getRootStatementOfNode(identifierNode2), variableDeclarationNode);
});
it('should return root statement in scope for `identifier` node #4', () => {
assert.deepEqual(NodeUtils.getRootStatementOfNode(identifierNode4), expressionStatement);
});
it('should return root statement in scope for `identifier` node #5', () => {
assert.deepEqual(NodeUtils.getRootStatementOfNode(identifierNode5), expressionStatement);
});
it('should throw a `ReferenceError` if node has no `parentNode` property', () => {
assert.throws(() => NodeUtils.getRootStatementOfNode(identifierNode3), ReferenceError);
});
});
describe('getScopeOfNode', () => {
let functionDeclarationBlockStatementNode: ESTree.BlockStatement,
ifStatementBlockStatementNode1: ESTree.BlockStatement,
+2
View File
@@ -1,3 +1,5 @@
import 'reflect-metadata';
import { assert } from 'chai';
import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
+394 -385
View File
File diff suppressed because it is too large Load Diff