diff --git a/dist/index.js b/dist/index.js index 19c782cf..5ea40703 100644 --- a/dist/index.js +++ b/dist/index.js @@ -90,7 +90,7 @@ module.exports = /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 150); +/******/ return __webpack_require__(__webpack_require__.s = 151); /******/ }) /************************************************************************/ /******/ ([ @@ -567,6 +567,11 @@ var Node = function () { value: function isArrowFunctionExpressionNode(node) { return node.type === NodeType_1.NodeType.ArrowFunctionExpression; } + }, { + key: "isAssignmentPatternNode", + value: function isAssignmentPatternNode(node) { + return node.type === NodeType_1.NodeType.AssignmentPattern; + } }, { key: "isBlockStatementNode", value: function isBlockStatementNode(node) { @@ -635,6 +640,11 @@ var Node = function () { value: function isMemberExpressionNode(node) { return node.type === NodeType_1.NodeType.MemberExpression; } + }, { + key: "isObjectPatternNode", + value: function isObjectPatternNode(node) { + return node.type === NodeType_1.NodeType.ObjectPattern; + } }, { key: "isObjectExpressionNode", value: function isObjectExpressionNode(node) { @@ -1002,6 +1012,7 @@ exports.NodeType = Utils_1.Utils.strEnumify({ ArrayExpression: 'ArrayExpression', ArrowFunctionExpression: 'ArrowFunctionExpression', AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', BinaryExpression: 'BinaryExpression', BlockStatement: 'BlockStatement', BreakStatement: 'BreakStatement', @@ -1020,6 +1031,7 @@ exports.NodeType = Utils_1.Utils.strEnumify({ MemberExpression: 'MemberExpression', MethodDefinition: 'MethodDefinition', ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', Program: 'Program', Property: 'Property', ReturnStatement: 'ReturnStatement', @@ -6032,9 +6044,20 @@ var FunctionTransformer = function (_AbstractNodeTransfor) { var _this2 = this; functionNode.params.forEach(function (paramsNode) { - if (Node_1.Node.isIdentifierNode(paramsNode)) { - _this2.identifierReplacer.storeNames(paramsNode.name, nodeIdentifier); + if (Node_1.Node.isObjectPatternNode(paramsNode)) { + return estraverse.VisitorOption.Skip; } + estraverse.traverse(paramsNode, { + enter: function enter(node) { + if (Node_1.Node.isAssignmentPatternNode(node) && Node_1.Node.isIdentifierNode(node.left)) { + _this2.identifierReplacer.storeNames(node.left.name, nodeIdentifier); + return estraverse.VisitorOption.Skip; + } + if (Node_1.Node.isIdentifierNode(node)) { + _this2.identifierReplacer.storeNames(node.name, nodeIdentifier); + } + } + }); }); } }, { @@ -8121,7 +8144,8 @@ module.exports = require("mkdirp"); module.exports = require("reflect-metadata"); /***/ }), -/* 150 */ +/* 150 */, +/* 151 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; diff --git a/src/enums/NodeType.ts b/src/enums/NodeType.ts index dd3fc540..6fea420c 100644 --- a/src/enums/NodeType.ts +++ b/src/enums/NodeType.ts @@ -4,6 +4,7 @@ export const NodeType: any = Utils.strEnumify({ ArrayExpression: 'ArrayExpression', ArrowFunctionExpression: 'ArrowFunctionExpression', AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', BinaryExpression: 'BinaryExpression', BlockStatement: 'BlockStatement', BreakStatement: 'BreakStatement', @@ -22,6 +23,7 @@ export const NodeType: any = Utils.strEnumify({ MemberExpression: 'MemberExpression', MethodDefinition: 'MethodDefinition', ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', Program: 'Program', Property: 'Property', ReturnStatement: 'ReturnStatement', diff --git a/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts b/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts index 2a3f6e84..03a83725 100644 --- a/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts +++ b/src/node-transformers/obfuscating-transformers/FunctionTransformer.ts @@ -61,9 +61,23 @@ export class FunctionTransformer extends AbstractNodeTransformer { private storeFunctionParams (functionNode: ESTree.Function, nodeIdentifier: number): void { functionNode.params .forEach((paramsNode: ESTree.Node) => { - if (Node.isIdentifierNode(paramsNode)) { - this.identifierReplacer.storeNames(paramsNode.name, nodeIdentifier); + if (Node.isObjectPatternNode(paramsNode)) { + return estraverse.VisitorOption.Skip; } + + estraverse.traverse(paramsNode, { + enter: (node: ESTree.Node): any => { + if (Node.isAssignmentPatternNode(node) && Node.isIdentifierNode(node.left)) { + this.identifierReplacer.storeNames(node.left.name, nodeIdentifier); + + return estraverse.VisitorOption.Skip; + } + + if (Node.isIdentifierNode(node)) { + this.identifierReplacer.storeNames(node.name, nodeIdentifier); + } + } + }); }); } diff --git a/src/node/Node.ts b/src/node/Node.ts index 046f092d..c5e84bc0 100644 --- a/src/node/Node.ts +++ b/src/node/Node.ts @@ -13,6 +13,14 @@ export class Node { return node.type === NodeType.ArrowFunctionExpression; } + /** + * @param node + * @returns {boolean} + */ + public static isAssignmentPatternNode (node: ESTree.Node): node is ESTree.AssignmentPattern { + return node.type === NodeType.AssignmentPattern; + } + /** * @param node * @returns {boolean} @@ -122,6 +130,14 @@ export class Node { return node.type === NodeType.MemberExpression; } + /** + * @param node + * @returns {boolean} + */ + public static isObjectPatternNode (node: ESTree.Node): node is ESTree.ObjectPattern { + return node.type === NodeType.ObjectPattern; + } + /** * @param node * @returns {boolean} diff --git a/test/dev/dev.ts b/test/dev/dev.ts index 6aa24259..04efc098 100644 --- a/test/dev/dev.ts +++ b/test/dev/dev.ts @@ -11,83 +11,10 @@ if (!(global)._babelPolyfill) { let obfuscatedCode: string = JavaScriptObfuscator.obfuscate( ` (function(){ - var result = 1, - term1 = 0, - term2 = 1, - i = 1; - while(i < 10) - { - var test = 10; - result = term1 + term2; - console.log(result); - term1 = term2; - term2 = result; - i++; - } - - console.log(test); - - var test = function (test) { - console.log(test); - - if (true) { - var test = 5 - } - - return test; - } - - console.log(test(1)); - - function test2 (abc) { - function test1 () { - console.log('inside', abc.item); - } - - console.log('ั‚ะตัั‚', abc); - - var abc = {}; - - return abc.item = 15, test1(); - }; - - var regexptest = /version\\/(\\d+)/i; - console.log(regexptest); - - test2(22); - console.log(105.4); - console.log(true, false); - - var sA = 'shorthand1'; - var sB = 'shorthand2'; - - console.log({sA, sB}); - - try { - } catch (error) { - console.log(error); - } - - function foo () { - return function () { - var sum1 = 10 + 20; - var sum2 = 20 + 30; - var sum3 = 30 + 50; - var sub = sum3 - sum2; - - return sum1 + sub; - } - } - - console.log(foo()()); - - if (true) { - console.log(\`1\`); - console.log(\`2\`); - console.log(\`3\`); - console.log(\`4\`); - console.log(\`5\`); - } + var foo = 1; + var test = function (foo, abc = foo) { + return foo, abc; + } })(); `, { diff --git a/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts index 95040aeb..76a9584e 100644 --- a/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts +++ b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts @@ -52,4 +52,90 @@ describe('FunctionTransformer', () => { assert.match(obfuscatedCode, functionBodyMatch); }); }); + + describe('assignment pattern as parameter', () => { + describe('literal as right value', () => { + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + readFileAsString(__dirname + '/fixtures/assignment-pattern-as-parameter-1.js'), + { + ...NO_CUSTOM_NODES_PRESET + } + ); + const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); + + it('should transform function parameter assignment pattern identifier', () => { + const functionParameterMatch: RegExp = /function *\(_0x[a-f0-9]{4,6} *= *0x1\) *\{/; + const functionBodyMatch: RegExp = /return *_0x[a-f0-9]{4,6};/; + + assert.match(obfuscatedCode, functionParameterMatch); + assert.match(obfuscatedCode, functionBodyMatch); + }); + }); + + describe('identifier as right value', () => { + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + readFileAsString(__dirname + '/fixtures/assignment-pattern-as-parameter-2.js'), + { + ...NO_CUSTOM_NODES_PRESET + } + ); + const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); + + const variableDeclarationMatch: RegExp = /var *(_0x[a-f0-9]{4,6}) *= *0x1;/; + const functionParameterMatch: RegExp = /function *\((_0x[a-f0-9]{4,6}), *(_0x[a-f0-9]{4,6}) *= *(_0x[a-f0-9]{4,6})\) *\{/; + const functionBodyMatch: RegExp = /return *(_0x[a-f0-9]{4,6}) *\+ *(_0x[a-f0-9]{4,6});/; + + const variableDeclarationIdentifierName: string = obfuscatedCode.match(variableDeclarationMatch)![1]; + const functionParameterIdentifierName: string = obfuscatedCode.match(functionParameterMatch)![1]; + const functionDefaultParameterIdentifierName1: string = obfuscatedCode.match(functionParameterMatch)![2]; + const functionDefaultParameterIdentifierName2: string = obfuscatedCode.match(functionParameterMatch)![3]; + + const functionBodyIdentifierName1: string = obfuscatedCode.match(functionBodyMatch)![1]; + const functionBodyIdentifierName2: string = obfuscatedCode.match(functionBodyMatch)![2]; + + it('should transform function parameter assignment pattern identifier', () => { + assert.match(obfuscatedCode, variableDeclarationMatch); + assert.match(obfuscatedCode, functionParameterMatch); + assert.match(obfuscatedCode, functionBodyMatch); + }); + + it('shouldn\'t keep same names variable declaration identifier and function parameters identifiers', () => { + assert.notEqual(variableDeclarationIdentifierName, functionParameterIdentifierName); + assert.notEqual(variableDeclarationIdentifierName, functionDefaultParameterIdentifierName1); + assert.notEqual(variableDeclarationIdentifierName, functionDefaultParameterIdentifierName2); + }); + + it('should keep same names for identifier in first function parameter and default value identifier of second function parameter', () => { + assert.equal(functionParameterIdentifierName, functionDefaultParameterIdentifierName2); + }); + + it('should keep same names for identifiers in function params and function body', () => { + assert.equal(functionParameterIdentifierName, functionBodyIdentifierName1); + assert.equal(functionDefaultParameterIdentifierName1, functionBodyIdentifierName2); + }); + }); + }); + + describe('array pattern as parameter', () => { + const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate( + readFileAsString(__dirname + '/fixtures/array-pattern-as-parameter.js'), + { + ...NO_CUSTOM_NODES_PRESET + } + ); + const obfuscatedCode: string = obfuscationResult.getObfuscatedCode(); + + const functionParameterMatch: RegExp = /function *\(\[(_0x[a-f0-9]{4,6}), *(_0x[a-f0-9]{4,6})\]\) *\{/; + const functionBodyMatch: RegExp = /return *(_0x[a-f0-9]{4,6}) *\+ *(_0x[a-f0-9]{4,6});/; + + const arrayPatternIdentifierName1: string = obfuscatedCode.match(functionParameterMatch)![1]; + const arrayPatternIdentifierName2: string = obfuscatedCode.match(functionParameterMatch)![2]; + const functionBodyIdentifierName1: string = obfuscatedCode.match(functionBodyMatch)![1]; + const functionBodyIdentifierName2: string = obfuscatedCode.match(functionBodyMatch)![2]; + + it('should keep same names for identifiers in function parameter array pattern and function body', () => { + assert.equal(arrayPatternIdentifierName1, functionBodyIdentifierName1); + assert.equal(arrayPatternIdentifierName2, functionBodyIdentifierName2); + }); + }); }); diff --git a/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/array-pattern-as-parameter.js b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/array-pattern-as-parameter.js new file mode 100644 index 00000000..1638b9a7 --- /dev/null +++ b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/array-pattern-as-parameter.js @@ -0,0 +1,5 @@ +(function () { + var test = function ([foo, bar]) { + return foo + bar; + } +})(); diff --git a/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/assignment-pattern-as-parameter-1.js b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/assignment-pattern-as-parameter-1.js new file mode 100644 index 00000000..f21992a4 --- /dev/null +++ b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/assignment-pattern-as-parameter-1.js @@ -0,0 +1,5 @@ +(function () { + var test = function (bar = 1) { + return bar; + } +})(); diff --git a/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/assignment-pattern-as-parameter-2.js b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/assignment-pattern-as-parameter-2.js new file mode 100644 index 00000000..9782200f --- /dev/null +++ b/test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/assignment-pattern-as-parameter-2.js @@ -0,0 +1,6 @@ +(function () { + var foo = 1; + var test = function (foo, bar = foo) { + return foo + bar; + } +})();