Skip to content

Commit

Permalink
Merge pull request #792 from javascript-obfuscator/export-specifier-t…
Browse files Browse the repository at this point in the history
…ransformer

Added `ExportSpecifierTransformer`
  • Loading branch information
sanex3339 committed Oct 28, 2020
2 parents d07574a + 229c99f commit 867c125
Show file tree
Hide file tree
Showing 16 changed files with 294 additions and 84 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
Change Log

v2.6.3
---
* Added `ExportSpecifierTransformer`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/791

v2.6.2
---
* Fixed installation in `PowerShell`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/783
Expand Down
2 changes: 1 addition & 1 deletion dist/index.browser.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.cli.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "2.6.2",
"version": "2.6.3",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand All @@ -27,7 +27,7 @@
"chalk": "4.1.0",
"chance": "1.1.7",
"class-validator": "0.12.2",
"commander": "6.1.0",
"commander": "6.2.0",
"escodegen": "2.0.0",
"eslint-scope": "5.1.1",
"estraverse": "5.2.0",
Expand Down Expand Up @@ -58,18 +58,18 @@
"@types/mkdirp": "1.0.1",
"@types/mocha": "8.0.3",
"@types/multimatch": "4.0.0",
"@types/node": "14.14.2",
"@types/node": "14.14.5",
"@types/rimraf": "3.0.0",
"@types/sinon": "9.0.8",
"@types/string-template": "1.0.2",
"@types/webpack-env": "1.15.3",
"@typescript-eslint/eslint-plugin": "4.5.0",
"@typescript-eslint/parser": "4.5.0",
"@typescript-eslint/eslint-plugin": "4.6.0",
"@typescript-eslint/parser": "4.6.0",
"chai": "4.2.0",
"chai-exclude": "2.0.2",
"coveralls": "3.1.0",
"cross-env": "7.0.2",
"eslint": "7.12.0",
"eslint": "7.12.1",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsdoc": "30.7.3",
"eslint-plugin-no-null": "1.0.2",
Expand All @@ -84,10 +84,10 @@
"rimraf": "3.0.2",
"sinon": "9.2.0",
"threads": "1.6.3",
"ts-loader": "8.0.6",
"ts-loader": "8.0.7",
"ts-node": "9.0.0",
"typescript": "4.1.0-beta",
"webpack": "5.2.0",
"webpack": "5.3.0",
"webpack-cli": "4.1.0",
"webpack-node-externals": "2.5.2"
},
Expand Down
1 change: 1 addition & 0 deletions src/JavaScriptObfuscator.ts
Expand Up @@ -70,6 +70,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
NodeTransformer.DeadCodeInjectionTransformer,
NodeTransformer.EscapeSequenceTransformer,
NodeTransformer.EvalCallExpressionTransformer,
NodeTransformer.ExportSpecifierTransformer,
NodeTransformer.ExpressionStatementsMergeTransformer,
NodeTransformer.FunctionControlFlowTransformer,
NodeTransformer.IfStatementSimplifyTransformer,
Expand Down
Expand Up @@ -10,6 +10,7 @@ import { ObjectExpressionExtractor } from '../../../enums/node-transformers/conv

import { BasePropertiesExtractor } from '../../../node-transformers/converting-transformers/object-expression-extractors/BasePropertiesExtractor';
import { BooleanLiteralTransformer } from '../../../node-transformers/converting-transformers/BooleanLiteralTransformer';
import { ExportSpecifierTransformer } from '../../../node-transformers/converting-transformers/ExportSpecifierTransformer';
import { MemberExpressionTransformer } from '../../../node-transformers/converting-transformers/MemberExpressionTransformer';
import { MethodDefinitionTransformer } from '../../../node-transformers/converting-transformers/MethodDefinitionTransformer';
import { NumberLiteralTransformer } from '../../../node-transformers/converting-transformers/NumberLiteralTransformer';
Expand All @@ -27,6 +28,10 @@ export const convertingTransformersModule: interfaces.ContainerModule = new Cont
.to(BooleanLiteralTransformer)
.whenTargetNamed(NodeTransformer.BooleanLiteralTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ExportSpecifierTransformer)
.whenTargetNamed(NodeTransformer.ExportSpecifierTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(MemberExpressionTransformer)
.whenTargetNamed(NodeTransformer.MemberExpressionTransformer);
Expand Down
1 change: 1 addition & 0 deletions src/enums/node-transformers/NodeTransformer.ts
Expand Up @@ -7,6 +7,7 @@ export enum NodeTransformer {
DeadCodeInjectionTransformer = 'DeadCodeInjectionTransformer',
EscapeSequenceTransformer = 'EscapeSequenceTransformer',
EvalCallExpressionTransformer = 'EvalCallExpressionTransformer',
ExportSpecifierTransformer = 'ExportSpecifierTransformer',
ExpressionStatementsMergeTransformer = 'ExpressionStatementsMergeTransformer',
FunctionControlFlowTransformer = 'FunctionControlFlowTransformer',
IfStatementSimplifyTransformer = 'IfStatementSimplifyTransformer',
Expand Down
1 change: 1 addition & 0 deletions src/enums/node/NodeType.ts
Expand Up @@ -16,6 +16,7 @@ export enum NodeType {
ContinueStatement = 'ContinueStatement',
ExportAllDeclaration = 'ExportAllDeclaration',
ExportNamedDeclaration = 'ExportNamedDeclaration',
ExportSpecifier = 'ExportSpecifier',
ExpressionStatement = 'ExpressionStatement',
ForStatement = 'ForStatement',
ForInStatement = 'ForInStatement',
Expand Down
@@ -0,0 +1,67 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';

import * as ESTree from 'estree';

import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';

import { NodeTransformationStage } from '../../enums/node-transformers/NodeTransformationStage';

import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
import { NodeGuards } from '../../node/NodeGuards';
import { NodeUtils } from '../../node/NodeUtils';

@injectable()
export class ExportSpecifierTransformer extends AbstractNodeTransformer {
/**
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(randomGenerator, options);
}

/**
* @param {NodeTransformationStage} nodeTransformationStage
* @returns {IVisitor | null}
*/
public getVisitor (nodeTransformationStage: NodeTransformationStage): IVisitor | null {
switch (nodeTransformationStage) {
case NodeTransformationStage.Converting:
return {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node | undefined => {
if (parentNode && NodeGuards.isExportSpecifierNode(node)) {
return this.transformNode(node, parentNode);
}
}
};

default:
return null;
}
}

/**
* Replaces:
* export {foo};
*
* on:
* export {foo as foo};
*
* @param {ExportSpecifier} exportSpecifierNode
* @param {Node} parentNode
* @returns {Node}
*/
public transformNode (exportSpecifierNode: ESTree.ExportSpecifier, parentNode: ESTree.Node): ESTree.Node {
if (exportSpecifierNode.local.name === exportSpecifierNode.exported.name) {
exportSpecifierNode.exported = NodeUtils.clone(exportSpecifierNode.local);
}

return exportSpecifierNode;
}
}
8 changes: 8 additions & 0 deletions src/node/NodeGuards.ts
Expand Up @@ -132,6 +132,14 @@ export class NodeGuards {
return node.type === NodeType.ExportNamedDeclaration;
}

/**
* @param {Node} node
* @returns {boolean}
*/
public static isExportSpecifierNode (node: ESTree.Node): node is ESTree.ExportSpecifier {
return node.type === NodeType.ExportSpecifier;
}

/**
* @param {Node} node
* @returns {boolean}
Expand Down
@@ -0,0 +1,113 @@
import { assert } from 'chai';

import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';

import { readFileAsString } from '../../../../helpers/readFileAsString';

import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';

describe('ExportSpecifierTransformer', () => {
describe('Variant #1: exported constant', () => {
describe('Variant #1:`renameGlobals` option is enabled', () => {
const regExp: RegExp = new RegExp(
'const _0x([a-f0-9]){4,6} *= *0x1; *' +
'export *{_0x([a-f0-9]){4,6} as foo};'
);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/exported-constant.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});

it('should transform export specifier node', () => {
assert.match(obfuscatedCode, regExp);
});
});

describe('Variant #2: `renameGlobals` option is disabled', () => {
const regExp: RegExp = new RegExp(
'const foo *= *0x1; *' +
'export *{foo};'
);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/exported-constant.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: false
}
).getObfuscatedCode();
});

it('should not transform export specifier node', () => {
assert.match(obfuscatedCode, regExp);
});
});
});

describe('Variant #2: exported import', () => {
describe('Variant #1:`renameGlobals` option is enabled', () => {
const regExp: RegExp = new RegExp(
'import _0x([a-f0-9]){4,6} from *\'./bar\'; *' +
'export *{_0x([a-f0-9]){4,6} as foo};'
);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/exported-import.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});

it('should transform export specifier node', () => {
assert.match(obfuscatedCode, regExp);
});
});

describe('Variant #2: `renameGlobals` option is disabled', () => {
const regExp: RegExp = new RegExp(
'import _0x([a-f0-9]){4,6} from *\'./bar\'; *' +
'export *{_0x([a-f0-9]){4,6} as foo};'
);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/exported-import.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: false
}
).getObfuscatedCode();
});

it('should transform export specifier node', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
});
@@ -0,0 +1,2 @@
const foo = 1;
export {foo};
@@ -0,0 +1,2 @@
import foo from './bar';
export {foo};
1 change: 1 addition & 0 deletions test/index.spec.ts
Expand Up @@ -85,6 +85,7 @@ import './functional-tests/node-transformers/control-flow-transformers/control-f
import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/string-litertal-control-flow-replacer/StringLiteralControlFlowReplacer.spec';
import './functional-tests/node-transformers/control-flow-transformers/function-control-flow-transformer/FunctionControlFlowTransformer.spec';
import './functional-tests/node-transformers/converting-transformers/boolean-literal-transformer/BooleanLiteralTransformer.spec';
import './functional-tests/node-transformers/converting-transformers/export-specifier-transformer/ExportSpecifierTransformer.spec';
import './functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec';
import './functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec';
import './functional-tests/node-transformers/converting-transformers/number-literal-transformer/NumberLiteralTransformer.spec';
Expand Down

0 comments on commit 867c125

Please sign in to comment.