diff --git a/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec.ts b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec.ts new file mode 100644 index 00000000..11a70c5d --- /dev/null +++ b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec.ts @@ -0,0 +1,159 @@ +import { assert } from 'chai'; + +import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult'; + +import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes'; + +import { readFileAsString } from '../../../../helpers/readFileAsString'; + +import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade'; +import { getRegExpMatch } from '../../../../helpers/getRegExpMatch'; + +describe('AstToEvalCallExpressionTransformer', () => { + describe('variant #1: identifier reference', () => { + const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/; + const variableReferenceIdentifierRegExp: RegExp = /eval *\('(_0x(?:[a-f0-9]){4,6});'\);/; + + let functionIdentifierName: string | null, + obfuscatedCode: string, + variableReferenceIdentifierName: string | null; + + before(() => { + const code: string = readFileAsString(__dirname + '/fixtures/identifier-reference.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_ADDITIONAL_NODES_PRESET + } + ); + + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + + functionIdentifierName = getRegExpMatch(obfuscatedCode, functionIdentifierRegExp); + variableReferenceIdentifierName = getRegExpMatch(obfuscatedCode, variableReferenceIdentifierRegExp); + }); + + it('should obfuscate eval string', () => { + assert.match(obfuscatedCode, variableReferenceIdentifierRegExp); + }); + + it('should correctly transform function parameter inside eval expression', () => { + assert.equal(functionIdentifierName, variableReferenceIdentifierName); + }); + }); + + describe('variant #2: call expression with identifier reference', () => { + const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/; + const variableReferenceIdentifierRegExp: RegExp = /eval *\('console\[\\'log\\']\((_0x(?:[a-f0-9]){4,6})\);'\);/; + + let functionIdentifierName: string | null, + obfuscatedCode: string, + variableReferenceIdentifierName: string | null; + + before(() => { + const code: string = readFileAsString(__dirname + '/fixtures/call-expression-identifier-reference.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_ADDITIONAL_NODES_PRESET + } + ); + + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + + functionIdentifierName = getRegExpMatch(obfuscatedCode, functionIdentifierRegExp); + variableReferenceIdentifierName = getRegExpMatch(obfuscatedCode, variableReferenceIdentifierRegExp); + }); + + it('should obfuscate eval string', () => { + assert.match(obfuscatedCode, variableReferenceIdentifierRegExp); + }); + + it('should correctly transform function parameter inside eval expression', () => { + assert.equal(functionIdentifierName, variableReferenceIdentifierName); + }); + }); + + describe('variant #3: multiple statements in eval', () => { + const regExp: RegExp = /eval *\('_0x([a-f0-9]){4,6}; *\\n_0x([a-f0-9]){4,6};'\);/; + + let obfuscatedCode: string; + + before(() => { + const code: string = readFileAsString(__dirname + '/fixtures/multiple-statements-eval.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_ADDITIONAL_NODES_PRESET + } + ); + + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + }); + + it('should obfuscate eval string', () => { + assert.match(obfuscatedCode, regExp); + }); + }); + + describe('variant #4: string array calls wrapper call', () => { + const stringArrayRegExp: RegExp = /var *_0x([a-f0-9]){4} *= *\['log', *'bar'];/; + const stringArrayCallsWrapperRegExp: RegExp = /eval *\('console\[_0x([a-f0-9]){4,6}\(\\'0x0\\'\)]\(_0x([a-f0-9]){4,6}\(\\'0x1\\'\)\);'\);/; + + let obfuscatedCode: string; + + before(() => { + const code: string = readFileAsString(__dirname + '/fixtures/string-array-calls-wrapper-call.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_ADDITIONAL_NODES_PRESET, + stringArray: true, + stringArrayThreshold: 1 + } + ); + + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + }); + + it('match #1: should add strings from eval expression to the string array', () => { + assert.match(obfuscatedCode, stringArrayRegExp); + }); + + it('match #1: should replace string with call to the string array calls wrapper', () => { + assert.match(obfuscatedCode, stringArrayCallsWrapperRegExp); + }); + }); + + describe('variant #5: eval expression as argument', () => { + const functionIdentifierRegExp: RegExp = /function *_0x(?:[a-f0-9]){4,6} *\((_0x(?:[a-f0-9]){4,6})\)/; + const variableReferenceIdentifierRegExp: RegExp = /console\['log']\(eval *\('(_0x(?:[a-f0-9]){4,6});'\)\);/; + + let functionIdentifierName: string | null, + obfuscatedCode: string, + variableReferenceIdentifierName: string | null; + + before(() => { + const code: string = readFileAsString(__dirname + '/fixtures/eval-expression-as-argument.js'); + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + code, + { + ...NO_ADDITIONAL_NODES_PRESET + } + ); + + obfuscatedCode = obfuscationResult.getObfuscatedCode(); + + functionIdentifierName = getRegExpMatch(obfuscatedCode, functionIdentifierRegExp); + variableReferenceIdentifierName = getRegExpMatch(obfuscatedCode, variableReferenceIdentifierRegExp); + }); + + it('should obfuscate eval string', () => { + assert.match(obfuscatedCode, variableReferenceIdentifierRegExp); + }); + + it('should correctly transform function parameter inside eval expression', () => { + assert.equal(functionIdentifierName, variableReferenceIdentifierName); + }); + }); +}); diff --git a/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/call-expression-identifier-reference.js b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/call-expression-identifier-reference.js new file mode 100644 index 00000000..48d8b4ef --- /dev/null +++ b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/call-expression-identifier-reference.js @@ -0,0 +1,7 @@ +(function(){ + function foo (bar) { + eval('console.log(bar);'); + } + + foo(1); +})(); \ No newline at end of file diff --git a/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/eval-expression-as-argument.js b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/eval-expression-as-argument.js new file mode 100644 index 00000000..f59e32ca --- /dev/null +++ b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/eval-expression-as-argument.js @@ -0,0 +1,7 @@ +(function(){ + function foo (bar) { + console.log(eval('bar;')); + } + + foo(1); +})(); \ No newline at end of file diff --git a/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/identifier-reference.js b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/identifier-reference.js new file mode 100644 index 00000000..9d46a47e --- /dev/null +++ b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/identifier-reference.js @@ -0,0 +1,7 @@ +(function(){ + function foo (bar) { + eval('bar'); + } + + foo(1); +})(); \ No newline at end of file diff --git a/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/multiple-statements-eval.js b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/multiple-statements-eval.js new file mode 100644 index 00000000..e3ae0ef7 --- /dev/null +++ b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/multiple-statements-eval.js @@ -0,0 +1,7 @@ +(function(){ + function foo (bar, baz) { + eval('bar;baz;'); + } + + foo(1, 2); +})(); \ No newline at end of file diff --git a/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/string-array-calls-wrapper-call.js b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/string-array-calls-wrapper-call.js new file mode 100644 index 00000000..60357464 --- /dev/null +++ b/test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/string-array-calls-wrapper-call.js @@ -0,0 +1,7 @@ +(function(){ + function foo () { + eval('console.log(\'bar\')'); + } + + foo(); +})(); \ No newline at end of file diff --git a/test/index.spec.ts b/test/index.spec.ts index f488ba7e..fe4fe0e2 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -51,6 +51,7 @@ import './functional-tests/node-transformers/control-flow-transformers/control-f import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec'; import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec'; import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/string-litertal-control-flow-replacer/StringLiteralControlFlowReplacer.spec'; +import './functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.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/object-expression-keys-transformer/ObjectExpressionKeysTransformer.spec';