sanex3339 преди 8 години
родител
ревизия
b862c3f4f5

+ 6 - 0
CHANGELOG.md

@@ -1,6 +1,12 @@
 Change Log
 ===
 
+v0.7.2
+---
+* runtime error fix [#7](https://github.com/sanex3339/webpack-obfuscator/issues/7)
+
+* shorthand object expression fix [#16](https://github.com/sanex3339/javascript-obfuscator/issues/16)
+
 v0.7.1
 ---
 * IE error fix [#14](https://github.com/sanex3339/javascript-obfuscator/issues/14)

+ 143 - 178
dist/index.js

@@ -221,7 +221,7 @@ var escodegen = __webpack_require__(10);
 var esprima = __webpack_require__(18);
 var estraverse = __webpack_require__(4);
 var NodeType_1 = __webpack_require__(7);
-var Nodes_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 var Utils_1 = __webpack_require__(0);
 
 var NodeUtils = function () {
@@ -324,6 +324,7 @@ var NodeUtils = function () {
                         value = parentNode || node;
                     }
                     node['parentNode'] = value;
+                    node['obfuscated'] = false;
                 }
             });
         }
@@ -413,8 +414,88 @@ 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__(7);
+
+var Nodes = function () {
+    function Nodes() {
+        _classCallCheck(this, Nodes);
+    }
+
+    _createClass(Nodes, null, [{
+        key: "getProgramNode",
+        value: function getProgramNode(bodyNode) {
+            return {
+                'type': NodeType_1.NodeType.Program,
+                'body': bodyNode,
+                'sourceType': 'script',
+                'obfuscated': false
+            };
+        }
+    }, {
+        key: "isBlockStatementNode",
+        value: function isBlockStatementNode(node) {
+            return node.type === NodeType_1.NodeType.BlockStatement;
+        }
+    }, {
+        key: "isCallExpressionNode",
+        value: function isCallExpressionNode(node) {
+            return node.type === NodeType_1.NodeType.CallExpression;
+        }
+    }, {
+        key: "isIdentifierNode",
+        value: function isIdentifierNode(node) {
+            return node.type === NodeType_1.NodeType.Identifier;
+        }
+    }, {
+        key: "isLiteralNode",
+        value: function isLiteralNode(node) {
+            return node.type === NodeType_1.NodeType.Literal;
+        }
+    }, {
+        key: "isMemberExpressionNode",
+        value: function isMemberExpressionNode(node) {
+            return node.type === NodeType_1.NodeType.MemberExpression;
+        }
+    }, {
+        key: "isProgramNode",
+        value: function isProgramNode(node) {
+            return node.type === NodeType_1.NodeType.Program;
+        }
+    }, {
+        key: "isPropertyNode",
+        value: function isPropertyNode(node) {
+            return node.type === NodeType_1.NodeType.Property;
+        }
+    }, {
+        key: "isVariableDeclaratorNode",
+        value: function isVariableDeclaratorNode(node) {
+            return node.type === NodeType_1.NodeType.VariableDeclarator;
+        }
+    }, {
+        key: "isNodeHasBlockStatement",
+        value: function isNodeHasBlockStatement(node) {
+            return node.hasOwnProperty('body') && Array.isArray(node.body);
+        }
+    }]);
+
+    return Nodes;
+}();
+
+exports.Nodes = Nodes;
+
+/***/ },
+/* 6 */
+/***/ function(module, exports, __webpack_require__) {
+
+"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 JSFuck_1 = __webpack_require__(16);
-var Nodes_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 var Utils_1 = __webpack_require__(0);
 
 var NodeObfuscator = function () {
@@ -512,80 +593,6 @@ var NodeObfuscator = function () {
 
 exports.NodeObfuscator = NodeObfuscator;
 
-/***/ },
-/* 6 */
-/***/ function(module, exports, __webpack_require__) {
-
-"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 NodeType_1 = __webpack_require__(7);
-
-var Nodes = function () {
-    function Nodes() {
-        _classCallCheck(this, Nodes);
-    }
-
-    _createClass(Nodes, null, [{
-        key: "getProgramNode",
-        value: function getProgramNode(bodyNode) {
-            return {
-                'type': NodeType_1.NodeType.Program,
-                'body': bodyNode,
-                'sourceType': 'script'
-            };
-        }
-    }, {
-        key: "isBlockStatementNode",
-        value: function isBlockStatementNode(node) {
-            return node.type === NodeType_1.NodeType.BlockStatement;
-        }
-    }, {
-        key: "isIdentifierNode",
-        value: function isIdentifierNode(node) {
-            return node.type === NodeType_1.NodeType.Identifier;
-        }
-    }, {
-        key: "isLiteralNode",
-        value: function isLiteralNode(node) {
-            return node.type === NodeType_1.NodeType.Literal;
-        }
-    }, {
-        key: "isMemberExpressionNode",
-        value: function isMemberExpressionNode(node) {
-            return node.type === NodeType_1.NodeType.MemberExpression;
-        }
-    }, {
-        key: "isProgramNode",
-        value: function isProgramNode(node) {
-            return node.type === NodeType_1.NodeType.Program;
-        }
-    }, {
-        key: "isPropertyNode",
-        value: function isPropertyNode(node) {
-            return node.type === NodeType_1.NodeType.Property;
-        }
-    }, {
-        key: "isVariableDeclaratorNode",
-        value: function isVariableDeclaratorNode(node) {
-            return node.type === NodeType_1.NodeType.VariableDeclarator;
-        }
-    }, {
-        key: "isNodeHasBlockStatement",
-        value: function isNodeHasBlockStatement(node) {
-            return node.hasOwnProperty('body') && Array.isArray(node.body);
-        }
-    }]);
-
-    return Nodes;
-}();
-
-exports.Nodes = Nodes;
-
 /***/ },
 /* 7 */
 /***/ function(module, exports, __webpack_require__) {
@@ -990,7 +997,7 @@ var FunctionObfuscator_1 = __webpack_require__(40);
 var LiteralObfuscator_1 = __webpack_require__(41);
 var MemberExpressionObfuscator_1 = __webpack_require__(42);
 var MethodDefinitionObfuscator_1 = __webpack_require__(43);
-var Nodes_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 var NodeUtils_1 = __webpack_require__(1);
 var ObjectExpressionObfuscator_1 = __webpack_require__(44);
 var SelfDefendingNodesGroup_1 = __webpack_require__(36);
@@ -1055,7 +1062,7 @@ var Obfuscator = function () {
             var _this2 = this;
 
             estraverse.replace(node, {
-                leave: function leave(node, parentNode) {
+                enter: function enter(node, parentNode) {
                     _this2.initializeNodeObfuscators(node, parentNode);
                 }
             });
@@ -1378,15 +1385,9 @@ var ConsoleOutputDisableExpressionNode = function (_Node_1$Node) {
     _inherits(ConsoleOutputDisableExpressionNode, _Node_1$Node);
 
     function ConsoleOutputDisableExpressionNode() {
-        var _Object$getPrototypeO;
-
         _classCallCheck(this, ConsoleOutputDisableExpressionNode);
 
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-            args[_key] = arguments[_key];
-        }
-
-        var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(ConsoleOutputDisableExpressionNode)).call.apply(_Object$getPrototypeO, [this].concat(args)));
+        var _this = _possibleConstructorReturn(this, (ConsoleOutputDisableExpressionNode.__proto__ || Object.getPrototypeOf(ConsoleOutputDisableExpressionNode)).apply(this, arguments));
 
         _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
         return _this;
@@ -1436,7 +1437,7 @@ var DebugProtectionFunctionCallNode = function (_Node_1$Node) {
     function DebugProtectionFunctionCallNode(debugProtectionFunctionName, options) {
         _classCallCheck(this, DebugProtectionFunctionCallNode);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionCallNode).call(this, options));
+        var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionCallNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionCallNode)).call(this, options));
 
         _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
         _this.debugProtectionFunctionName = debugProtectionFunctionName;
@@ -1489,7 +1490,7 @@ var DebugProtectionFunctionIntervalNode = function (_Node_1$Node) {
     function DebugProtectionFunctionIntervalNode(debugProtectionFunctionName, options) {
         _classCallCheck(this, DebugProtectionFunctionIntervalNode);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionIntervalNode).call(this, options));
+        var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionIntervalNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionIntervalNode)).call(this, options));
 
         _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
         _this.debugProtectionFunctionName = debugProtectionFunctionName;
@@ -1543,7 +1544,7 @@ var DebugProtectionFunctionNode = function (_Node_1$Node) {
     function DebugProtectionFunctionNode(debugProtectionFunctionName, options) {
         _classCallCheck(this, DebugProtectionFunctionNode);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionFunctionNode).call(this, options));
+        var _this = _possibleConstructorReturn(this, (DebugProtectionFunctionNode.__proto__ || Object.getPrototypeOf(DebugProtectionFunctionNode)).call(this, options));
 
         _this.appendState = AppendState_1.AppendState.BeforeObfuscation;
         _this.debugProtectionFunctionName = debugProtectionFunctionName;
@@ -1606,15 +1607,9 @@ var SelfDefendingUnicodeNode = function (_Node_1$Node) {
     _inherits(SelfDefendingUnicodeNode, _Node_1$Node);
 
     function SelfDefendingUnicodeNode() {
-        var _Object$getPrototypeO;
-
         _classCallCheck(this, SelfDefendingUnicodeNode);
 
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-            args[_key] = arguments[_key];
-        }
-
-        var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(SelfDefendingUnicodeNode)).call.apply(_Object$getPrototypeO, [this].concat(args)));
+        var _this = _possibleConstructorReturn(this, (SelfDefendingUnicodeNode.__proto__ || Object.getPrototypeOf(SelfDefendingUnicodeNode)).apply(this, arguments));
 
         _this.appendState = AppendState_1.AppendState.AfterObfuscation;
         return _this;
@@ -1675,7 +1670,7 @@ var UnicodeArrayCallsWrapper = function (_Node_1$Node) {
     function UnicodeArrayCallsWrapper(unicodeArrayCallsWrapperName, unicodeArrayName, unicodeArray, options) {
         _classCallCheck(this, UnicodeArrayCallsWrapper);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayCallsWrapper).call(this, options));
+        var _this = _possibleConstructorReturn(this, (UnicodeArrayCallsWrapper.__proto__ || Object.getPrototypeOf(UnicodeArrayCallsWrapper)).call(this, options));
 
         _this.appendState = AppendState_1.AppendState.AfterObfuscation;
         _this.unicodeArrayCallsWrapperName = unicodeArrayCallsWrapperName;
@@ -1700,7 +1695,7 @@ var UnicodeArrayCallsWrapper = function (_Node_1$Node) {
     }, {
         key: "getNode",
         value: function getNode() {
-            return _get(Object.getPrototypeOf(UnicodeArrayCallsWrapper.prototype), "getNode", this).call(this);
+            return _get(UnicodeArrayCallsWrapper.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayCallsWrapper.prototype), "getNode", this).call(this);
         }
     }, {
         key: "getNodeStructure",
@@ -1752,7 +1747,7 @@ var UnicodeArrayDecodeNode = function (_Node_1$Node) {
     function UnicodeArrayDecodeNode(unicodeArrayName, unicodeArray, options) {
         _classCallCheck(this, UnicodeArrayDecodeNode);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayDecodeNode).call(this, options));
+        var _this = _possibleConstructorReturn(this, (UnicodeArrayDecodeNode.__proto__ || Object.getPrototypeOf(UnicodeArrayDecodeNode)).call(this, options));
 
         _this.appendState = AppendState_1.AppendState.AfterObfuscation;
         _this.unicodeArrayName = unicodeArrayName;
@@ -1771,7 +1766,7 @@ var UnicodeArrayDecodeNode = function (_Node_1$Node) {
     }, {
         key: "getNode",
         value: function getNode() {
-            return _get(Object.getPrototypeOf(UnicodeArrayDecodeNode.prototype), "getNode", this).call(this);
+            return _get(UnicodeArrayDecodeNode.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayDecodeNode.prototype), "getNode", this).call(this);
         }
     }, {
         key: "getNodeStructure",
@@ -1833,7 +1828,7 @@ var UnicodeArrayNode = function (_Node_1$Node) {
 
         _classCallCheck(this, UnicodeArrayNode);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayNode).call(this, options));
+        var _this = _possibleConstructorReturn(this, (UnicodeArrayNode.__proto__ || Object.getPrototypeOf(UnicodeArrayNode)).call(this, options));
 
         _this.appendState = AppendState_1.AppendState.AfterObfuscation;
         _this.unicodeArray = [];
@@ -1864,7 +1859,7 @@ var UnicodeArrayNode = function (_Node_1$Node) {
         key: 'getNode',
         value: function getNode() {
             Utils_1.Utils.arrayRotate(this.unicodeArray, this.unicodeArrayRotateValue);
-            return _get(Object.getPrototypeOf(UnicodeArrayNode.prototype), 'getNode', this).call(this);
+            return _get(UnicodeArrayNode.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayNode.prototype), 'getNode', this).call(this);
         }
     }, {
         key: 'updateNodeData',
@@ -1920,7 +1915,7 @@ var UnicodeArrayRotateFunctionNode = function (_Node_1$Node) {
     function UnicodeArrayRotateFunctionNode(unicodeArrayName, unicodeArray, unicodeArrayRotateValue, options) {
         _classCallCheck(this, UnicodeArrayRotateFunctionNode);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayRotateFunctionNode).call(this, options));
+        var _this = _possibleConstructorReturn(this, (UnicodeArrayRotateFunctionNode.__proto__ || Object.getPrototypeOf(UnicodeArrayRotateFunctionNode)).call(this, options));
 
         _this.appendState = AppendState_1.AppendState.AfterObfuscation;
         _this.unicodeArrayName = unicodeArrayName;
@@ -1940,7 +1935,7 @@ var UnicodeArrayRotateFunctionNode = function (_Node_1$Node) {
     }, {
         key: "getNode",
         value: function getNode() {
-            return _get(Object.getPrototypeOf(UnicodeArrayRotateFunctionNode.prototype), "getNode", this).call(this);
+            return _get(UnicodeArrayRotateFunctionNode.prototype.__proto__ || Object.getPrototypeOf(UnicodeArrayRotateFunctionNode.prototype), "getNode", this).call(this);
         }
     }, {
         key: "getNodeStructure",
@@ -1993,7 +1988,7 @@ var ConsoleOutputNodesGroup = function (_NodesGroup_1$NodesGr) {
     function ConsoleOutputNodesGroup(options) {
         _classCallCheck(this, ConsoleOutputNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ConsoleOutputNodesGroup).call(this, options));
+        var _this = _possibleConstructorReturn(this, (ConsoleOutputNodesGroup.__proto__ || Object.getPrototypeOf(ConsoleOutputNodesGroup)).call(this, options));
 
         if (!_this.options.disableConsoleOutput) {
             return _possibleConstructorReturn(_this);
@@ -2032,7 +2027,7 @@ var DebugProtectionNodesGroup = function (_NodesGroup_1$NodesGr) {
     function DebugProtectionNodesGroup(options) {
         _classCallCheck(this, DebugProtectionNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DebugProtectionNodesGroup).call(this, options));
+        var _this = _possibleConstructorReturn(this, (DebugProtectionNodesGroup.__proto__ || Object.getPrototypeOf(DebugProtectionNodesGroup)).call(this, options));
 
         _this.debugProtectionFunctionIdentifier = Utils_1.Utils.getRandomVariableName();
         if (!_this.options.debugProtection) {
@@ -2073,7 +2068,7 @@ var SelfDefendingNodesGroup = function (_NodesGroup_1$NodesGr) {
     function SelfDefendingNodesGroup(options) {
         _classCallCheck(this, SelfDefendingNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SelfDefendingNodesGroup).call(this, options));
+        var _this = _possibleConstructorReturn(this, (SelfDefendingNodesGroup.__proto__ || Object.getPrototypeOf(SelfDefendingNodesGroup)).call(this, options));
 
         if (!_this.options.selfDefending) {
             return _possibleConstructorReturn(_this);
@@ -2113,7 +2108,7 @@ var UnicodeArrayNodesGroup = function (_NodesGroup_1$NodesGr) {
     function UnicodeArrayNodesGroup(options) {
         _classCallCheck(this, UnicodeArrayNodesGroup);
 
-        var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UnicodeArrayNodesGroup).call(this, options));
+        var _this = _possibleConstructorReturn(this, (UnicodeArrayNodesGroup.__proto__ || Object.getPrototypeOf(UnicodeArrayNodesGroup)).call(this, options));
 
         _this.unicodeArrayName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
         _this.unicodeArrayTranslatorName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
@@ -2164,21 +2159,15 @@ 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 NodeObfuscator_1 = __webpack_require__(5);
+var NodeObfuscator_1 = __webpack_require__(6);
 
 var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) {
     _inherits(CatchClauseObfuscator, _NodeObfuscator_1$Nod);
 
     function CatchClauseObfuscator() {
-        var _Object$getPrototypeO;
-
         _classCallCheck(this, CatchClauseObfuscator);
 
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-            args[_key] = arguments[_key];
-        }
-
-        var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(CatchClauseObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args)));
+        var _this = _possibleConstructorReturn(this, (CatchClauseObfuscator.__proto__ || Object.getPrototypeOf(CatchClauseObfuscator)).apply(this, arguments));
 
         _this.catchClauseParam = new Map();
         return _this;
@@ -2196,7 +2185,7 @@ var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) {
             var _this2 = this;
 
             estraverse.traverse(catchClauseNode.param, {
-                leave: function leave(node) {
+                enter: function enter(node) {
                     return _this2.storeIdentifiersNames(node, _this2.catchClauseParam);
                 }
             });
@@ -2207,7 +2196,7 @@ var CatchClauseObfuscator = function (_NodeObfuscator_1$Nod) {
             var _this3 = this;
 
             estraverse.replace(catchClauseNode, {
-                leave: function leave(node, parentNode) {
+                enter: function enter(node, parentNode) {
                     _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.catchClauseParam);
                 }
             });
@@ -2236,22 +2225,16 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 
 var estraverse = __webpack_require__(4);
 var NodeType_1 = __webpack_require__(7);
-var NodeObfuscator_1 = __webpack_require__(5);
+var NodeObfuscator_1 = __webpack_require__(6);
 var NodeUtils_1 = __webpack_require__(1);
 
 var FunctionDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
     _inherits(FunctionDeclarationObfuscator, _NodeObfuscator_1$Nod);
 
     function FunctionDeclarationObfuscator() {
-        var _Object$getPrototypeO;
-
         _classCallCheck(this, FunctionDeclarationObfuscator);
 
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-            args[_key] = arguments[_key];
-        }
-
-        var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(FunctionDeclarationObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args)));
+        var _this = _possibleConstructorReturn(this, (FunctionDeclarationObfuscator.__proto__ || Object.getPrototypeOf(FunctionDeclarationObfuscator)).apply(this, arguments));
 
         _this.functionName = new Map();
         return _this;
@@ -2272,7 +2255,7 @@ var FunctionDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
             var _this2 = this;
 
             estraverse.traverse(functionDeclarationNode.id, {
-                leave: function leave(node) {
+                enter: function enter(node) {
                     return _this2.storeIdentifiersNames(node, _this2.functionName);
                 }
             });
@@ -2312,21 +2295,16 @@ 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 NodeObfuscator_1 = __webpack_require__(5);
+var NodeObfuscator_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 
 var FunctionObfuscator = function (_NodeObfuscator_1$Nod) {
     _inherits(FunctionObfuscator, _NodeObfuscator_1$Nod);
 
     function FunctionObfuscator() {
-        var _Object$getPrototypeO;
-
         _classCallCheck(this, FunctionObfuscator);
 
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-            args[_key] = arguments[_key];
-        }
-
-        var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(FunctionObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args)));
+        var _this = _possibleConstructorReturn(this, (FunctionObfuscator.__proto__ || Object.getPrototypeOf(FunctionObfuscator)).apply(this, arguments));
 
         _this.functionParams = new Map();
         return _this;
@@ -2345,7 +2323,7 @@ var FunctionObfuscator = function (_NodeObfuscator_1$Nod) {
 
             functionNode.params.forEach(function (paramsNode) {
                 estraverse.traverse(paramsNode, {
-                    leave: function leave(node) {
+                    enter: function enter(node) {
                         return _this2.storeIdentifiersNames(node, _this2.functionParams);
                     }
                 });
@@ -2357,8 +2335,17 @@ var FunctionObfuscator = function (_NodeObfuscator_1$Nod) {
             var _this3 = this;
 
             var replaceVisitor = {
-                leave: function leave(node, parentNode) {
+                enter: function enter(node, parentNode) {
+                    var newNodeName = '';
+                    if (Nodes_1.Nodes.isIdentifierNode(node)) {
+                        newNodeName = node.name;
+                    }
                     _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.functionParams);
+                    if (Nodes_1.Nodes.isIdentifierNode(node)) {
+                        if (node.name !== newNodeName) {
+                            node.obfuscated = true;
+                        }
+                    }
                 }
             };
             functionNode.params.forEach(function (paramsNode) {
@@ -2391,8 +2378,8 @@ 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 escodegen = __webpack_require__(10);
-var NodeObfuscator_1 = __webpack_require__(5);
-var Nodes_1 = __webpack_require__(6);
+var NodeObfuscator_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 
 var LiteralObfuscator = function (_NodeObfuscator_1$Nod) {
     _inherits(LiteralObfuscator, _NodeObfuscator_1$Nod);
@@ -2400,7 +2387,7 @@ var LiteralObfuscator = function (_NodeObfuscator_1$Nod) {
     function LiteralObfuscator() {
         _classCallCheck(this, LiteralObfuscator);
 
-        return _possibleConstructorReturn(this, Object.getPrototypeOf(LiteralObfuscator).apply(this, arguments));
+        return _possibleConstructorReturn(this, (LiteralObfuscator.__proto__ || Object.getPrototypeOf(LiteralObfuscator)).apply(this, arguments));
     }
 
     _createClass(LiteralObfuscator, [{
@@ -2456,8 +2443,8 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 var escodegen = __webpack_require__(10);
 var estraverse = __webpack_require__(4);
 var NodeType_1 = __webpack_require__(7);
-var NodeObfuscator_1 = __webpack_require__(5);
-var Nodes_1 = __webpack_require__(6);
+var NodeObfuscator_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 
 var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
     _inherits(MemberExpressionObfuscator, _NodeObfuscator_1$Nod);
@@ -2465,7 +2452,7 @@ var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
     function MemberExpressionObfuscator() {
         _classCallCheck(this, MemberExpressionObfuscator);
 
-        return _possibleConstructorReturn(this, Object.getPrototypeOf(MemberExpressionObfuscator).apply(this, arguments));
+        return _possibleConstructorReturn(this, (MemberExpressionObfuscator.__proto__ || Object.getPrototypeOf(MemberExpressionObfuscator)).apply(this, arguments));
     }
 
     _createClass(MemberExpressionObfuscator, [{
@@ -2474,7 +2461,7 @@ var MemberExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
             var _this2 = this;
 
             estraverse.replace(memberExpressionNode.property, {
-                leave: function leave(node, parentNode) {
+                enter: function enter(node, parentNode) {
                     if (Nodes_1.Nodes.isLiteralNode(node)) {
                         _this2.obfuscateLiteralProperty(node);
                         return;
@@ -2538,23 +2525,17 @@ 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 NodeObfuscator_1 = __webpack_require__(5);
-var Nodes_1 = __webpack_require__(6);
+var NodeObfuscator_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 var Utils_1 = __webpack_require__(0);
 
 var MethodDefinitionObfuscator = function (_NodeObfuscator_1$Nod) {
     _inherits(MethodDefinitionObfuscator, _NodeObfuscator_1$Nod);
 
     function MethodDefinitionObfuscator() {
-        var _Object$getPrototypeO;
-
         _classCallCheck(this, MethodDefinitionObfuscator);
 
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-            args[_key] = arguments[_key];
-        }
-
-        var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(MethodDefinitionObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args)));
+        var _this = _possibleConstructorReturn(this, (MethodDefinitionObfuscator.__proto__ || Object.getPrototypeOf(MethodDefinitionObfuscator)).apply(this, arguments));
 
         _this.ignoredNames = ['constructor'];
         return _this;
@@ -2606,8 +2587,8 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 var escodegen = __webpack_require__(10);
 var estraverse = __webpack_require__(4);
 var NodeType_1 = __webpack_require__(7);
-var NodeObfuscator_1 = __webpack_require__(5);
-var Nodes_1 = __webpack_require__(6);
+var NodeObfuscator_1 = __webpack_require__(6);
+var Nodes_1 = __webpack_require__(5);
 var Utils_1 = __webpack_require__(0);
 
 var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
@@ -2616,7 +2597,7 @@ var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
     function ObjectExpressionObfuscator() {
         _classCallCheck(this, ObjectExpressionObfuscator);
 
-        return _possibleConstructorReturn(this, Object.getPrototypeOf(ObjectExpressionObfuscator).apply(this, arguments));
+        return _possibleConstructorReturn(this, (ObjectExpressionObfuscator.__proto__ || Object.getPrototypeOf(ObjectExpressionObfuscator)).apply(this, arguments));
     }
 
     _createClass(ObjectExpressionObfuscator, [{
@@ -2625,6 +2606,9 @@ var ObjectExpressionObfuscator = function (_NodeObfuscator_1$Nod) {
             var _this2 = this;
 
             objectExpressionNode.properties.forEach(function (property) {
+                if (property.shorthand) {
+                    property.shorthand = false;
+                }
                 estraverse.replace(property.key, {
                     leave: function leave(node, parentNode) {
                         if (Nodes_1.Nodes.isLiteralNode(node)) {
@@ -2688,23 +2672,16 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
 
 var estraverse = __webpack_require__(4);
 var NodeType_1 = __webpack_require__(7);
-var NodeObfuscator_1 = __webpack_require__(5);
+var NodeObfuscator_1 = __webpack_require__(6);
 var NodeUtils_1 = __webpack_require__(1);
-var Utils_1 = __webpack_require__(0);
 
 var VariableDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
     _inherits(VariableDeclarationObfuscator, _NodeObfuscator_1$Nod);
 
     function VariableDeclarationObfuscator() {
-        var _Object$getPrototypeO;
-
         _classCallCheck(this, VariableDeclarationObfuscator);
 
-        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
-            args[_key] = arguments[_key];
-        }
-
-        var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(VariableDeclarationObfuscator)).call.apply(_Object$getPrototypeO, [this].concat(args)));
+        var _this = _possibleConstructorReturn(this, (VariableDeclarationObfuscator.__proto__ || Object.getPrototypeOf(VariableDeclarationObfuscator)).apply(this, arguments));
 
         _this.variableNames = new Map();
         return _this;
@@ -2737,22 +2714,10 @@ var VariableDeclarationObfuscator = function (_NodeObfuscator_1$Nod) {
         value: function replaceVariableNames(variableDeclarationNode, variableParentNode) {
             var _this3 = this;
 
-            var scopeNode = variableDeclarationNode.kind === 'var' ? NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode) : variableParentNode,
-                isNodeAfterVariableDeclaratorFlag = false;
+            var scopeNode = variableDeclarationNode.kind === 'var' ? NodeUtils_1.NodeUtils.getBlockScopeOfNode(variableDeclarationNode) : variableParentNode;
             estraverse.replace(scopeNode, {
                 enter: function enter(node, parentNode) {
-                    var functionNodes = [NodeType_1.NodeType.ArrowFunctionExpression, NodeType_1.NodeType.FunctionDeclaration, NodeType_1.NodeType.FunctionExpression];
-                    if (Utils_1.Utils.arrayContains(functionNodes, node.type)) {
-                        estraverse.replace(node, {
-                            enter: function enter(node, parentNode) {
-                                _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.variableNames);
-                            }
-                        });
-                    }
-                    if (node === variableDeclarationNode) {
-                        isNodeAfterVariableDeclaratorFlag = true;
-                    }
-                    if (isNodeAfterVariableDeclaratorFlag) {
+                    if (!node.obfuscated) {
                         _this3.replaceIdentifiersWithRandomNames(node, parentNode, _this3.variableNames);
                     }
                 }

+ 16 - 16
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.7.1",
+  "version": "0.7.2",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -22,43 +22,43 @@
   "dependencies": {
     "babel-polyfill": "^6.13.0",
     "chance": "^1.0.4",
-    "class-validator": "^0.5.0",
+    "class-validator": "^0.6.0",
     "commander": "^2.9.0",
     "escodegen": "^1.8.1",
-    "esprima": "^2.7.2",
+    "esprima": "^3.0.0",
     "estraverse": "^4.2.0",
     "format-unicorn": "^1.1.0",
     "mkdirp": "^0.5.1",
     "source-map-support": "^0.4.2"
   },
   "devDependencies": {
-    "@types/chai": "^3.4.31",
+    "@types/chai": "^3.4.32",
     "@types/chance": "^0.7.28",
     "@types/commander": "^2.3.29",
     "@types/escodegen": "^0.0.3",
     "@types/esprima": "^2.1.30",
     "@types/estraverse": "^0.0.3",
     "@types/format-unicorn": "^0.0.28",
-    "@types/joi": "^9.0.30",
+    "@types/joi": "^9.0.31",
     "@types/mkdirp": "^0.3.28",
-    "@types/mocha": "^2.2.30",
+    "@types/mocha": "^2.2.31",
     "@types/node": "^4.0.30",
-    "@types/sinon": "^1.16.28",
-    "babel-cli": "^6.11.4",
+    "@types/sinon": "^1.16.29",
+    "babel-cli": "^6.14.0",
     "babel-loader": "^6.2.5",
-    "babel-preset-es2015": "^6.13.2",
+    "babel-preset-es2015": "^6.14.0",
     "chai": "^3.5.0",
-    "chai-members-deep": "^1.1.0",
-    "coveralls": "^2.11.12",
+    "coveralls": "^2.11.14",
     "istanbul": "1.1.0-alpha.1",
     "mocha": "^3.0.2",
-    "sinon": "^2.0.0-pre.2",
+    "optimize-js-plugin": "0.0.4",
+    "sinon": "^2.0.0-pre.3",
     "ts-loader": "^0.8.2",
     "ts-node": "^1.3.0",
-    "tslint": "^3.14.0",
+    "tslint": "^3.15.1",
     "typescript": "^2.0.0",
-    "webpack": "^2.1.0-beta.21",
-    "webpack-node-externals": "^1.3.3"
+    "webpack": "^2.1.0-beta.25",
+    "webpack-node-externals": "^1.4.3"
   },
   "repository": {
     "type": "git",
@@ -83,4 +83,4 @@
     "name": "Timofey Kachalov"
   },
   "license": "BSD-2-Clause"
-}
+}

+ 1 - 0
src/NodeUtils.ts

@@ -152,6 +152,7 @@ export class NodeUtils {
                 }
 
                 node['parentNode'] = value;
+                node['obfuscated'] = false;
             }
         });
     }

+ 11 - 1
src/Nodes.ts

@@ -12,6 +12,7 @@ import { TStatement } from "./types/nodes/TStatement";
 import { TNodeWithBlockStatement } from "./types/TNodeWithBlockStatement";
 
 import { NodeType } from "./enums/NodeType";
+import { ICallExpressionNode } from "./interfaces/nodes/ICallExpressionNode";
 
 export class Nodes {
     /**
@@ -22,7 +23,8 @@ export class Nodes {
         return {
             'type': NodeType.Program,
             'body': bodyNode,
-            'sourceType': 'script'
+            'sourceType': 'script',
+            'obfuscated': false
         };
     }
 
@@ -34,6 +36,14 @@ export class Nodes {
         return node.type === NodeType.BlockStatement;
     }
 
+    /**
+     * @param node
+     * @returns {boolean}
+     */
+    public static isCallExpressionNode (node: INode): node is ICallExpressionNode {
+        return node.type === NodeType.CallExpression;
+    }
+
     /**
      * @param node
      * @returns {boolean}

+ 1 - 1
src/Obfuscator.ts

@@ -131,7 +131,7 @@ export class Obfuscator implements IObfuscator {
      */
     private obfuscate (node: INode): void {
         estraverse.replace(node, {
-            leave: (node: INode, parentNode: INode): any => {
+            enter: (node: INode, parentNode: INode): any => {
                 this.initializeNodeObfuscators(node, parentNode);
             }
         });

+ 1 - 0
src/interfaces/nodes/INode.d.ts

@@ -1,4 +1,5 @@
 export interface INode {
     type: string;
     parentNode?: INode;
+    obfuscated?: boolean;
 }

+ 2 - 2
src/node-obfuscators/CatchClauseObfuscator.ts

@@ -32,7 +32,7 @@ export class CatchClauseObfuscator extends NodeObfuscator {
      */
     private storeCatchClauseParam (catchClauseNode: ICatchClauseNode): void {
         estraverse.traverse(catchClauseNode.param, {
-            leave: (node: INode): any => this.storeIdentifiersNames(node, this.catchClauseParam)
+            enter: (node: INode): any => this.storeIdentifiersNames(node, this.catchClauseParam)
         });
     }
 
@@ -41,7 +41,7 @@ export class CatchClauseObfuscator extends NodeObfuscator {
      */
     private replaceCatchClauseParam (catchClauseNode: ICatchClauseNode): void {
         estraverse.replace(catchClauseNode, {
-            leave: (node: INode, parentNode: INode): any => {
+            enter: (node: INode, parentNode: INode): any => {
                 this.replaceIdentifiersWithRandomNames(node, parentNode, this.catchClauseParam);
             }
         });

+ 1 - 1
src/node-obfuscators/FunctionDeclarationObfuscator.ts

@@ -41,7 +41,7 @@ export class FunctionDeclarationObfuscator extends NodeObfuscator {
      */
     private storeFunctionName (functionDeclarationNode: IFunctionDeclarationNode): void {
         estraverse.traverse(functionDeclarationNode.id, {
-            leave: (node: INode): any => this.storeIdentifiersNames(node, this.functionName)
+            enter: (node: INode): any => this.storeIdentifiersNames(node, this.functionName)
         });
     }
 

+ 15 - 2
src/node-obfuscators/FunctionObfuscator.ts

@@ -4,6 +4,7 @@ import { IFunctionNode } from "../interfaces/nodes/IFunctionNode";
 import { INode } from "../interfaces/nodes/INode";
 
 import { NodeObfuscator } from './NodeObfuscator';
+import { Nodes } from "../Nodes";
 
 /**
  * replaces:
@@ -34,7 +35,7 @@ export class FunctionObfuscator extends NodeObfuscator {
         functionNode.params
             .forEach((paramsNode: INode) => {
                 estraverse.traverse(paramsNode, {
-                    leave: (node: INode): any => this.storeIdentifiersNames(node, this.functionParams)
+                    enter: (node: INode): any => this.storeIdentifiersNames(node, this.functionParams)
                 });
             });
     }
@@ -44,8 +45,20 @@ export class FunctionObfuscator extends NodeObfuscator {
      */
     private replaceFunctionParams (functionNode: IFunctionNode): void {
         let replaceVisitor: estraverse.Visitor = {
-            leave: (node: INode, parentNode: INode): any => {
+            enter: (node: INode, parentNode: INode): any => {
+                let newNodeName: string = '';
+
+                if (Nodes.isIdentifierNode(node)) {
+                    newNodeName = node.name;
+                }
+
                 this.replaceIdentifiersWithRandomNames(node, parentNode, this.functionParams);
+
+                if (Nodes.isIdentifierNode(node)) {
+                    if (node.name !== newNodeName) {
+                        node.obfuscated = true;
+                    }
+                }
             }
         };
 

+ 1 - 1
src/node-obfuscators/MemberExpressionObfuscator.ts

@@ -17,7 +17,7 @@ export class MemberExpressionObfuscator extends NodeObfuscator {
      */
     public obfuscateNode (memberExpressionNode: IMemberExpressionNode): void {
         estraverse.replace(memberExpressionNode.property, {
-            leave: (node: INode, parentNode: INode): any => {
+            enter: (node: INode, parentNode: INode): any => {
                 if (Nodes.isLiteralNode(node)) {
                     this.obfuscateLiteralProperty(node);
 

+ 4 - 0
src/node-obfuscators/ObjectExpressionObfuscator.ts

@@ -30,6 +30,10 @@ export class ObjectExpressionObfuscator extends NodeObfuscator {
     public obfuscateNode (objectExpressionNode: IObjectExpressionNode): void {
         objectExpressionNode.properties
             .forEach((property: IPropertyNode) => {
+                if (property.shorthand) {
+                    property.shorthand = false;
+                }
+
                 estraverse.replace(property.key, {
                     leave: (node: INode, parentNode: INode): any => {
                         if (Nodes.isLiteralNode(node)) {

+ 2 - 22
src/node-obfuscators/VariableDeclarationObfuscator.ts

@@ -8,7 +8,6 @@ import { NodeType } from "../enums/NodeType";
 
 import { NodeObfuscator } from './NodeObfuscator';
 import { NodeUtils } from "../NodeUtils";
-import { Utils } from '../Utils';
 
 /**
  * replaces:
@@ -58,30 +57,11 @@ export class VariableDeclarationObfuscator extends NodeObfuscator {
     private replaceVariableNames (variableDeclarationNode: IVariableDeclarationNode, variableParentNode: INode): void {
         let scopeNode: INode = variableDeclarationNode.kind === 'var' ? NodeUtils.getBlockScopeOfNode(
                 variableDeclarationNode
-            ) : variableParentNode,
-            isNodeAfterVariableDeclaratorFlag: boolean = false;
+            ) : variableParentNode;
 
         estraverse.replace(scopeNode, {
             enter: (node: INode, parentNode: INode): any => {
-                const functionNodes: string[] = [
-                    NodeType.ArrowFunctionExpression,
-                    NodeType.FunctionDeclaration,
-                    NodeType.FunctionExpression
-                ];
-
-                if (Utils.arrayContains(functionNodes, node.type)) {
-                    estraverse.replace(node, {
-                        enter: (node: INode, parentNode: INode): any => {
-                            this.replaceIdentifiersWithRandomNames(node, parentNode, this.variableNames);
-                        }
-                    });
-                }
-
-                if (node === variableDeclarationNode) {
-                    isNodeAfterVariableDeclaratorFlag = true;
-                }
-
-                if (isNodeAfterVariableDeclaratorFlag) {
+                if (!node.obfuscated) {
                     this.replaceIdentifiersWithRandomNames(node, parentNode, this.variableNames);
                 }
             }

+ 5 - 0
test/dev/test.ts

@@ -56,6 +56,11 @@ let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         console.log(105.4);
         console.log(true, false);
         
+        var sA = 'shorthand1';
+        var sB = 'shorthand2';
+        
+        console.log({sA, sB});
+        
         try {
         } catch (error) {
             console.log(error);

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

@@ -0,0 +1,42 @@
+import { IObfuscationResult } from "../../../src/interfaces/IObfuscationResult";
+
+import { NO_CUSTOM_NODES_PRESET } from "../../../src/preset-options/NoCustomNodesPreset";
+
+import { JavaScriptObfuscator } from "../../../src/JavaScriptObfuscator";
+
+const assert: Chai.AssertStatic = require('chai').assert;
+
+describe('FunctionObfuscator', () => {
+    describe('identifiers obfuscation inside `FunctionDeclaration` and `FunctionExpression` node body', () => {
+        it('should correct obfuscate both function parameter identifier and function body identifier with same name', () => {
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                `
+                    (function () {
+                        var test = function (test) {
+                            console.log(test);
+                            
+                            if (true) {
+                                var test = 5
+                            }
+                            
+                            return test;
+                        }
+                    })();
+                `,
+                Object.assign({}, NO_CUSTOM_NODES_PRESET)
+            );
+
+            const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
+
+            const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/var _0x[a-z0-9]{5,6} *= *function *\((_0x[a-z0-9]{5,6})\) *\{/);
+            const functionBodyIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{5,6})\)/);
+
+            const functionParamIdentifierName: string = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
+            const functionBodyIdentifierName: string = (<RegExpMatchArray>functionBodyIdentifierMatch)[1];
+
+            assert.equal(functionParamIdentifierName, functionBodyIdentifierName);
+        });
+    });
+});

+ 18 - 0
test/functional-tests/node-obfuscators/ObjectExpressionObfuscator.spec.ts

@@ -24,4 +24,22 @@ describe('ObjectExpressionObfuscator', () => {
 
         assert.match(obfuscationResult.getObfuscatedCode(),  /^var *test *= *\{'\\x66\\x6f\\x6f':0x0\};$/);
     });
+
+    it('should correct convert shorthand ES6 object expression to non-shorthand object expression', () => {
+        let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+            `
+                (function () {
+                    let a = 0;
+                    let b = 0;
+                    var test = {a, b};
+                })();
+            `,
+            Object.assign({}, NO_CUSTOM_NODES_PRESET)
+        );
+
+        assert.match(
+            obfuscationResult.getObfuscatedCode(),
+            /var *_0x[a-z0-9]{4,6} *= *\{'\\x61': *_0x[a-z0-9]{4,6}\, *'\\x62': *_0x[a-z0-9]{4,6}\};/
+        );
+    });
 });

+ 63 - 5
test/functional-tests/node-obfuscators/VariableDeclarationObfuscator.spec.ts

@@ -18,8 +18,8 @@ describe('VariableDeclarationObfuscator', () => {
             Object.assign({}, NO_CUSTOM_NODES_PRESET)
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-z0-9]){6} *= *'\\x61\\x62\\x63';/);
-        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){6}\);/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /var *_0x([a-z0-9]){4,6} *= *'\\x61\\x62\\x63';/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
     });
 
     it('should obfuscate variable call (`identifier` node) outside of block scope of node in which this variable was declared with `var` kind', () => {
@@ -35,7 +35,65 @@ describe('VariableDeclarationObfuscator', () => {
             Object.assign({}, NO_CUSTOM_NODES_PRESET)
         );
 
-        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){6}\);/);
+        assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\);/);
+    });
+
+    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;
+
+        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)
+            );
+        });
+
+        it('should correct obfuscate variables inside function body', () => {
+            const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
+            const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/function *_0x[a-z0-9]{5,6} *\((_0x[a-z0-9]{5,6})\,(_0x[a-z0-9]{5,6})\) *\{/);
+            const innerFunctionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/function _0x[a-z0-9]{5,6} *\((_0x[a-z0-9]{5,6})\) *\{/);
+            const constructorIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/console\['\\x6c\\x6f\\x67'\]\((_0x[a-z0-9]{5,6})\)/);
+            const objectIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/return\{'\\x74':(_0x[a-z0-9]{5,6})\}/);
+            const variableDeclarationIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/var *(_0x[a-z0-9]{5,6});/);
+
+            functionParamIdentifierName = (<RegExpMatchArray>functionParamIdentifierMatch)[1];
+            innerFunctionParamIdentifierName = (<RegExpMatchArray>innerFunctionParamIdentifierMatch)[1];
+            constructorIdentifierName = (<RegExpMatchArray>constructorIdentifierMatch)[1];
+            objectIdentifierName = (<RegExpMatchArray>objectIdentifierMatch)[1];
+            variableDeclarationIdentifierName = (<RegExpMatchArray>variableDeclarationIdentifierMatch)[1];
+
+            assert.notEqual(functionParamIdentifierName, constructorIdentifierName);
+            assert.notEqual(functionParamIdentifierName, innerFunctionParamIdentifierName);
+
+            assert.equal(functionParamIdentifierName, objectIdentifierName);
+            assert.equal(functionParamIdentifierName, variableDeclarationIdentifierName);
+
+            assert.equal(innerFunctionParamIdentifierName, constructorIdentifierName);
+            assert.equal(variableDeclarationIdentifierName, objectIdentifierName);
+        });
     });
 
     it('should not obfuscate variable call (`identifier` node) outside of block scope of node in which this variable was declared with `let` kind', () => {
@@ -78,11 +136,11 @@ describe('VariableDeclarationObfuscator', () => {
         });
 
         it('should obfuscate variable call (`identifier` node) before variable declaration if this call is inside function body', () => {
-            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){6}\['\\x69\\x74\\x65\\x6d'\]\);/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){4,6}\['\\x69\\x74\\x65\\x6d'\]\);/);
         });
 
         it('should not obfuscate variable call (`identifier` node) before variable declaration', () => {
-            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(abc\);/);
+            assert.match(obfuscationResult.getObfuscatedCode(),  /console\['\\x6c\\x6f\\x67'\]\(_0x([a-z0-9]){5,6}\);/);
         });
     });
 });

+ 1 - 0
test/index.spec.ts

@@ -23,6 +23,7 @@ import './unit-tests/node-obfuscators/FunctionObfuscator.spec';
 import './functional-tests/JavaScriptObfuscator.spec';
 import './functional-tests/JavaScriptObfuscatorCLI.spec';
 import './functional-tests/JavaScriptObfuscatorInternal.spec';
+import './functional-tests/node-obfuscators/FunctionObfuscator.spec';
 import './functional-tests/node-obfuscators/LiteralObfuscator.spec';
 import './functional-tests/node-obfuscators/MemberExpressionObfuscator.spec';
 import './functional-tests/node-obfuscators/MethodDefinitionObfuscator.spec';

+ 25 - 12
test/mocks/NodeMocks.ts

@@ -28,7 +28,8 @@ export class NodeMocks {
         return {
             type: NodeType.Program,
             body: bodyNodes,
-            sourceType: 'script'
+            sourceType: 'script',
+            obfuscated: false
         };
     }
 
@@ -39,7 +40,8 @@ export class NodeMocks {
     public static getBlockStatementNode (bodyNodes: TStatement[] = []): IBlockStatementNode {
         return {
             type: NodeType.BlockStatement,
-            body: bodyNodes
+            body: bodyNodes,
+            obfuscated: false
         };
     }
 
@@ -51,7 +53,8 @@ export class NodeMocks {
         return {
             type: NodeType.CatchClause,
             param: NodeMocks.getIdentifierNode('err'),
-            body: NodeMocks.getBlockStatementNode(bodyNodes)
+            body: NodeMocks.getBlockStatementNode(bodyNodes),
+            obfuscated: false
         };
     }
 
@@ -67,7 +70,8 @@ export class NodeMocks {
         return {
             type: NodeType.CallExpression,
             callee: callee,
-            arguments: args
+            arguments: args,
+            obfuscated: false
         };
     }
 
@@ -80,7 +84,8 @@ export class NodeMocks {
     ): IExpressionStatementNode {
         return {
             type: NodeType.ExpressionStatement,
-            expression: expression
+            expression: expression,
+            obfuscated: false
         };
     }
 
@@ -101,7 +106,8 @@ export class NodeMocks {
             params: params,
             body: blockStatementNode,
             generator: false,
-            expression: false
+            expression: false,
+            obfuscated: false
         };
     }
 
@@ -115,10 +121,12 @@ export class NodeMocks {
             test: {
                 type: 'Literal',
                 value: true,
-                raw: 'true'
+                raw: 'true',
+                obfuscated: false
             },
             consequent: blockStatementNode,
-            alternate: null
+            alternate: null,
+            obfuscated: false
         };
     }
 
@@ -130,6 +138,7 @@ export class NodeMocks {
         return {
             type: NodeType.Identifier,
             name: identifierName,
+            obfuscated: false
         };
     }
 
@@ -145,7 +154,8 @@ export class NodeMocks {
             'x-verbatim-property': {
                 content: `'${value}'`,
                 precedence: escodegen.Precedence.Primary
-            }
+            },
+            obfuscated: false
         };
     }
 
@@ -162,7 +172,8 @@ export class NodeMocks {
             type: NodeType.MemberExpression,
             computed: false,
             object: object,
-            property: property
+            property: property,
+            obfuscated: false
         };
     }
 
@@ -178,7 +189,8 @@ export class NodeMocks {
         return {
             type: NodeType.VariableDeclaration,
             declarations: declarations,
-            kind: kind
+            kind: kind,
+            obfuscated: false
         };
     }
 
@@ -191,7 +203,8 @@ export class NodeMocks {
         return {
             type: NodeType.VariableDeclarator,
             id: id,
-            init: init
+            init: init,
+            obfuscated: false
         };
     }
 }

+ 1 - 1
test/unit-tests/NodeUtils.spec.ts

@@ -102,7 +102,7 @@ describe('NodeUtils', () => {
         });
 
         it('should convert code to `INode` structure', () => {
-            assert.deepEqualIdent(NodeUtils.convertCodeToStructure(code), variableDeclarationNode);
+            assert.deepEqual(NodeUtils.convertCodeToStructure(code), variableDeclarationNode);
         });
     });
 

+ 9 - 12
webpack.config.js

@@ -1,15 +1,13 @@
 'use strict';
 
-let fs = require("fs"),
+var fs = require("fs"),
     nodeExternals = require('webpack-node-externals'),
-    webpack = require('webpack');
+    webpack = require('webpack'),
+    OptimizeJSPlugin = require('optimize-js-plugin');
 
 function getLicenseText () {
-    return `/*
-Copyright (C) 2016 Timofey Kachalov <[email protected]>
-
-${fs.readFileSync('./LICENSE.BSD', 'utf8')}
-*/`;
+    return "/*\nCopyright (C) 2016 Timofey Kachalov <[email protected]>\n\n" +
+        fs.readFileSync('./LICENSE.BSD', 'utf8') + "\n*/";
 }
 
 module.exports = {
@@ -25,17 +23,16 @@ module.exports = {
         ]
     },
     resolve: {
-        extensions: ['', '.ts'],
-        modulesDirectories: ['./src', './node_modules']
+        extensions: ['.ts']
     },
     plugins: [
         new webpack.BannerPlugin(
             {
-                banner: `${getLicenseText()}\n\nrequire("source-map-support").install();\n`,
+                banner: getLicenseText() + '\n\nrequire("source-map-support").install();\n',
                 raw: true,
                 entryOnly: false
             }
-        )
+        ),
     ],
     output: {
         path: './dist',
@@ -43,4 +40,4 @@ module.exports = {
         libraryTarget:  "commonjs2",
         library: "JavaScriptObfuscator"
     }
-};
+};