Merge branch 'dev'

# Conflicts:
#	package.json
This commit is contained in:
sanex3339
2017-01-12 01:00:22 +03:00
62 changed files with 1097 additions and 985 deletions
+12
View File
@@ -1,5 +1,17 @@
Change Log
===
v0.8.6
---
* additional fixes for https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
v0.8.5
---
* fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
v0.8.4
---
* fixed https://github.com/javascript-obfuscator/webpack-obfuscator/issues/13
v0.8.3
---
* `selfDefending` option now disabled by default.
+1 -1
View File
@@ -298,7 +298,7 @@ If checked, an interval is used to force the debug mode on the Console tab, maki
### `disableConsoleOutput`
Type: `boolean` Default: `true`
Disables the use of `console.log`, `console.info`, `console.error` and `console.warn` by replacing them with empty functions. This makes the use of the debugger harder.
Disables the use of `console.log`, `console.info`, `console.error`, `console.warn`, `console.debug`, `console.exception` and `console.trace` by replacing them with empty functions. This makes the use of the debugger harder.
### `domainLock`
Type: `string[]` Default: `[]`
+732 -763
View File
File diff suppressed because it is too large Load Diff
+17 -17
View File
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "0.9.0-dev.9",
"version": "0.9.0-dev.10",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
@@ -20,21 +20,21 @@
"javascript-obfuscator": "./bin/javascript-obfuscator.js"
},
"dependencies": {
"babel-polyfill": "^6.20.0",
"babel-runtime": "^6.20.0",
"babel-polyfill": "6.20.0",
"babel-runtime": "6.20.0",
"chance": "1.0.4",
"class-validator": "0.6.6",
"class-validator": "0.6.8",
"commander": "2.9.0",
"escodegen": "1.8.1",
"esprima": "3.1.3",
"estraverse": "4.2.0",
"inversify": "^3.0.0-rc.4",
"lodash": "^4.17.4",
"inversify": "3.0.0-rc.4",
"lodash": "4.17.4",
"mkdirp": "0.5.1",
"reflect-metadata": "^0.1.9",
"reflect-metadata": "0.1.9",
"source-map-support": "0.4.8",
"string-template": "^1.0.0",
"tslib": "^1.5.0"
"string-template": "1.0.0",
"tslib": "1.5.0"
},
"devDependencies": {
"@types/chai": "3.4.34",
@@ -44,16 +44,16 @@
"@types/esprima": "2.1.33",
"@types/estraverse": "0.0.6",
"@types/estree": "0.0.34",
"@types/lodash": "^4.14.45",
"@types/lodash": "4.14.48",
"@types/mkdirp": "0.3.29",
"@types/mocha": "2.2.35",
"@types/node": "6.0.57",
"@types/mocha": "2.2.37",
"@types/node": "6.0.59",
"@types/sinon": "1.16.34",
"@types/string-template": "1.0.2",
"awesome-typescript-loader": "3.0.0-beta.17",
"awesome-typescript-loader": "3.0.0-beta.18",
"babel-cli": "6.18.0",
"babel-loader": "6.2.10",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-plugin-transform-runtime": "6.15.0",
"babel-preset-es2015": "6.18.0",
"chai": "4.0.0-canary.1",
"coveralls": "2.11.15",
@@ -61,10 +61,10 @@
"mocha": "3.2.0",
"sinon": "2.0.0-pre.4",
"ts-node": "2.0.0",
"tslint": "4.2.0",
"tslint-loader": "^3.3.0",
"tslint": "4.3.1",
"tslint-loader": "3.3.0",
"typescript": "2.1.4",
"webpack": "2.2.0-rc.2",
"webpack": "2.2.0-rc.3",
"webpack-node-externals": "1.5.4"
},
"repository": {
@@ -51,7 +51,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
*/
protected getTemplate (): string {
return format(ConsoleOutputDisableExpressionTemplate(), {
consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(6),
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
});
}
@@ -96,7 +96,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
return;
}
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNodes.ConsoleOutputDisableExpressionNode);
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
@@ -43,7 +43,7 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
*/
protected getNodeStructure (): TStatement[] {
const structure: TStatement = Nodes.getFunctionDeclarationNode(
RandomGeneratorUtils.getRandomVariableName(1, true, false),
RandomGeneratorUtils.getRandomString(3),
[
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
@@ -51,7 +51,7 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
}
const structure: TStatement = Nodes.getFunctionDeclarationNode(
RandomGeneratorUtils.getRandomVariableName(1, true, false),
RandomGeneratorUtils.getRandomString(3),
[
calleeIdentifier,
...params
@@ -43,7 +43,7 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
*/
protected getNodeStructure (): TStatement[] {
const structure: TStatement = Nodes.getFunctionDeclarationNode(
RandomGeneratorUtils.getRandomVariableName(1, true, false),
RandomGeneratorUtils.getRandomString(3),
[
Nodes.getIdentifierNode('x'),
Nodes.getIdentifierNode('y')
@@ -89,7 +89,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
return;
}
const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
const debugProtectionFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionNode);
const debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionCallNode);
@@ -55,7 +55,7 @@ export class DomainLockNode extends AbstractCustomNode {
const [hiddenDomainsString, diff]: string[] = CryptUtils.hideString(domainsString, domainsString.length * 3);
return format(DomainLockNodeTemplate(), {
domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(6),
diff: diff,
domains: hiddenDomainsString,
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
@@ -96,7 +96,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
return;
}
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
const domainLockNode: ICustomNode = this.customNodeFactory(CustomNodes.DomainLockNode);
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
@@ -55,7 +55,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
protected getTemplate (): string {
return JavaScriptObfuscator.obfuscate(
format(SelfDefendingTemplate(), {
selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(6, true, true),
selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(6),
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}),
{
@@ -96,7 +96,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
return;
}
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNodes.SelfDefendingUnicodeNode);
const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);
@@ -76,8 +76,8 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
* @returns {string}
*/
protected getTemplate (): string {
const timesName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6, true, true);
const timesName: string = RandomGeneratorUtils.getRandomVariableName(6);
const whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName(6);
let code: string = '';
+1 -1
View File
@@ -6,5 +6,5 @@ declare module 'escodegen' {
* @param options
* @returns IGeneratorOutput
*/
export function generate(ast: any, options?: GenerateOptions): IGeneratorOutput;
export function generate (ast: any, options?: GenerateOptions): IGeneratorOutput;
}
@@ -62,14 +62,14 @@ export class BlockStatementControlFlowTransformer extends AbstractNodeTransforme
}
const blockStatementBody: ESTree.Statement[] = blockStatementNode.body;
const originalKeys: number[] = [...Array(blockStatementBody.length).keys()];
const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys);
const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key));
if (blockStatementBody.length <= 4) {
return blockStatementNode;
}
const originalKeys: number[] = [...Array(blockStatementBody.length).keys()];
const shuffledKeys: number[] = Utils.arrayShuffle(originalKeys);
const originalKeysIndexesInShuffledArray: number[] = originalKeys.map((key: number) => shuffledKeys.indexOf(key));
const blockStatementControlFlowFlatteningCustomNode: ICustomNode = this.customNodeFactory(
CustomNodes.BlockStatementControlFlowFlatteningNode
);
@@ -9,11 +9,9 @@ import { IObfuscationReplacer } from '../../interfaces/node-transformers/IObfusc
import { IObfuscationReplacerWithStorage } from '../../interfaces/node-transformers/IObfuscationReplacerWithStorage';
import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscationReplacers';
import { NodeType } from '../../enums/NodeType';
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
import { Node } from '../../node/Node';
import { NodeUtils } from '../../node/NodeUtils';
/**
* replaces:
@@ -34,7 +32,7 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
* @param replacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -61,9 +59,9 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
* @param nodeIdentifier
*/
private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause, nodeIdentifier: number): void {
NodeUtils.typedTraverse(catchClauseNode.param, NodeType.Identifier, {
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
});
if (Node.isIdentifierNode(catchClauseNode.param)) {
this.identifierReplacer.storeNames(catchClauseNode.param.name, nodeIdentifier);
}
}
/**
@@ -74,7 +72,12 @@ export class CatchClauseTransformer extends AbstractNodeTransformer {
estraverse.replace(catchClauseNode, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (Node.isReplaceableIdentifierNode(node, parentNode)) {
node.name = this.identifierReplacer.replace(node.name, nodeIdentifier);
const newNodeName: string = this.identifierReplacer.replace(node.name, nodeIdentifier);
if (node.name !== newNodeName) {
node.name = newNodeName;
node.obfuscated = true;
}
}
}
});
@@ -42,7 +42,7 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
* @param nodeObfuscatorsReplacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -76,9 +76,7 @@ export class FunctionDeclarationTransformer extends AbstractNodeTransformer {
* @param nodeIdentifier
*/
private storeFunctionName (functionDeclarationNode: ESTree.FunctionDeclaration, nodeIdentifier: number): void {
NodeUtils.typedTraverse(functionDeclarationNode.id, NodeType.Identifier, {
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
});
this.identifierReplacer.storeNames(functionDeclarationNode.id.name, nodeIdentifier);
}
/**
@@ -9,11 +9,9 @@ import { IObfuscationReplacer } from '../../interfaces/node-transformers/IObfusc
import { IObfuscationReplacerWithStorage } from '../../interfaces/node-transformers/IObfuscationReplacerWithStorage';
import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscationReplacers';
import { NodeType } from '../../enums/NodeType';
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
import { Node } from '../../node/Node';
import { NodeUtils } from '../../node/NodeUtils';
/**
* replaces:
@@ -34,7 +32,7 @@ export class FunctionTransformer extends AbstractNodeTransformer {
* @param nodeObfuscatorsReplacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -63,9 +61,9 @@ export class FunctionTransformer extends AbstractNodeTransformer {
private storeFunctionParams (functionNode: ESTree.Function, nodeIdentifier: number): void {
functionNode.params
.forEach((paramsNode: ESTree.Node) => {
NodeUtils.typedTraverse(paramsNode, NodeType.Identifier, {
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
});
if (Node.isIdentifierNode(paramsNode)) {
this.identifierReplacer.storeNames(paramsNode.name, nodeIdentifier);
}
});
}
@@ -9,11 +9,9 @@ import { IObfuscationReplacer } from '../../interfaces/node-transformers/IObfusc
import { IObfuscationReplacerWithStorage } from '../../interfaces/node-transformers/IObfuscationReplacerWithStorage';
import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscationReplacers';
import { NodeType } from '../../enums/NodeType';
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
import { Node } from '../../node/Node';
import { NodeUtils } from '../../node/NodeUtils';
/**
* replaces:
@@ -42,7 +40,7 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
* @param nodeObfuscatorsReplacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -69,9 +67,7 @@ export class LabeledStatementTransformer extends AbstractNodeTransformer {
* @param nodeIdentifier
*/
private storeLabeledStatementName (labeledStatementNode: ESTree.LabeledStatement, nodeIdentifier: number): void {
NodeUtils.typedTraverse(labeledStatementNode.label, NodeType.Identifier, {
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
});
this.identifierReplacer.storeNames(labeledStatementNode.label.name, nodeIdentifier);
}
/**
@@ -23,7 +23,7 @@ export class LiteralTransformer extends AbstractNodeTransformer {
* @param replacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -23,7 +23,7 @@ export class MemberExpressionTransformer extends AbstractNodeTransformer {
* @param replacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -37,7 +37,7 @@ export class MethodDefinitionTransformer extends AbstractNodeTransformer {
* @param replacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -27,7 +27,7 @@ export class ObjectExpressionTransformer extends AbstractNodeTransformer {
/**
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(options);
@@ -27,7 +27,7 @@ export class TemplateLiteralTransformer extends AbstractNodeTransformer {
* @param replacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -43,7 +43,7 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
* @param replacersFactory
* @param options
*/
constructor(
constructor (
@inject(ServiceIdentifiers.Factory__IObfuscatorReplacer) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IObfuscationReplacer,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
@@ -83,9 +83,9 @@ export class VariableDeclarationTransformer extends AbstractNodeTransformer {
private storeVariableNames (variableDeclarationNode: ESTree.VariableDeclaration, nodeIdentifier: number): void {
variableDeclarationNode.declarations
.forEach((declarationNode: ESTree.VariableDeclarator) => {
NodeUtils.typedTraverse(declarationNode.id, NodeType.Identifier, {
enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name, nodeIdentifier)
});
if (Node.isIdentifierNode(declarationNode.id)) {
this.identifierReplacer.storeNames(declarationNode.id.name, nodeIdentifier);
}
});
}
@@ -47,7 +47,7 @@ export class IdentifierReplacer extends AbstractReplacer implements IObfuscation
*/
public storeNames (nodeName: string, nodeIdentifier: number): void {
if (!this.isReservedName(nodeName)) {
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, RandomGeneratorUtils.getRandomVariableName(6, true, true));
this.namesMap.set(`${nodeName}-${String(nodeIdentifier)}`, RandomGeneratorUtils.getRandomVariableName(6));
}
}
+2 -20
View File
@@ -1,24 +1,10 @@
import * as ESTree from 'estree';
import { TNodeWithBlockStatement } from '../types/node/TNodeWithBlockStatement';
import { TStatement } from '../types/node/TStatement';
import { NodeType } from '../enums/NodeType';
export class Node {
/**
* @param bodyNode
* @returns ESTree.Program
*/
public static getProgramNode (bodyNode: TStatement[]): ESTree.Program {
return {
'type': NodeType.Program,
'body': bodyNode,
'sourceType': 'script',
'obfuscated': false
};
}
/**
* @param node
* @returns {boolean}
@@ -109,9 +95,7 @@ export class Node {
const parentNodeIsContinueStatementNode: boolean = Node.isContinueStatementNode(parentNode) && parentNode.label === node;
const parentNodeIsBreakStatementNode: boolean = Node.isBreakStatementNode(parentNode) && parentNode.label === node;
return parentNodeIsLabeledStatementNode ||
parentNodeIsContinueStatementNode ||
parentNodeIsBreakStatementNode;
return parentNodeIsLabeledStatementNode || parentNodeIsContinueStatementNode || parentNodeIsBreakStatementNode;
}
/**
@@ -181,9 +165,7 @@ export class Node {
parentNode.property === node
);
return !parentNodeIsPropertyNode &&
!parentNodeIsMemberExpressionNode &&
!Node.isLabelIdentifierNode(node, parentNode);
return !parentNodeIsPropertyNode && !parentNodeIsMemberExpressionNode && !Node.isLabelIdentifierNode(node, parentNode);
}
/**
+19 -18
View File
@@ -9,6 +9,7 @@ import { TStatement } from '../types/node/TStatement';
import { NodeType } from '../enums/NodeType';
import { Node } from './Node';
import { Nodes } from './Nodes';
export class NodeUtils {
/**
@@ -23,20 +24,20 @@ export class NodeUtils {
];
/**
* @param node
* @param astTree
* @return {T}
*/
public static addXVerbatimPropertyToLiterals <T extends ESTree.Node> (node: T): T {
NodeUtils.typedReplace(node, NodeType.Literal, {
leave: (node: ESTree.Literal) => {
node['x-verbatim-property'] = {
content : node.raw,
public static addXVerbatimPropertyToLiterals <T extends ESTree.Node> (astTree: T): T {
NodeUtils.typedReplace(astTree, NodeType.Literal, {
leave: (literalNode: ESTree.Literal) => {
literalNode['x-verbatim-property'] = {
content : literalNode.raw,
precedence: escodegen.Precedence.Primary
};
}
});
return node;
return astTree;
}
/**
@@ -152,13 +153,13 @@ export class NodeUtils {
}
/**
* @param node
* @param astTree
* @return {T}
*/
public static parentize <T extends ESTree.Node> (node: T): T {
public static parentize <T extends ESTree.Node> (astTree: T): T {
let isRootNode: boolean = true;
estraverse.traverse(node, {
estraverse.traverse(astTree, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
let value: ESTree.Node;
@@ -166,7 +167,7 @@ export class NodeUtils {
if (node.type === NodeType.Program) {
value = node;
} else {
value = Node.getProgramNode(<TStatement[]>[node]);
value = Nodes.getProgramNode(<TStatement[]>[node]);
value.parentNode = value;
}
@@ -180,35 +181,35 @@ export class NodeUtils {
}
});
return node;
return astTree;
}
/**
* @param node
* @param astTree
* @param nodeType
* @param visitor
*/
public static typedReplace (
node: ESTree.Node,
astTree: ESTree.Node,
nodeType: string,
visitor: {enter?: (node: ESTree.Node) => void, leave?: (node: ESTree.Node) => void},
): void {
NodeUtils.typedTraverse(node, nodeType, visitor, 'replace');
NodeUtils.typedTraverse(astTree, nodeType, visitor, 'replace');
}
/**
* @param node
* @param astTree
* @param nodeType
* @param visitor
* @param traverseType
*/
public static typedTraverse (
node: ESTree.Node,
astTree: ESTree.Node,
nodeType: string,
visitor: estraverse.Visitor,
traverseType: string = 'traverse'
): void {
(<any>estraverse)[traverseType](node, {
(<any>estraverse)[traverseType](astTree, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (node.type === nodeType && visitor.enter) {
return visitor.enter(node, parentNode);
@@ -37,14 +37,14 @@ export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataEx
}
/**
* @param node
* @param targetNode
* @param name
* @returns {ESTree.BlockStatement|null}
*/
private getCalleeBlockStatement (node: ESTree.Node, name: string): ESTree.BlockStatement|null {
private getCalleeBlockStatement (targetNode: ESTree.Node, name: string): ESTree.BlockStatement|null {
let calleeBlockStatement: ESTree.BlockStatement|null = null;
estraverse.traverse(node, {
estraverse.traverse(targetNode, {
enter: (node: ESTree.Node): any => {
if (Node.isFunctionDeclarationNode(node) && node.id.name === name) {
calleeBlockStatement = node.body;
@@ -41,14 +41,14 @@ export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExt
}
/**
* @param node
* @param targetNode
* @param name
* @returns {ESTree.BlockStatement|null}
*/
private getCalleeBlockStatement (node: ESTree.Node, name: string): ESTree.BlockStatement|null {
private getCalleeBlockStatement (targetNode: ESTree.Node, name: string): ESTree.BlockStatement|null {
let calleeBlockStatement: ESTree.BlockStatement|null = null;
estraverse.traverse(node, {
estraverse.traverse(targetNode, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (
Node.isFunctionExpressionNode(node) &&
@@ -85,12 +85,12 @@ export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtra
}
/**
* @param node
* @param targetNode
* @param objectMembersCallsChain
* @returns {ESTree.BlockStatement|null}
*/
private getCalleeBlockStatement (
node: ESTree.Node,
targetNode: ESTree.Node,
objectMembersCallsChain: TObjectMembersCallsChain
): ESTree.BlockStatement|null {
const objectName: string|number|undefined = objectMembersCallsChain.shift();
@@ -101,7 +101,7 @@ export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtra
let calleeBlockStatement: ESTree.BlockStatement|null = null;
estraverse.traverse(node, {
estraverse.traverse(targetNode, {
enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
if (
Node.isVariableDeclaratorNode(node) &&
@@ -18,7 +18,7 @@ export class StringArrayStorage extends ArrayStorage <string> {
public initialize (...args: any[]): void {
super.initialize(args);
this.storageId = RandomGeneratorUtils.getRandomVariableName(4, false, false);
this.storageId = RandomGeneratorUtils.getRandomString(4, RandomGeneratorUtils.randomGeneratorPoolHexadecimal);
}
/**
@@ -9,10 +9,29 @@ export function ConsoleOutputDisableExpressionTemplate (): string {
var func = function () {};
var that = getGlobal();
that.console.log = func;
that.console.error = func;
that.console.warn = func;
that.console.info = func;
if (!that.console) {
that.console = (function (func){
var c = {};
c.log = func;
c.warn = func;
c.debug = func;
c.info = func;
c.error = func;
c.exception = func;
c.trace = func;
return c;
})(func);
} else {
that.console.log = func;
that.console.warn = func;
that.console.debug = func;
that.console.info = func;
that.console.error = func;
that.console.exception = func;
that.console.trace = func;
}
});
{consoleLogDisableFunctionName}();
+1 -1
View File
@@ -38,7 +38,7 @@ export class CryptUtils {
* @param length
* @returns {string[]}
*/
public static hideString(str: string, length: number): [string, string] {
public static hideString (str: string, length: number): [string, string] {
const escapeRegExp: (s: string) => string = (s: string) =>
s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+9 -6
View File
@@ -8,6 +8,11 @@ export class RandomGeneratorUtils {
*/
public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
/**
* @type {string}
*/
public static readonly randomGeneratorPoolHexadecimal: string = 'abcdef0123456789';
/**
* @type {string}
*/
@@ -87,12 +92,10 @@ export class RandomGeneratorUtils {
/**
* @param length
* @param withPrefix
* @param unique
* @returns {string}
*/
public static getRandomVariableName (length: number, withPrefix: boolean, unique: boolean): string {
const prefix: string = withPrefix ? `_${Utils.hexadecimalPrefix}` : '';
public static getRandomVariableName (length: number): string {
const prefix: string = `_${Utils.hexadecimalPrefix}`;
const rangeMinInteger: number = 10000;
const rangeMaxInteger: number = 99999999;
const randomVariableName: string = `${prefix}${(
@@ -101,8 +104,8 @@ export class RandomGeneratorUtils {
)
).substr(0, length)}`;
if (unique && RandomGeneratorUtils.randomVariableNameSet.has(randomVariableName)) {
return RandomGeneratorUtils.getRandomVariableName(length, withPrefix, unique);
if (RandomGeneratorUtils.randomVariableNameSet.has(randomVariableName)) {
return RandomGeneratorUtils.getRandomVariableName(length);
}
RandomGeneratorUtils.randomVariableNameSet.add(randomVariableName);
@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../helpers/readFileAsString';
import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
describe('ConsoleOutputDisableExpressionNode', () => {
const regExp = /(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*)*'\]\['(\\x[a-f0-9]*)*'\] *= *_0x([a-z0-9]){4,6};){4}/;
const regExp = /(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*)*'\]\['(\\x[a-f0-9]*)*'\] *= *_0x([a-f0-9]){4,6};){4}/;
it('should correctly append `ConsoleOutputDisableExpressionNode` custom node into the obfuscated code if `disableConsoleOutput` option is set', () => {
let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
@@ -18,7 +18,7 @@ describe('DomainLockNode', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-z0-9]){4,6} *= *new RegExp/);
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-f0-9]){4,6} *= *new RegExp/);
});
it('should\'t append `DomainLockNode` custom node into the obfuscated code if `domainLock` option is not set', () => {
@@ -30,6 +30,6 @@ describe('DomainLockNode', () => {
}
);
assert.notMatch(obfuscationResult.getObfuscatedCode(), /var _0x([a-z0-9]){4,6} *= *new RegExp/);
assert.notMatch(obfuscationResult.getObfuscatedCode(), /var _0x([a-f0-9]){4,6} *= *new RegExp/);
});
});
@@ -22,7 +22,7 @@ describe('StringArrayCallsWrapper', () => {
assert.match(
obfuscationResult.getObfuscatedCode(),
/_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6} *- *0x0\;/
/_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6} *- *0x0\;/
);
});
});
@@ -19,7 +19,7 @@ describe('StringArrayNode', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /^var _0x([a-z0-9]){4} *= *\[/);
assert.match(obfuscationResult.getObfuscatedCode(), /^var _0x([a-f0-9]){4} *= *\[/);
});
it('should\'t append `StringArrayNode` custom node into the obfuscated code if `stringArray` option is not set', () => {
@@ -31,6 +31,6 @@ describe('StringArrayNode', () => {
}
);
assert.notMatch(obfuscationResult.getObfuscatedCode(), /^var _0x([a-z0-9]){4} *= *\[/);
assert.notMatch(obfuscationResult.getObfuscatedCode(), /^var _0x([a-f0-9]){4} *= *\[/);
});
});
@@ -20,7 +20,7 @@ describe('StringArrayRotateFunctionNode', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-z0-9]){4,6}\) *\{/);
assert.match(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-f0-9]){4,6}\) *\{/);
});
it('should\'t append `StringArrayRotateFunctionNode` custom node into the obfuscated code if `rotateStringArray` option is not set', () => {
@@ -34,6 +34,6 @@ describe('StringArrayRotateFunctionNode', () => {
}
);
assert.notMatch(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-z0-9]){4,6}\) *\{/);
assert.notMatch(obfuscationResult.getObfuscatedCode(), /while *\(-- *_0x([a-f0-9]){4,6}\) *\{/);
});
});
@@ -28,11 +28,11 @@ describe('BlockStatementControlFlowTransformer', () => {
const statementRegExp4: RegExp = /console\['log'\]\(0x4\);/;
const statementRegExp5: RegExp = /console\['log'\]\(0x5\);/;
const switchCaseRegExp: RegExp = /switch *\(_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\+\+\]\) *\{/;
const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
const switchCaseLength: number = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-z0-9]){4,6} *= *'(.*?)'/;
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *'(.*?)'/;
const switchCaseMapMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapRegExp);
const switchCaseMapMatch: string = switchCaseMapMatches[1];
const switchCaseMap: string[] = switchCaseMapMatch.replace(/\\x7c/g, '|').split('|').sort();
@@ -73,11 +73,11 @@ describe('BlockStatementControlFlowTransformer', () => {
const statementRegExp4: RegExp = /console\['log'\]\(0x4\);/;
const statementRegExp5: RegExp = /console\['log'\]\(0x5\);/;
const switchCaseRegExp: RegExp = /switch *\(_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\+\+\]\) *\{/;
const switchCaseRegExp: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/;
const switchCaseLengthRegExp: RegExp = /case *'[0-5]': *console\['log'\]\(0x[0-6]\);/g;
const switchCaseLength: number = obfuscatedCode.match(switchCaseLengthRegExp)!.length;
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-z0-9]){4,6} *= *'(.*?)'/;
const switchCaseMapRegExp: RegExp = /var *_0x(?:[a-f0-9]){4,6} *= *'(.*?)'/;
const switchCaseMapMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(switchCaseMapRegExp);
const switchCaseMapMatch: string = switchCaseMapMatches[1];
const switchCaseMap: string[] = switchCaseMapMatch.replace(/\\x7c/g, '|').split('|').sort();
@@ -129,7 +129,7 @@ describe('BlockStatementControlFlowTransformer', () => {
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-z0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *const *_0x([a-f0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
it('shouldn\'t transform block statement if block statement contain variable declaration with `const` kind', () => {
assert.match(obfuscatedCode, statementRegExp);
@@ -147,7 +147,7 @@ describe('BlockStatementControlFlowTransformer', () => {
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-z0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *let *_0x([a-f0-9]){4,6} *= *0x1; *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
it('shouldn\'t transform block statement if block statement contain variable declaration with `let` kind', () => {
assert.match(obfuscatedCode, statementRegExp);
@@ -201,7 +201,7 @@ describe('BlockStatementControlFlowTransformer', () => {
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-z0-9]){4,6} *\( *\) *\{ *\} *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
const statementRegExp: RegExp = /^\(function *\( *\) *\{ *function *_0x([a-f0-9]){4,6} *\( *\) *\{ *\} *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/;
it('shouldn\'t transform block statement if block statement contain function declaration', () => {
assert.match(obfuscatedCode, statementRegExp);
@@ -221,7 +221,7 @@ describe('BlockStatementControlFlowTransformer', () => {
}
);
const regExp1: RegExp = /switch *\(_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\+\+\]\) *\{/g;
const regExp1: RegExp = /switch *\(_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\+\+\]\) *\{/g;
const regExp2: RegExp = /\(function *\( *\) *\{ *console\['(\\x[a-f0-9]*){3}'\]\(0x1\);/g;
const transformedStatementMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp1)!.length;
const untouchedStatementMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp2)!.length;
@@ -20,7 +20,7 @@ describe('BinaryExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(0x1, *0x2\);/;
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(0x1, *0x2\);/;
it('should replace binary expression node by call to control flow storage node', () => {
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -47,8 +47,8 @@ describe('BinaryExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x1, *0x2\);/;
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x2, *0x3\);/;
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x1, *0x2\);/;
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(0x2, *0x3\);/;
const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
@@ -20,7 +20,7 @@ describe('CallExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(_0x([a-z0-9]){4,6}, *0x1, *0x2\);/;
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
it('should replace call expression node by call to control flow storage node', () => {
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -47,8 +47,8 @@ describe('CallExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-z0-9]){4,6}, *0x1, *0x2\);/;
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-z0-9]){4,6}, *0x2, *0x3\);/;
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-f0-9]){4,6}, *0x1, *0x2\);/;
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(_0x([a-f0-9]){4,6}, *0x2, *0x3\);/;
const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
@@ -80,7 +80,7 @@ describe('CallExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['\\x73\\x75\\x6d'\]\(0x1, *0x2\);/;
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['\\x73\\x75\\x6d'\]\(0x1, *0x2\);/;
it('shouldn\'t replace call expression node by call to control flow storage node if call expression callee is member expression node', () => {
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -20,7 +20,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!!\[\], *!\[\]\);/;
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!!\[\], *!\[\]\);/;
it('should replace logical expression node by call to control flow storage node', () => {
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -47,8 +47,8 @@ describe('LogicalExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!!\[\], *!\[\]\);/;
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-z0-9]){4,6} *= *(_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!\[\], *!!\[\]\);/;
const controlFlowStorageCallRegExp1: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!!\[\], *!\[\]\);/;
const controlFlowStorageCallRegExp2: RegExp = /var *_0x([a-f0-9]){4,6} *= *(_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\])\(!\[\], *!!\[\]\);/;
const firstMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp1);
const secondMatchArray: RegExpMatchArray | null = obfuscatedCode.match(controlFlowStorageCallRegExp2);
@@ -80,7 +80,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!_0x([a-z0-9]){4,6}, *!_0x([a-z0-9]){4,6}\);/;
const controlFlowStorageCallRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['(\\x[a-f0-9]*){3}'\]\(!_0x([a-f0-9]){4,6}, *!_0x([a-f0-9]){4,6}\);/;
it('should replace logical expression node with unary expression by call to control flow storage node', () => {
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
@@ -97,7 +97,7 @@ describe('LogicalExpressionControlFlowReplacer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const regExp: RegExp = /var *_0x([a-z0-9]){4,6} *= *_0x([a-z0-9]){4,6}\[_0x([a-z0-9]){4,6}\] *&& *!\[\];/;
const regExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\[_0x([a-f0-9]){4,6}\] *&& *!\[\];/;
it('shouldn\'t replace prohibited expression nodes', () => {
assert.match(obfuscatedCode, regExp);
@@ -9,7 +9,7 @@ import { readFileAsString } from '../../../../helpers/readFileAsString';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator';
describe('FunctionControlFlowTransformer', () => {
const variableMatch: string = '_0x([a-z0-9]){4,6}';
const variableMatch: string = '_0x([a-f0-9]){4,6}';
const rootControlFlowStorageNodeMatch: string = `` +
`var *${variableMatch} *= *\\{` +
`'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
@@ -171,7 +171,7 @@ describe('FunctionControlFlowTransformer', () => {
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const controlFlowStorageMatch: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
const regexp: RegExp = /var *_0x([a-z0-9]){4,6} *= *0x1 *\+ *0x2;/;
const regexp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1 *\+ *0x2;/;
it('shouldn\'t add `control flow storage` node to the obfuscated code when threshold is 0', () => {
assert.match(obfuscatedCode, regexp);
@@ -17,8 +17,8 @@ describe('CatchClauseTransformer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const paramNameRegExp: RegExp = /catch *\((_0x([a-z0-9]){4,6})\) *\{/;
const bodyParamNameRegExp: RegExp = /console\['\\x6c\\x6f\\x67'\]\((_0x([a-z0-9]){4,6})\);/;
const paramNameRegExp: RegExp = /catch *\((_0x([a-f0-9]){4,6})\) *\{/;
const bodyParamNameRegExp: RegExp = /console\['\\x6c\\x6f\\x67'\]\((_0x([a-f0-9]){4,6})\);/;
it('should transform catch clause node', () => {
assert.match(obfuscatedCode, paramNameRegExp);
@@ -37,4 +37,22 @@ describe('CatchClauseTransformer', () => {
assert.equal(firstMatch, secondMatch);
});
});
describe('object pattern as parameter', () => {
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
readFileAsString(__dirname + '/fixtures/object-pattern-as-parameter.js'),
{
...NO_CUSTOM_NODES_PRESET
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
it('shouldn\'t transform function parameter object pattern identifier', () => {
const functionParameterMatch: RegExp = /\} *catch *\(\{ *name *\}\) *\{/;
const functionBodyMatch: RegExp = /return *name;/;
assert.match(obfuscatedCode, functionParameterMatch);
assert.match(obfuscatedCode, functionBodyMatch);
});
});
});
@@ -0,0 +1,7 @@
(function () {
try {
} catch ({ name }) {
return name;
}
})();
@@ -32,9 +32,9 @@ describe('FunctionDeclarationTransformer', () => {
it('should transform function name if `functionDeclaration` parent block scope is not a `ProgramNode`', () => {
const functionNameIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/function *_0x[a-z0-9]{4,6} *\(\) *\{/);
.match(/function *_0x[a-f0-9]{4,6} *\(\) *\{/);
const functionCallIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/_0x[a-z0-9]{4,6} *\( *\);/);
.match(/_0x[a-f0-9]{4,6} *\( *\);/);
const functionParamIdentifierName: string = (<RegExpMatchArray>functionNameIdentifierMatch)[1];
const functionBodyIdentifierName: string = (<RegExpMatchArray>functionCallIdentifierMatch)[1];
@@ -20,9 +20,9 @@ describe('FunctionTransformer', () => {
it('should correct transform both function parameter identifier and function body identifier with same name', () => {
const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/var _0x[a-z0-9]{4,6} *= *function *\((_0x[a-z0-9]{4,6})\) *\{/);
.match(/var _0x[a-f0-9]{4,6} *= *function *\((_0x[a-f0-9]{4,6})\) *\{/);
const functionBodyIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{4,6})\)/);
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
const functionParamIdentifierName: string = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
const functionBodyIdentifierName: string = (<RegExpMatchArray>functionBodyIdentifierMatch)[1];
@@ -34,4 +34,22 @@ describe('FunctionTransformer', () => {
assert.equal(/variable *= *0x6;/.test(obfuscatedCode), true);
});
});
describe('object pattern as parameter', () => {
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
readFileAsString(__dirname + '/fixtures/object-pattern-as-parameter.js'),
{
...NO_CUSTOM_NODES_PRESET
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
it('shouldn\'t transform function parameter object pattern identifier', () => {
const functionParameterMatch: RegExp = /function *\(\{ *bar *\}\) *\{/;
const functionBodyMatch: RegExp = /return *bar;/;
assert.match(obfuscatedCode, functionParameterMatch);
assert.match(obfuscatedCode, functionBodyMatch);
});
});
});
@@ -0,0 +1,5 @@
(function () {
var test = function ({ bar }) {
return bar;
}
})();
@@ -17,9 +17,9 @@ describe('LabeledStatementTransformer', () => {
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const labeledStatementRegExp: RegExp = /(_0x([a-z0-9]){4,6}): *\{/;
const continueStatementRegExp: RegExp = /continue *(_0x([a-z0-9]){4,6});/;
const breakStatementRegExp: RegExp = /break *(_0x([a-z0-9]){4,6});/;
const labeledStatementRegExp: RegExp = /(_0x([a-f0-9]){4,6}): *\{/;
const continueStatementRegExp: RegExp = /continue *(_0x([a-f0-9]){4,6});/;
const breakStatementRegExp: RegExp = /break *(_0x([a-f0-9]){4,6});/;
it('should transform `labeledStatement` identifier', () => {
assert.match(obfuscatedCode, labeledStatementRegExp);
@@ -33,9 +33,9 @@ describe('LiteralTransformer', () => {
assert.match(
obfuscationResult.getObfuscatedCode(),
/^var *_0x([a-z0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
/^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
});
it('should create only one item in string array for same literal node values', () => {
@@ -50,9 +50,9 @@ describe('LiteralTransformer', () => {
assert.match(
obfuscationResult.getObfuscatedCode(),
/^var *_0x([a-z0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
/^var *_0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
});
it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` is disabled', () => {
@@ -68,9 +68,9 @@ describe('LiteralTransformer', () => {
assert.match(
obfuscationResult.getObfuscatedCode(),
/^var *_0x([a-z0-9]){4} *= *\['test'\];/
/^var *_0x([a-f0-9]){4} *= *\['test'\];/
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
});
it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` and `stringArray` are disabled', () => {
@@ -126,9 +126,9 @@ describe('LiteralTransformer', () => {
assert.match(
obfuscationResult.getObfuscatedCode(),
/^var *_0x([a-z0-9]){4} *= *\['\\x64\\x47\\x56\\x7a\\x64\\x41\\x3d\\x3d'\];/
/^var *_0x([a-f0-9]){4} *= *\['\\x64\\x47\\x56\\x7a\\x64\\x41\\x3d\\x3d'\];/
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/);
});
it('should replace literal node value with value from string array encoded using rc4', () => {
@@ -144,7 +144,7 @@ describe('LiteralTransformer', () => {
assert.match(
obfuscationResult.getObfuscatedCode(),
/var *test *= *_0x([a-z0-9]){4}\('0x0', '(\\x[a-f0-9]*){4}'\);/
/var *test *= *_0x([a-f0-9]){4}\('0x0', '(\\x[a-f0-9]*){4}'\);/
);
});
@@ -161,7 +161,7 @@ describe('LiteralTransformer', () => {
}
);
const regExp1: RegExp = /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/g;
const regExp1: RegExp = /var *test *= *_0x([a-f0-9]){4}\('0x0'\);/g;
const regExp2: RegExp = /var *test *= *'\\x74\\x65\\x73\\x74';/g;
const stringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp1)!.length;
const noStringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp2)!.length;
@@ -31,8 +31,8 @@ describe('MemberExpressionTransformer', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-z0-9]){4}\('0x0'\)\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/);
});
});
@@ -47,8 +47,8 @@ describe('MemberExpressionTransformer', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-z0-9]){4}\('0x0'\)\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4} *= *\['\\x6c\\x6f\\x67'\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *console\[_0x([a-f0-9]){4}\('0x0'\)\];/);
});
it('should ignore square brackets call with identifier value', () => {
@@ -32,8 +32,8 @@ describe('MethodDefinitionTransformer', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4} *= *\['\\x62\\x61\\x72'\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /\[_0x([a-z0-9]){4}\('0x0'\)\]\(\)\{\}/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4} *= *\['\\x62\\x61\\x72'\];/);
assert.match(obfuscationResult.getObfuscatedCode(), /\[_0x([a-f0-9]){4}\('0x0'\)\]\(\)\{\}/);
});
it('should not transform method definition node with `constructor` key', () => {
@@ -41,7 +41,7 @@ describe('ObjectExpressionTransformer', () => {
assert.match(
obfuscationResult.getObfuscatedCode(),
/var *_0x[a-z0-9]{4,6} *= *\{'\\x61': *_0x[a-z0-9]{4,6}\, *'\\x62': *_0x[a-z0-9]{4,6}\};/
/var *_0x[a-f0-9]{4,6} *= *\{'\\x61': *_0x[a-f0-9]{4,6}\, *'\\x62': *_0x[a-f0-9]{4,6}\};/
);
});
});
@@ -17,8 +17,8 @@ describe('VariableDeclarationTransformer', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-z0-9]){4,6} *= *'\\x61\\x62\\x63';/);
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /var *_0x([a-f0-9]){4,6} *= *'\\x61\\x62\\x63';/);
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
});
it('should not transform `variableDeclaration` node if parent block scope node is `Program` node', () => {
@@ -41,7 +41,7 @@ describe('VariableDeclarationTransformer', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
});
it('should not transform variable call (`identifier` node) outside of block scope of node in which this variable was declared with `let` kind', () => {
@@ -68,57 +68,100 @@ describe('VariableDeclarationTransformer', () => {
});
it('should transform variable call (`identifier` node) before variable declaration if this call is inside function body', () => {
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\['\\x69\\x74\\x65\\x6d'\]\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\['\\x69\\x74\\x65\\x6d'\]\);/);
});
it('should not transform variable call (`identifier` node) before variable declaration', () => {
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
assert.match(obfuscationResult.getObfuscatedCode(), /console\['\\x6c\\x6f\\x67'\]\(_0x([a-f0-9]){4,6}\);/);
});
});
describe(`variable calls before variable declaration when function param has the same name as variables name`, () => {
let obfuscationResult: IObfuscationResult,
functionParamIdentifierName: string|null,
innerFunctionParamIdentifierName: string|null,
constructorIdentifierName: string|null,
objectIdentifierName: string|null,
variableDeclarationIdentifierName: string|null;
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
readFileAsString(__dirname + '/fixtures/variable-call-before-variable-declaration-2.js'),
{
...NO_CUSTOM_NODES_PRESET
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
beforeEach(() => {
obfuscationResult = JavaScriptObfuscator.obfuscate(
readFileAsString(__dirname + '/fixtures/variable-call-before-variable-declaration-2.js'),
{
...NO_CUSTOM_NODES_PRESET
}
);
const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/function *_0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\,(_0x[a-f0-9]{4,6})\) *\{/);
const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/);
const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/return\{'\\x74':(_0x[a-f0-9]{4,6})\}/);
const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/var *(_0x[a-f0-9]{4,6});/);
const outerFunctionParamIdentifierName: string|null = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
const innerFunctionParamIdentifierName: string|null = (<RegExpMatchArray>innerFunctionParamIdentifierMatch)[1];
const constructorIdentifierName: string|null = (<RegExpMatchArray>constructorIdentifierMatch)[1];
const objectIdentifierName: string|null = (<RegExpMatchArray>objectIdentifierMatch)[1];
const variableDeclarationIdentifierName: string|null = (<RegExpMatchArray>variableDeclarationIdentifierMatch)[1];
it('should\'t name variables inside inner function with names from outer function params', () => {
assert.notEqual(outerFunctionParamIdentifierName, constructorIdentifierName);
assert.notEqual(outerFunctionParamIdentifierName, innerFunctionParamIdentifierName);
});
it('should correct transform variables inside function body', () => {
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/function *_0x[a-z0-9]{4,6} *\((_0x[a-z0-9]{4,6})\,(_0x[a-z0-9]{4,6})\) *\{/);
const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/function _0x[a-z0-9]{4,6} *\((_0x[a-z0-9]{4,6})\) *\{/);
const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{4,6})\)/);
const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/return\{'\\x74':(_0x[a-z0-9]{4,6})\}/);
const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/var *(_0x[a-z0-9]{4,6});/);
it('should correct transform variables inside outer function body', () => {
assert.equal(outerFunctionParamIdentifierName, objectIdentifierName);
assert.equal(outerFunctionParamIdentifierName, variableDeclarationIdentifierName);
});
functionParamIdentifierName = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
innerFunctionParamIdentifierName = (<RegExpMatchArray>innerFunctionParamIdentifierMatch)[1];
constructorIdentifierName = (<RegExpMatchArray>constructorIdentifierMatch)[1];
objectIdentifierName = (<RegExpMatchArray>objectIdentifierMatch)[1];
variableDeclarationIdentifierName = (<RegExpMatchArray>variableDeclarationIdentifierMatch)[1];
it('should correct transform variables inside inner function body', () => {
assert.equal(innerFunctionParamIdentifierName, constructorIdentifierName);
});
it('should keep equal names after transformation for variables with same names', () => {
assert.equal(variableDeclarationIdentifierName, objectIdentifierName);
});
});
describe(`variable calls before variable declaration when catch clause param has the same name as variables name`, () => {
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
readFileAsString(__dirname + '/fixtures/variable-call-before-variable-declaration-3.js'),
{
...NO_CUSTOM_NODES_PRESET
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
const catchClauseParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/catch *\((_0x[a-f0-9]{4,6})\) *\{/);
const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/function _0x[a-f0-9]{4,6} *\((_0x[a-f0-9]{4,6})\) *\{/);
const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-f0-9]{4,6})\)/);
const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/return\{'\\x74':(_0x[a-f0-9]{4,6})\}/);
const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
.match(/var *(_0x[a-f0-9]{4,6});/);
const functionParamIdentifierName: string|null = (<RegExpMatchArray>catchClauseParamIdentifierMatch)[1];
const innerFunctionParamIdentifierName: string|null = (<RegExpMatchArray>innerFunctionParamIdentifierMatch)[1];
const constructorIdentifierName: string|null = (<RegExpMatchArray>constructorIdentifierMatch)[1];
const objectIdentifierName: string|null = (<RegExpMatchArray>objectIdentifierMatch)[1];
const variableDeclarationIdentifierName: string|null = (<RegExpMatchArray>variableDeclarationIdentifierMatch)[1];
it('should\'t name variables inside inner function with names from catch clause param', () => {
assert.notEqual(functionParamIdentifierName, constructorIdentifierName);
assert.notEqual(functionParamIdentifierName, innerFunctionParamIdentifierName);
});
it('should correct transform variables inside catch clause body', () => {
assert.equal(functionParamIdentifierName, objectIdentifierName);
assert.equal(functionParamIdentifierName, variableDeclarationIdentifierName);
});
it('should correct transform variables inside inner function body', () => {
assert.equal(innerFunctionParamIdentifierName, constructorIdentifierName);
});
it('should keep equal names after transformation for variables with same names', () => {
assert.equal(variableDeclarationIdentifierName, objectIdentifierName);
});
});
@@ -132,7 +175,7 @@ describe('VariableDeclarationTransformer', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-z0-9]){4,6} *= *\{'\\x74\\x65\\x73\\x74/);
assert.match(obfuscationResult.getObfuscatedCode(), /var _0x([a-f0-9]){4,6} *= *\{'\\x74\\x65\\x73\\x74/);
});
it('shouldn\'t replace computed member expression identifier', () => {
@@ -143,7 +186,25 @@ describe('VariableDeclarationTransformer', () => {
}
);
assert.match(obfuscationResult.getObfuscatedCode(), /_0x([a-z0-9]){4,6}\['\\x74\\x65\\x73\\x74'\]/);
assert.match(obfuscationResult.getObfuscatedCode(), /_0x([a-f0-9]){4,6}\['\\x74\\x65\\x73\\x74'\]/);
});
});
describe('object pattern as variable declarator', () => {
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
readFileAsString(__dirname + '/fixtures/object-pattern.js'),
{
...NO_CUSTOM_NODES_PRESET
}
);
const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
it('shouldn\'t transform object pattern variable declarator', () => {
const objectPatternVariableDeclarator: RegExp = /var *\{ *bar *\} *= *\{ *'\\x62\\x61\\x72' *: *'\\x66\\x6f\\x6f' *\};/;
const variableUsageMatch: RegExp = /console\['\\x6c\\x6f\\x67'\]\(bar\);/;
assert.match(obfuscatedCode, objectPatternVariableDeclarator);
assert.match(obfuscatedCode, variableUsageMatch);
});
});
});
@@ -0,0 +1,4 @@
(function () {
var { bar } = { bar: 'foo' };
console.log(bar);
})();
@@ -0,0 +1,14 @@
(function () {
try {
} catch (t) {
return function () {
function baz (t) {
console.log(t);
}
return {t: t};
var t;
}();
}
})();
@@ -5,8 +5,8 @@ import { RandomGeneratorUtils } from '../../../../src/utils/RandomGeneratorUtils
describe('RandomGeneratorUtils', () => {
describe('getRandomVariableName (length: number = 6): string', () => {
it('should return a string of given length with random variable name', () => {
assert.match(RandomGeneratorUtils.getRandomVariableName(4, true, false), /^_0x(\w){4}$/);
assert.match(RandomGeneratorUtils.getRandomVariableName(6, true, true), /^_0x(\w){4,6}$/);
assert.match(RandomGeneratorUtils.getRandomVariableName(4), /^_0x(\w){4}$/);
assert.match(RandomGeneratorUtils.getRandomVariableName(6), /^_0x(\w){4,6}$/);
});
});
});
+5 -1
View File
@@ -29,6 +29,7 @@
true,
"always-prefix"
],
"import-spacing": true,
"jsdoc-format": true,
"label-position": true,
"max-line-length": false,
@@ -66,7 +67,7 @@
"no-parameter-properties": true,
"no-reference": true,
"no-require-imports": false,
"no-shadowed-variable": false,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-string-throw": true,
"no-switch-case-fall-through": false,
@@ -89,6 +90,7 @@
"quotemark": false,
"radix": true,
"semicolon": [true, "always"],
"space-before-function-paren": true,
"switch-default": false,
"trailing-comma": false,
"triple-equals": [
@@ -122,6 +124,8 @@
"variable-declaration": "space"
}
],
"typeof-compare": true,
"unified-signatures": true,
"use-isnan": true,
"variable-name": false,
"whitespace": [