Переглянути джерело

Added tests for issue https://github.com/javascript-obfuscator/javascript-obfuscator/issues/297

sanex3339 6 роки тому
батько
коміт
0e76dbcf50

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
dist/index.cli.js


Різницю між файлами не показано, бо вона завелика
+ 0 - 0
dist/index.js


+ 16 - 16
package.json

@@ -21,12 +21,12 @@
   },
   "types": "index.d.ts",
   "dependencies": {
-    "@babel/runtime": "7.0.0-beta.51",
+    "@babel/runtime": "7.0.0-beta.54",
     "chalk": "2.4.1",
     "chance": "1.0.16",
-    "class-validator": "0.8.5",
-    "commander": "2.15.1",
-    "escodegen-wallaby": "1.6.18",
+    "class-validator": "0.9.0",
+    "commander": "2.16.0",
+    "escodegen-wallaby": "1.6.19",
     "espree": "4.0.0",
     "estraverse": "4.2.0",
     "inversify": "4.13.0",
@@ -41,10 +41,10 @@
     "tslib": "1.9.3"
   },
   "devDependencies": {
-    "@babel/cli": "7.0.0-beta.51",
-    "@babel/core": "7.0.0-beta.51",
-    "@babel/plugin-transform-runtime": "7.0.0-beta.51",
-    "@babel/preset-env": "7.0.0-beta.51",
+    "@babel/cli": "7.0.0-beta.54",
+    "@babel/core": "7.0.0-beta.54",
+    "@babel/plugin-transform-runtime": "7.0.0-beta.54",
+    "@babel/preset-env": "7.0.0-beta.54",
     "@types/chai": "4.1.4",
     "@types/chance": "1.0.1",
     "@types/escodegen": "0.0.6",
@@ -52,9 +52,9 @@
     "@types/estree": "0.0.38",
     "@types/md5": "2.1.32",
     "@types/mkdirp": "0.5.2",
-    "@types/mocha": "5.2.3",
+    "@types/mocha": "5.2.5",
     "@types/multimatch": "2.1.2",
-    "@types/node": "10.3.6",
+    "@types/node": "10.5.2",
     "@types/rimraf": "2.0.2",
     "@types/sinon": "5.0.1",
     "@types/string-template": "1.0.2",
@@ -62,23 +62,23 @@
     "awesome-typescript-loader": "5.2.0",
     "babel-loader": "8.0.0-beta.3",
     "chai": "4.1.2",
-    "coveralls": "3.0.1",
+    "coveralls": "3.0.2",
     "istanbul": "1.1.0-alpha.1",
     "mocha": "5.2.0",
     "pjson": "1.0.9",
     "pre-commit": "1.2.2",
     "rimraf": "2.6.2",
-    "sinon": "6.0.1",
+    "sinon": "6.1.3",
     "threads": "0.12.0",
     "ts-node": "6.1.0",
-    "tslint": "5.10.0",
+    "tslint": "5.11.0",
     "tslint-eslint-rules": "5.3.1",
     "tslint-language-service": "0.9.9",
-    "tslint-microsoft-contrib": "5.0.3",
+    "tslint-microsoft-contrib": "5.1.0",
     "tslint-webpack-plugin": "1.2.2",
     "typescript": "2.9.2",
-    "webpack": "4.12.2",
-    "webpack-cli": "3.0.8",
+    "webpack": "4.16.1",
+    "webpack-cli": "3.1.0",
     "webpack-node-externals": "1.7.2"
   },
   "repository": {

+ 7 - 36
src/node-transformers/obfuscating-transformers/FunctionTransformer.ts

@@ -62,13 +62,7 @@ export class FunctionTransformer extends AbstractNodeTransformer {
             case TransformationStage.Obfuscating:
                 return {
                     enter: (node: ESTree.Node, parentNode: ESTree.Node | null) => {
-                        if (
-                            parentNode && (
-                                NodeGuards.isFunctionDeclarationNode(node) ||
-                                NodeGuards.isFunctionExpressionNode(node) ||
-                                NodeGuards.isArrowFunctionExpressionNode(node)
-                            )
-                        ) {
+                        if (parentNode && NodeGuards.isFunctionNode(node)) {
                             return this.transformNode(node, parentNode);
                         }
                     }
@@ -104,7 +98,11 @@ export class FunctionTransformer extends AbstractNodeTransformer {
             .forEach((paramsNode: ESTree.Node) => {
                 estraverse.traverse(paramsNode, {
                     enter: (node: ESTree.Node): estraverse.VisitorOption | void => {
-                        if (NodeGuards.isPropertyNode(paramsNode)) {
+                        if (
+                            NodeGuards.isPropertyNode(node)
+                            && node.shorthand
+                            && NodeGuards.isIdentifierNode(node.key)
+                        ) {
                             return estraverse.VisitorOption.Skip;
                         }
 
@@ -122,41 +120,14 @@ export class FunctionTransformer extends AbstractNodeTransformer {
             });
     }
 
-    /**
-     * @param {Property[]} properties
-     * @param {Set<string>} ignoredIdentifierNamesSet
-     */
-    private addIdentifiersToIgnoredIdentifierNamesSet (
-        properties: ESTree.Property[],
-        ignoredIdentifierNamesSet: Set<string>
-    ): void {
-        properties.forEach((property: ESTree.Property) => {
-            if (!property.key || !NodeGuards.isIdentifierNode(property.key)) {
-                return;
-            }
-
-            ignoredIdentifierNamesSet.add(property.key.name);
-        });
-    }
-
     /**
      * @param {Function} functionNode
      * @param {TNodeWithBlockScope} blockScopeNode
      */
     private replaceFunctionParams (functionNode: ESTree.Function, blockScopeNode: TNodeWithBlockScope): void {
-        const ignoredIdentifierNamesSet: Set<string> = new Set();
-
         const replaceVisitor: estraverse.Visitor = {
             enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
-                if (NodeGuards.isObjectPatternNode(node)) {
-                    this.addIdentifiersToIgnoredIdentifierNamesSet(node.properties, ignoredIdentifierNamesSet);
-                }
-
-                if (
-                    parentNode &&
-                    NodeGuards.isReplaceableIdentifierNode(node, parentNode) &&
-                    !ignoredIdentifierNamesSet.has(node.name)
-                ) {
+                if (parentNode && NodeGuards.isReplaceableIdentifierNode(node, parentNode)) {
                     const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
                         .replace(node.name, blockScopeNode);
                     const newIdentifierName: string = newIdentifier.name;

+ 10 - 0
src/node/NodeGuards.ts

@@ -120,6 +120,16 @@ export class NodeGuards {
         return node.type === NodeType.ExpressionStatement;
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isFunctionNode(node: ESTree.Node): node is ESTree.Function {
+        return NodeGuards.isFunctionDeclarationNode(node) ||
+            NodeGuards.isFunctionExpressionNode(node) ||
+            NodeGuards.isArrowFunctionExpressionNode(node);
+    }
+
     /**
      * @param {Node} node
      * @returns {boolean}

+ 3 - 5
test/dev/dev.ts

@@ -6,11 +6,9 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-        (function () {
-            let a = 0;
-            let b = 0;
-            var test = {a, b};
-        })();
+        function foo (data) {
+            return ({data}) => data + 1;
+        }	
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,

+ 68 - 2
test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/FunctionTransformer.spec.ts

@@ -77,8 +77,10 @@ describe('FunctionTransformer', () => {
         });
 
         describe('Variant #2: correct transformation when identifier with same name in parent scope exist', () => {
+            const functionParameterRegExp: RegExp = /^\(function *\(\) *{ *function *_0x[a-f0-9]{4,6} *\(_0x[a-f0-9]{4,6}\) *\{/;
             const callbackParameterRegExp: RegExp = /\['then'] *\(\({ *data *}\)/;
             const callbackBodyRegExp: RegExp = /console\['log']\(data\)/;
+            const returnRegExp: RegExp = /return _0x[a-f0-9]{4,6};/;
 
             let obfuscatedCode: string;
 
@@ -94,13 +96,53 @@ describe('FunctionTransformer', () => {
                 obfuscatedCode = obfuscationResult.getObfuscatedCode();
             });
 
-            it('match #1: shouldn\'t transform callback parameter object pattern identifier', () => {
-                assert.match(obfuscatedCode, callbackParameterRegExp);
+            it('match #1: should transform function parameter identifier', () => {
+                assert.match(obfuscatedCode, functionParameterRegExp);
             });
 
             it('match #2: shouldn\'t transform callback parameter object pattern identifier', () => {
+                assert.match(obfuscatedCode, callbackParameterRegExp);
+            });
+
+            it('match #3: shouldn\'t transform callback body identifier', () => {
                 assert.match(obfuscatedCode, callbackBodyRegExp);
             });
+
+            it('match #4: should transform identifier in `ReturnStatement`', () => {
+                assert.match(obfuscatedCode, returnRegExp);
+            });
+        });
+
+        describe('Variant #3: correct transformation when parent scope identifier conflicts with current scope object pattern identifier', () => {
+            const functionObjectPatternParameterRegExp: RegExp = /function _0x[a-f0-9]{4,6} *\({data, *\.\.\._0x[a-f0-9]{4,6}}\) *{/;
+            const returnRegExp1: RegExp = /return data *\+ *_0x[a-f0-9]{4,6};/;
+            const returnRegExp2: RegExp = /return _0x[a-f0-9]{4,6};/;
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/object-pattern-as-parameter-3.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET
+                    }
+                );
+
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+            });
+
+            it('match #1: should transform function parameter object pattern rest identifier', () => {
+                assert.match(obfuscatedCode, functionObjectPatternParameterRegExp);
+            });
+
+            it('match #2: should transform identifier in `ReturnStatement` of inner function', () => {
+                assert.match(obfuscatedCode, returnRegExp1);
+            });
+
+            it('match #2: should transform identifier in `ReturnStatement` of outer function', () => {
+                assert.match(obfuscatedCode, returnRegExp2);
+            });
         });
     });
 
@@ -365,4 +407,28 @@ describe('FunctionTransformer', () => {
             assert.match(obfuscatedCode, returnRegExp);
         });
     });
+
+    describe('ignored identifier names set', () => {
+        describe('Variant #1: avoid to add `ObjectPattern` identifier to the set when same identifier exist in function parameter', () => {
+            const functionBodyRegExp: RegExp = /\[]\['find']\(\({bar: *_0x[a-f0-9]{4,6}}\) *=> *_0x[a-f0-9]{4,6}\);/;
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/identifier-names-set-object-pattern.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET
+                    }
+                );
+
+                obfuscatedCode = obfuscationResult.getObfuscatedCode();
+            });
+
+            it('should transform identifiers in function body', () => {
+                assert.match(obfuscatedCode, functionBodyRegExp);
+            });
+        });
+    });
 });

+ 3 - 0
test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/identifier-names-set-object-pattern.js

@@ -0,0 +1,3 @@
+function foo(bar) {
+    [].find(({bar: baz}) => bar);
+}

+ 1 - 0
test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/object-pattern-as-parameter-2.js

@@ -2,6 +2,7 @@
     function foo (data) {
         new Promise((resolve) => resolve({data: data}))
             .then(({data}) => console.log(data));
+        return data;
     }
 
     foo(1);

+ 9 - 0
test/functional-tests/node-transformers/obfuscating-transformers/function-transformer/fixtures/object-pattern-as-parameter-3.js

@@ -0,0 +1,9 @@
+(function(){
+    function foo (data) {
+        function bar ({data, ...rest}) {
+            return data + rest;
+        }
+
+        return data;
+    }
+})();

Різницю між файлами не показано, бо вона завелика
+ 467 - 464
yarn.lock


Деякі файли не було показано, через те що забагато файлів було змінено