Browse Source

CatchClause obfuscator ObjectPattern fix
CatchClause obfuscator ObjectPattern test
Tests refactoring

sanex3339 8 years ago
parent
commit
3e3f772ae4

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 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

+ 68 - 70
dist/index.js

@@ -320,7 +320,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
 var escodegen = __webpack_require__(13);
 var esprima = __webpack_require__(25);
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var Node_1 = __webpack_require__(2);
 var Utils_1 = __webpack_require__(0);
 
@@ -452,7 +452,7 @@ var _createClass = (function () { function defineProperties(target, props) { for
 
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 
 var Node = function () {
     function Node() {
@@ -729,6 +729,46 @@ exports.NodeAppender = NodeAppender;
 
 /***/ },
 /* 6 */
+/***/ function(module, exports) {
+
+"use strict";
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var AbstractCustomNode = function () {
+    function AbstractCustomNode(options) {
+        _classCallCheck(this, AbstractCustomNode);
+
+        this.options = options;
+    }
+
+    _createClass(AbstractCustomNode, [{
+        key: "getAppendState",
+        value: function getAppendState() {
+            return this.appendState;
+        }
+    }, {
+        key: "getNode",
+        value: function getNode() {
+            return this.getNodeStructure();
+        }
+    }, {
+        key: "setAppendState",
+        value: function setAppendState(appendState) {
+            this.appendState = appendState;
+        }
+    }]);
+
+    return AbstractCustomNode;
+}();
+
+exports.AbstractCustomNode = AbstractCustomNode;
+
+/***/ },
+/* 7 */
 /***/ function(module, exports, __webpack_require__) {
 
 "use strict";
@@ -768,46 +808,6 @@ exports.NodeType = Utils_1.Utils.strEnumify({
     WhileStatement: 'WhileStatement'
 });
 
-/***/ },
-/* 7 */
-/***/ function(module, exports) {
-
-"use strict";
-"use strict";
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var AbstractCustomNode = function () {
-    function AbstractCustomNode(options) {
-        _classCallCheck(this, AbstractCustomNode);
-
-        this.options = options;
-    }
-
-    _createClass(AbstractCustomNode, [{
-        key: "getAppendState",
-        value: function getAppendState() {
-            return this.appendState;
-        }
-    }, {
-        key: "getNode",
-        value: function getNode() {
-            return this.getNodeStructure();
-        }
-    }, {
-        key: "setAppendState",
-        value: function setAppendState(appendState) {
-            this.appendState = appendState;
-        }
-    }]);
-
-    return AbstractCustomNode;
-}();
-
-exports.AbstractCustomNode = AbstractCustomNode;
-
 /***/ },
 /* 8 */
 /***/ function(module, exports) {
@@ -1054,7 +1054,7 @@ __webpack_require__(9);
 var AppendState_1 = __webpack_require__(3);
 var SingleNodeCallControllerTemplate_1 = __webpack_require__(67);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var JavaScriptObfuscator_1 = __webpack_require__(10);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
@@ -1495,7 +1495,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
 
 var estraverse = __webpack_require__(4);
 var AppendState_1 = __webpack_require__(3);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var CatchClauseObfuscator_1 = __webpack_require__(48);
 var ConsoleOutputNodesGroup_1 = __webpack_require__(43);
 var DebugProtectionNodesGroup_1 = __webpack_require__(44);
@@ -1977,7 +1977,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 __webpack_require__(9);
 var AppendState_1 = __webpack_require__(3);
 var ConsoleOutputDisableExpressionTemplate_1 = __webpack_require__(68);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
 var Utils_1 = __webpack_require__(0);
@@ -2035,7 +2035,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 __webpack_require__(9);
 var AppendState_1 = __webpack_require__(3);
 var DebufProtectionFunctionCallTemplate_1 = __webpack_require__(69);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
 
@@ -2089,7 +2089,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 __webpack_require__(9);
 var AppendState_1 = __webpack_require__(3);
 var DebugProtectionFunctionIntervalTemplate_1 = __webpack_require__(70);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
 
@@ -2143,7 +2143,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 __webpack_require__(9);
 var AppendState_1 = __webpack_require__(3);
 var DebugProtectionFunctionTemplate_1 = __webpack_require__(71);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
 var Utils_1 = __webpack_require__(0);
@@ -2207,7 +2207,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 __webpack_require__(9);
 var AppendState_1 = __webpack_require__(3);
 var DomainLockNodeTemplate_1 = __webpack_require__(72);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
 var Utils_1 = __webpack_require__(0);
@@ -2272,7 +2272,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 var AppendState_1 = __webpack_require__(3);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var SelfDefendingTemplate_1 = __webpack_require__(73);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(5);
 var JavaScriptObfuscator_1 = __webpack_require__(10);
 var NodeUtils_1 = __webpack_require__(1);
@@ -2342,7 +2342,7 @@ var SelfDefendingTemplate_1 = __webpack_require__(74);
 var StringArrayBase64DecodeNodeTemplate_1 = __webpack_require__(75);
 var StringArrayCallsWrapperTemplate_1 = __webpack_require__(76);
 var StringArrayRC4DecodeNodeTemplate_1 = __webpack_require__(77);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var JavaScriptObfuscator_1 = __webpack_require__(10);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
@@ -2449,7 +2449,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 __webpack_require__(9);
 var AppendState_1 = __webpack_require__(3);
 var StringArrayTemplate_1 = __webpack_require__(78);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
 
@@ -2538,7 +2538,7 @@ var AppendState_1 = __webpack_require__(3);
 var NoCustomNodesPreset_1 = __webpack_require__(16);
 var SelfDefendingTemplate_1 = __webpack_require__(79);
 var StringArrayRotateFunctionTemplate_1 = __webpack_require__(80);
-var AbstractCustomNode_1 = __webpack_require__(7);
+var AbstractCustomNode_1 = __webpack_require__(6);
 var JavaScriptObfuscator_1 = __webpack_require__(10);
 var NodeAppender_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
@@ -2877,11 +2877,9 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
 var AbstractNodeObfuscator_1 = __webpack_require__(8);
 var IdentifierReplacer_1 = __webpack_require__(12);
 var Node_1 = __webpack_require__(2);
-var NodeUtils_1 = __webpack_require__(1);
 
 var CatchClauseObfuscator = function (_AbstractNodeObfuscat) {
     _inherits(CatchClauseObfuscator, _AbstractNodeObfuscat);
@@ -2904,23 +2902,23 @@ var CatchClauseObfuscator = function (_AbstractNodeObfuscat) {
     }, {
         key: 'storeCatchClauseParam',
         value: function storeCatchClauseParam(catchClauseNode) {
-            var _this2 = this;
-
-            NodeUtils_1.NodeUtils.typedReplace(catchClauseNode.param, NodeType_1.NodeType.Identifier, {
-                enter: function enter(node) {
-                    return _this2.identifierReplacer.storeNames(node.name);
-                }
-            });
+            if (Node_1.Node.isIdentifierNode(catchClauseNode.param)) {
+                this.identifierReplacer.storeNames(catchClauseNode.param.name);
+            }
         }
     }, {
         key: 'replaceCatchClauseParam',
         value: function replaceCatchClauseParam(catchClauseNode) {
-            var _this3 = this;
+            var _this2 = this;
 
             estraverse.replace(catchClauseNode, {
                 enter: function enter(node, parentNode) {
                     if (Node_1.Node.isReplaceableIdentifierNode(node, parentNode)) {
-                        node.name = _this3.identifierReplacer.replace(node.name);
+                        var newNodeName = _this2.identifierReplacer.replace(node.name);
+                        if (node.name !== newNodeName) {
+                            node.name = newNodeName;
+                            node.obfuscated = true;
+                        }
                     }
                 }
             });
@@ -2948,7 +2946,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(8);
 var IdentifierReplacer_1 = __webpack_require__(12);
 var Node_1 = __webpack_require__(2);
@@ -3100,7 +3098,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(8);
 var IdentifierReplacer_1 = __webpack_require__(12);
 var Node_1 = __webpack_require__(2);
@@ -3237,7 +3235,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 
 var escodegen = __webpack_require__(13);
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(8);
 var Node_1 = __webpack_require__(2);
 var StringLiteralReplacer_1 = __webpack_require__(19);
@@ -3381,7 +3379,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 
 var escodegen = __webpack_require__(13);
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(8);
 var Node_1 = __webpack_require__(2);
 var Utils_1 = __webpack_require__(0);
@@ -3466,7 +3464,7 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
 
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var AbstractNodeObfuscator_1 = __webpack_require__(8);
 var IdentifierReplacer_1 = __webpack_require__(12);
 var Node_1 = __webpack_require__(2);
@@ -3885,7 +3883,7 @@ var _createClass = (function () { function defineProperties(target, props) { for
 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
 var estraverse = __webpack_require__(4);
-var NodeType_1 = __webpack_require__(6);
+var NodeType_1 = __webpack_require__(7);
 var FunctionDeclarationCalleeDataExtractor_1 = __webpack_require__(62);
 var FunctionExpressionCalleeDataExtractor_1 = __webpack_require__(63);
 var ObjectExpressionCalleeDataExtractor_1 = __webpack_require__(64);

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.8.5",
+  "version": "0.8.6",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",

+ 9 - 7
src/node-obfuscators/CatchClauseObfuscator.ts

@@ -4,12 +4,9 @@ import * as ESTree from 'estree';
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../interfaces/IOptions';
 
-import { NodeType } from '../enums/NodeType';
-
 import { AbstractNodeObfuscator } from './AbstractNodeObfuscator';
 import { IdentifierReplacer } from './replacers/IdentifierReplacer';
 import { Node } from '../node/Node';
-import { NodeUtils } from '../node/NodeUtils';
 
 /**
  * replaces:
@@ -47,9 +44,9 @@ export class CatchClauseObfuscator extends AbstractNodeObfuscator {
      * @param catchClauseNode
      */
     private storeCatchClauseParam (catchClauseNode: ESTree.CatchClause): void {
-        NodeUtils.typedReplace(catchClauseNode.param, NodeType.Identifier, {
-            enter: (node: ESTree.Identifier) => this.identifierReplacer.storeNames(node.name)
-        });
+        if (Node.isIdentifierNode(catchClauseNode.param)) {
+            this.identifierReplacer.storeNames(catchClauseNode.param.name);
+        }
     }
 
     /**
@@ -59,7 +56,12 @@ export class CatchClauseObfuscator extends AbstractNodeObfuscator {
         estraverse.replace(catchClauseNode, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
                 if (Node.isReplaceableIdentifierNode(node, parentNode)) {
-                    node.name = this.identifierReplacer.replace(node.name);
+                    const newNodeName: string = this.identifierReplacer.replace(node.name);
+
+                    if (node.name !== newNodeName) {
+                        node.name = newNodeName;
+                        node.obfuscated = true;
+                    }
                 }
             }
         });

+ 24 - 0
test/functional-tests/node-obfuscators/CatchClauseObfuscator.spec.ts

@@ -35,4 +35,28 @@ describe('CatchClauseObfuscator', () => {
             assert.equal(firstMatch, secondMatch);
         });
     });
+
+    describe('object pattern as parameter', () => {
+        const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+            `
+                (function () {
+                    try {
+                    
+                    } catch ({ name }) {
+                        return name;
+                    }
+                })();
+            `,
+            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);
+        });
+    });
 });

+ 1 - 1
test/functional-tests/node-obfuscators/FunctionObfuscator.spec.ts

@@ -49,7 +49,7 @@ describe('FunctionObfuscator', () => {
                     }
                 })();
             `,
-            NO_CUSTOM_NODES_PRESET
+            Object.assign({}, NO_CUSTOM_NODES_PRESET)
         );
         const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 

+ 100 - 44
test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts

@@ -105,59 +105,115 @@ describe('VariableDeclarationObfuscator', () => {
     });
 
     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(
+            `
+                (function () {
+                    function foo (t, e) {
+                        return function () {
+                            function baz (t) {
+                                console.log(t);
+                            }
+                    
+                            return {t: t};
+                            var t;
+                        }();
+                    }
+                })();
+            `,
+            Object.assign({}, NO_CUSTOM_NODES_PRESET)
+        );
+        const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
-        beforeEach(() => {
-            obfuscationResult = JavaScriptObfuscator.obfuscate(
-                `
-                    (function () {
-                        function foo (t, e) {
-                            return function () {
-                                function baz (t) {
-                                    console.log(t);
-                                }
-                        
-                                return {t: t};
-                                var t;
-                            }();
-                        }
-                    })();
-                `,
-                Object.assign({}, 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 obfuscate 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});/);
-
-            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 outer function body', () => {
+            assert.equal(outerFunctionParamIdentifierName, objectIdentifierName);
+            assert.equal(outerFunctionParamIdentifierName, 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);
+        });
+    });
+
+    describe(`variable calls before variable declaration when catch clause param has the same name as variables name`, () => {
+        const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+            `
+                (function () {
+                    try {
+                    
+                    } catch (t) {
+                        return function () {
+                            function baz (t) {
+                                console.log(t);
+                            }
+                            
+                            return {t: t};
+                            var t;
+                        }();
+                    }
+                })(); 
+            `,
+            Object.assign({}, 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);
         });
     });
@@ -203,7 +259,7 @@ describe('VariableDeclarationObfuscator', () => {
         });
     });
 
-    describe('object pattern as argument', () => {
+    describe('object pattern as variable declarator', () => {
         const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
             `
                 (function () {
@@ -211,7 +267,7 @@ describe('VariableDeclarationObfuscator', () => {
                     console.log(bar);
                 })();
             `,
-            NO_CUSTOM_NODES_PRESET
+            Object.assign({}, NO_CUSTOM_NODES_PRESET)
         );
         const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();