From 1b32b9397014c093eb145c26f3b962c7302f153d Mon Sep 17 00:00:00 2001 From: sanex3339 Date: Thu, 15 Jun 2017 21:51:04 +0300 Subject: [PATCH] es2017 async functions support --- package.json | 8 +- .../FunctionDeclarationTransformer.spec.ts | 121 +++++++++++++----- .../fixtures/async-function.js | 5 + .../fixtures/generator-function.js | 10 ++ .../DomainLockNodeTemplate.spec.ts | 4 +- test/helpers/getRegExpMatch.ts | 15 +++ yarn.lock | 22 +++- 7 files changed, 137 insertions(+), 48 deletions(-) create mode 100644 test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/async-function.js create mode 100644 test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/generator-function.js create mode 100644 test/helpers/getRegExpMatch.ts diff --git a/package.json b/package.json index 34fd1d84..32e41d05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-obfuscator", - "version": "0.10.0-beta.3", + "version": "0.10.0-beta.4", "description": "JavaScript obfuscator", "keywords": [ "obfuscator", @@ -24,7 +24,7 @@ "commander": "2.9.0", "escodegen-wallaby": "1.6.11", "esmangle": "1.0.1", - "esprima": "3.1.3", + "esprima": "4.0.0", "estraverse": "4.2.0", "inversify": "4.1.1", "mkdirp": "0.5.1", @@ -44,7 +44,7 @@ "@types/estree": "0.0.35", "@types/mkdirp": "0.3.29", "@types/mocha": "2.2.41", - "@types/node": "7.0.29", + "@types/node": "7.0.31", "@types/sinon": "2.3.1", "@types/string-template": "1.0.2", "awesome-typescript-loader": "3.1.3", @@ -57,7 +57,7 @@ "istanbul": "1.1.0-alpha.1", "mocha": "3.4.2", "pre-commit": "1.2.2", - "sinon": "2.3.3", + "sinon": "2.3.4", "ts-node": "3.0.6", "tslint": "5.4.3", "tslint-loader": "3.5.3", diff --git a/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts b/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts index 4ba82397..df05ca1c 100644 --- a/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts +++ b/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts @@ -7,42 +7,34 @@ import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCus import { readFileAsString } from '../../../../helpers/readFileAsString'; import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscator'; +import { getRegExpMatch } from '../../../../helpers/getRegExpMatch'; describe('FunctionDeclarationTransformer', () => { describe('transformation of `functionDeclaration` node names', () => { - let obfuscatedCode: string; - - before(() => { - const code: string = readFileAsString(__dirname + '/fixtures/input.js'); - const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( - code, - { - ...NO_CUSTOM_NODES_PRESET - } - ); - - obfuscatedCode = obfuscationResult.getObfuscatedCode(); - }); - describe('variant #1: `functionDeclaration` parent block scope is not a `ProgramNode`', () => { - const functionNameIdentifierRegExp: RegExp = /function *_0x[a-f0-9]{4,6} *\(\) *\{/; - const functionCallIdentifierRegExp: RegExp = /_0x[a-f0-9]{4,6} *\( *\);/; + const functionNameIdentifierRegExp: RegExp = /function *(_0x[a-f0-9]{4,6}) *\(\) *\{/; + const functionCallIdentifierRegExp: RegExp = /(_0x[a-f0-9]{4,6}) *\( *\);/; - let functionParamIdentifierName: string, - functionBodyIdentifierName: string; + let obfuscatedCode: string, + functionNameIdentifier: string, + functionCallIdentifier: string; before(() => { - const functionNameIdentifierMatch: RegExpMatchArray|null = obfuscatedCode - .match(functionNameIdentifierRegExp); - const functionCallIdentifierMatch: RegExpMatchArray|null = obfuscatedCode - .match(functionCallIdentifierRegExp); + const code: string = readFileAsString(__dirname + '/fixtures/input.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_CUSTOM_NODES_PRESET + } + ); - functionParamIdentifierName = (functionNameIdentifierMatch)[1]; - functionBodyIdentifierName = (functionCallIdentifierMatch)[1]; + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + functionNameIdentifier = getRegExpMatch(obfuscatedCode, functionNameIdentifierRegExp); + functionCallIdentifier = getRegExpMatch(obfuscatedCode, functionCallIdentifierRegExp); }); it('should transform function name', () => { - assert.equal(functionParamIdentifierName, functionBodyIdentifierName); + assert.equal(functionNameIdentifier, functionCallIdentifier); }); }); @@ -50,21 +42,80 @@ describe('FunctionDeclarationTransformer', () => { const functionNameIdentifierRegExp: RegExp = /function *foo *\(\) *\{/; const functionCallIdentifierRegExp: RegExp = /foo *\( *\);/; - let functionParamIdentifierName: string, - functionBodyIdentifierName: string; + let obfuscatedCode: string; before(() => { - const functionNameIdentifierMatch: RegExpMatchArray|null = obfuscatedCode - .match(functionNameIdentifierRegExp); - const functionCallIdentifierMatch: RegExpMatchArray|null = obfuscatedCode - .match(functionCallIdentifierRegExp); + const code: string = readFileAsString(__dirname + '/fixtures/input.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_CUSTOM_NODES_PRESET + } + ); - functionParamIdentifierName = (functionNameIdentifierMatch)[1]; - functionBodyIdentifierName = (functionCallIdentifierMatch)[1]; + obfuscatedCode = obfuscationResult.getObfuscatedCode(); }); - it('shouldn\'t transform function name', () => { - assert.equal(functionParamIdentifierName, functionBodyIdentifierName); + it('match #1: shouldn\'t transform function name', () => { + assert.match(obfuscatedCode, functionNameIdentifierRegExp); + }); + + it('match #2: shouldn\'t transform function name', () => { + assert.match(obfuscatedCode, functionCallIdentifierRegExp); + }); + }); + + describe('variant #3: generator `functionDeclaration`', () => { + const functionNameIdentifierRegExp: RegExp = /function *\* *(_0x[a-f0-9]{4,6}) *\(\) *\{/; + const functionCallIdentifierRegExp: RegExp = /let *_0x[a-f0-9]{4,6} *= *(_0x[a-f0-9]{4,6}) *\( *\);/; + + let obfuscatedCode: string, + functionNameIdentifier: string, + functionCallIdentifier: string; + + before(() => { + const code: string = readFileAsString(__dirname + '/fixtures/generator-function.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_CUSTOM_NODES_PRESET + } + ); + + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + functionNameIdentifier = getRegExpMatch(obfuscatedCode, functionNameIdentifierRegExp); + functionCallIdentifier = getRegExpMatch(obfuscatedCode, functionCallIdentifierRegExp); + }); + + it('should transform generator function name', () => { + assert.equal(functionNameIdentifier, functionCallIdentifier); + }); + }); + + describe('variant #4: async `functionDeclaration`', () => { + const functionNameIdentifierRegExp: RegExp = /async *function *(_0x[a-f0-9]{4,6}) *\(\) *\{/; + const functionCallIdentifierRegExp: RegExp = /await *(_0x[a-f0-9]{4,6}) *\( *\);/; + + let obfuscatedCode: string, + functionNameIdentifier: string, + functionCallIdentifier: string; + + before(() => { + const code: string = readFileAsString(__dirname + '/fixtures/async-function.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_CUSTOM_NODES_PRESET + } + ); + + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + functionNameIdentifier = getRegExpMatch(obfuscatedCode, functionNameIdentifierRegExp); + functionCallIdentifier = getRegExpMatch(obfuscatedCode, functionCallIdentifierRegExp); + }); + + it('should transform async function name', () => { + assert.equal(functionNameIdentifier, functionCallIdentifier); }); }); }); diff --git a/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/async-function.js b/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/async-function.js new file mode 100644 index 00000000..4a397a23 --- /dev/null +++ b/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/async-function.js @@ -0,0 +1,5 @@ +(async function(){ + async function foo () {} + + await foo(); +})(); \ No newline at end of file diff --git a/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/generator-function.js b/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/generator-function.js new file mode 100644 index 00000000..d6aa3263 --- /dev/null +++ b/test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/fixtures/generator-function.js @@ -0,0 +1,10 @@ +(async function(){ + function* foo () { + yield 1; + yield 2; + + return 3; + } + + let bar = foo(); +})(); \ No newline at end of file diff --git a/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts b/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts index 480da5df..c64b6eff 100644 --- a/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts +++ b/test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts @@ -55,7 +55,7 @@ describe('DomainLockNodeTemplate (): string', () => { }, singleNodeCallControllerFunctionName, currentDomain); }); - it('should correctly runs code inside template', () => { + it('should correctly run code inside template', () => { assert.doesNotThrow(testFunc); }); }); @@ -80,7 +80,7 @@ describe('DomainLockNodeTemplate (): string', () => { }, singleNodeCallControllerFunctionName, currentDomain); }); - it('should correctly runs code inside template', () => { + it('should correctly run code inside template', () => { assert.doesNotThrow(testFunc); }); }); diff --git a/test/helpers/getRegExpMatch.ts b/test/helpers/getRegExpMatch.ts new file mode 100644 index 00000000..c816aed5 --- /dev/null +++ b/test/helpers/getRegExpMatch.ts @@ -0,0 +1,15 @@ +/** + * @param str + * @param regExp + * @param index + * @return {string} + */ +export function getRegExpMatch (str: string, regExp: RegExp, index: number = 1): string { + const match: RegExpMatchArray | null = str.match(regExp); + + if (!match) { + throw new Error(`No matches were found for regular expression \`${regExp.toString()}\``); + } + + return (match)[index]; +} diff --git a/yarn.lock b/yarn.lock index b377f3e8..4ad4149c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44,10 +44,14 @@ version "2.2.41" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.41.tgz#e27cf0817153eb9f2713b2d3f6c68f1e1c3ca608" -"@types/node@*", "@types/node@7.0.29": +"@types/node@*": version "7.0.29" resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.29.tgz#ccfcec5b7135c7caf6c4ffb8c7f33102340d99df" +"@types/node@7.0.31": + version "7.0.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.31.tgz#80ea4d175599b2a00149c29a10a4eb2dff592e86" + "@types/sinon@2.3.1": version "2.3.1" resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-2.3.1.tgz#5e214093e9e2345219ab0f31bf310c9790ad0712" @@ -1213,14 +1217,18 @@ esmangle@1.0.1: optionator "~0.3.0" source-map "~0.1.33" -esprima@3.1.3, esprima@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +esprima@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" +esprima@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + esprima@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" @@ -2844,9 +2852,9 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sinon@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.3.3.tgz#fc09e93451e32cb2d08cab16a03bea69778853fc" +sinon@2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.3.4.tgz#466ad8d1bae86d6db51aa218b92e997bc3e5db88" dependencies: diff "^3.1.0" formatio "1.2.0"