瀏覽代碼

cache scopeNodes for more faster traversing during obfuscation

sanex3339 8 年之前
父節點
當前提交
90e744734f

+ 94 - 2
dist/index.js

@@ -4796,6 +4796,14 @@ exports.CatchClauseObfuscator = CatchClauseObfuscator;
 "use strict";
 
 
+var _getIterator2 = __webpack_require__(24);
+
+var _getIterator3 = _interopRequireDefault(_getIterator2);
+
+var _map = __webpack_require__(12);
+
+var _map2 = _interopRequireDefault(_map);
+
 var _getPrototypeOf = __webpack_require__(5);
 
 var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
@@ -4836,6 +4844,7 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeTransfor) {
 
         var _this = (0, _possibleConstructorReturn3.default)(this, (FunctionDeclarationObfuscator.__proto__ || (0, _getPrototypeOf2.default)(FunctionDeclarationObfuscator)).call(this, options));
 
+        _this.replaceableIdentifiers = new _map2.default();
         _this.identifierReplacer = nodeObfuscatorsReplacersFactory(NodeObfuscatorsReplacers_1.NodeObfuscatorsReplacers.IdentifierReplacer);
         return _this;
     }
@@ -4867,13 +4876,50 @@ var FunctionDeclarationObfuscator = function (_AbstractNodeTransfor) {
         value: function replaceFunctionName(scopeNode, nodeIdentifier) {
             var _this3 = this;
 
+            var replaceableIdentifiersForCurrentScope = void 0;
+            if (this.replaceableIdentifiers.has(scopeNode)) {
+                replaceableIdentifiersForCurrentScope = this.replaceableIdentifiers.get(scopeNode);
+                var _iteratorNormalCompletion = true;
+                var _didIteratorError = false;
+                var _iteratorError = undefined;
+
+                try {
+                    for (var _iterator = (0, _getIterator3.default)(replaceableIdentifiersForCurrentScope), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+                        var replaceableIdentifier = _step.value;
+
+                        replaceableIdentifier.name = this.identifierReplacer.replace(replaceableIdentifier.name, nodeIdentifier);
+                    }
+                } catch (err) {
+                    _didIteratorError = true;
+                    _iteratorError = err;
+                } finally {
+                    try {
+                        if (!_iteratorNormalCompletion && _iterator.return) {
+                            _iterator.return();
+                        }
+                    } finally {
+                        if (_didIteratorError) {
+                            throw _iteratorError;
+                        }
+                    }
+                }
+
+                return;
+            }
+            replaceableIdentifiersForCurrentScope = [];
             estraverse.replace(scopeNode, {
                 enter: function enter(node, parentNode) {
                     if (Node_1.Node.isReplaceableIdentifierNode(node, parentNode)) {
-                        node.name = _this3.identifierReplacer.replace(node.name, nodeIdentifier);
+                        var newNodeName = _this3.identifierReplacer.replace(node.name, nodeIdentifier);
+                        if (node.name !== newNodeName) {
+                            node.name = newNodeName;
+                        } else {
+                            replaceableIdentifiersForCurrentScope.push(node);
+                        }
                     }
                 }
             });
+            this.replaceableIdentifiers.set(scopeNode, replaceableIdentifiersForCurrentScope);
         }
     }]);
     return FunctionDeclarationObfuscator;
@@ -5431,6 +5477,14 @@ exports.ObjectExpressionObfuscator = ObjectExpressionObfuscator;
 "use strict";
 
 
+var _getIterator2 = __webpack_require__(24);
+
+var _getIterator3 = _interopRequireDefault(_getIterator2);
+
+var _map = __webpack_require__(12);
+
+var _map2 = _interopRequireDefault(_map);
+
 var _getPrototypeOf = __webpack_require__(5);
 
 var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
@@ -5471,6 +5525,7 @@ var VariableDeclarationObfuscator = function (_AbstractNodeTransfor) {
 
         var _this = (0, _possibleConstructorReturn3.default)(this, (VariableDeclarationObfuscator.__proto__ || (0, _getPrototypeOf2.default)(VariableDeclarationObfuscator)).call(this, options));
 
+        _this.replaceableIdentifiers = new _map2.default();
         _this.identifierReplacer = replacersFactory(NodeObfuscatorsReplacers_1.NodeObfuscatorsReplacers.IdentifierReplacer);
         return _this;
     }
@@ -5505,13 +5560,50 @@ var VariableDeclarationObfuscator = function (_AbstractNodeTransfor) {
         value: function replaceVariableNames(scopeNode, nodeIdentifier) {
             var _this3 = this;
 
+            var replaceableIdentifiersForCurrentScope = void 0;
+            if (this.replaceableIdentifiers.has(scopeNode)) {
+                replaceableIdentifiersForCurrentScope = this.replaceableIdentifiers.get(scopeNode);
+                var _iteratorNormalCompletion = true;
+                var _didIteratorError = false;
+                var _iteratorError = undefined;
+
+                try {
+                    for (var _iterator = (0, _getIterator3.default)(replaceableIdentifiersForCurrentScope), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+                        var replaceableIdentifier = _step.value;
+
+                        replaceableIdentifier.name = this.identifierReplacer.replace(replaceableIdentifier.name, nodeIdentifier);
+                    }
+                } catch (err) {
+                    _didIteratorError = true;
+                    _iteratorError = err;
+                } finally {
+                    try {
+                        if (!_iteratorNormalCompletion && _iterator.return) {
+                            _iterator.return();
+                        }
+                    } finally {
+                        if (_didIteratorError) {
+                            throw _iteratorError;
+                        }
+                    }
+                }
+
+                return;
+            }
+            replaceableIdentifiersForCurrentScope = [];
             estraverse.replace(scopeNode, {
                 enter: function enter(node, parentNode) {
                     if (!node.obfuscated && Node_1.Node.isReplaceableIdentifierNode(node, parentNode)) {
-                        node.name = _this3.identifierReplacer.replace(node.name, nodeIdentifier);
+                        var newNodeName = _this3.identifierReplacer.replace(node.name, nodeIdentifier);
+                        if (node.name !== newNodeName) {
+                            node.name = newNodeName;
+                        } else {
+                            replaceableIdentifiersForCurrentScope.push(node);
+                        }
                     }
                 }
             });
+            this.replaceableIdentifiers.set(scopeNode, replaceableIdentifiersForCurrentScope);
         }
     }]);
     return VariableDeclarationObfuscator;

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

@@ -34,6 +34,11 @@ export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
      */
     private readonly identifierReplacer: IObfuscatorReplacerWithStorage;
 
+    /**
+     * @type {Map<ESTree.Node, ESTree.Identifier[]>}
+     */
+    private readonly replaceableIdentifiers: Map <ESTree.Node, ESTree.Identifier[]> = new Map();
+
     /**
      * @param nodeObfuscatorsReplacersFactory
      * @param options
@@ -79,12 +84,37 @@ export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
      * @param nodeIdentifier
      */
     private replaceFunctionName (scopeNode: ESTree.Node, nodeIdentifier: string): void {
+        let replaceableIdentifiersForCurrentScope: ESTree.Identifier[];
+
+        /**
+         * check for cached identifiers for current scope node. If exist - loop through them.
+         */
+        if (this.replaceableIdentifiers.has(scopeNode)) {
+            replaceableIdentifiersForCurrentScope = <ESTree.Identifier[]>this.replaceableIdentifiers.get(scopeNode);
+
+            for (const replaceableIdentifier of replaceableIdentifiersForCurrentScope) {
+                replaceableIdentifier.name = this.identifierReplacer.replace(replaceableIdentifier.name, nodeIdentifier);
+            }
+
+            return;
+        }
+
+        replaceableIdentifiersForCurrentScope = [];
+
         estraverse.replace(scopeNode, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
                 if (Node.isReplaceableIdentifierNode(node, parentNode)) {
-                    node.name = this.identifierReplacer.replace(node.name, nodeIdentifier);
+                    const newNodeName: string = this.identifierReplacer.replace(node.name, nodeIdentifier);
+
+                    if (node.name !== newNodeName) {
+                        node.name = newNodeName;
+                    } else {
+                        replaceableIdentifiersForCurrentScope.push(node);
+                    }
                 }
             }
         });
+
+        this.replaceableIdentifiers.set(scopeNode, replaceableIdentifiersForCurrentScope);
     }
 }

+ 32 - 1
src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts

@@ -35,6 +35,11 @@ export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
      */
     private readonly identifierReplacer: IObfuscatorReplacerWithStorage;
 
+    /**
+     * @type {Map<ESTree.Node, ESTree.Identifier[]>}
+     */
+    private readonly replaceableIdentifiers: Map <ESTree.Node, ESTree.Identifier[]> = new Map();
+
     /**
      * @param replacersFactory
      * @param options
@@ -87,12 +92,38 @@ export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
      * @param nodeIdentifier
      */
     private replaceVariableNames (scopeNode: ESTree.Node, nodeIdentifier: string): void {
+        let replaceableIdentifiersForCurrentScope: ESTree.Identifier[];
+
+        /**
+         * check for cached identifiers for current scope node. If exist - loop through them.
+         * if name of the identifier has been changed - remove identifier, so we won't iterate over him next time.
+         */
+        if (this.replaceableIdentifiers.has(scopeNode)) {
+            replaceableIdentifiersForCurrentScope = <ESTree.Identifier[]>this.replaceableIdentifiers.get(scopeNode);
+
+            for (const replaceableIdentifier of replaceableIdentifiersForCurrentScope) {
+                replaceableIdentifier.name = this.identifierReplacer.replace(replaceableIdentifier.name, nodeIdentifier);
+            }
+
+            return;
+        }
+
+        replaceableIdentifiersForCurrentScope = [];
+
         estraverse.replace(scopeNode, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
                 if (!node.obfuscated && Node.isReplaceableIdentifierNode(node, parentNode)) {
-                    node.name = this.identifierReplacer.replace(node.name, nodeIdentifier);
+                    const newNodeName: string = this.identifierReplacer.replace(node.name, nodeIdentifier);
+
+                    if (node.name !== newNodeName) {
+                        node.name = newNodeName;
+                    } else {
+                        replaceableIdentifiersForCurrentScope.push(node);
+                    }
                 }
             }
         });
+
+        this.replaceableIdentifiers.set(scopeNode, replaceableIdentifiersForCurrentScope);
     }
 }

+ 1 - 2
test/dev/dev.ts

@@ -84,8 +84,7 @@ if (!(<any>global)._babelPolyfill) {
         {
             compact: false,
             controlFlowFlattening: true,
-            disableConsoleOutput: false,
-            unicodeEscapeSequence: false
+            disableConsoleOutput: false
         }
     ).getObfuscatedCode();