Преглед изворни кода

Fixed wrong object keys transformation of objects inside sequence expressions

sanex3339 пре 5 година
родитељ
комит
87c8c612b8

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
dist/index.browser.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
dist/index.cli.js


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
dist/index.js


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "javascript-obfuscator",
   "name": "javascript-obfuscator",
-  "version": "0.24.0-rc.1",
+  "version": "0.24.0-rc.2",
   "description": "JavaScript obfuscator",
   "description": "JavaScript obfuscator",
   "keywords": [
   "keywords": [
     "obfuscator",
     "obfuscator",

+ 1 - 0
src/enums/node/NodeType.ts

@@ -36,6 +36,7 @@ export enum NodeType {
     Property = 'Property',
     Property = 'Property',
     RestElement = 'RestElement',
     RestElement = 'RestElement',
     ReturnStatement = 'ReturnStatement',
     ReturnStatement = 'ReturnStatement',
+    SequenceExpression = 'SequenceExpression',
     Super = 'Super',
     Super = 'Super',
     SwitchCase = 'SwitchCase',
     SwitchCase = 'SwitchCase',
     SwitchStatement = 'SwitchStatement',
     SwitchStatement = 'SwitchStatement',

+ 60 - 1
src/node-transformers/converting-transformers/ObjectExpressionKeysTransformer.ts

@@ -58,7 +58,9 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
         hostStatement: ESTree.Statement
         hostStatement: ESTree.Statement
     ): boolean {
     ): boolean {
         return ObjectExpressionKeysTransformer.isProhibitedVariableDeclarationHostStatement(objectExpressionNode, hostStatement)
         return ObjectExpressionKeysTransformer.isProhibitedVariableDeclarationHostStatement(objectExpressionNode, hostStatement)
-            || ObjectExpressionKeysTransformer.isProhibitedFunctionHostStatement(objectExpressionNode, hostStatement);
+            || ObjectExpressionKeysTransformer.isProhibitedFunctionHostStatement(objectExpressionNode, hostStatement)
+            || ObjectExpressionKeysTransformer.isProhibitedExpressionHostStatement(objectExpressionNode, hostStatement)
+            || ObjectExpressionKeysTransformer.isProhibitedReturnHostStatement(objectExpressionNode, hostStatement);
     }
     }
 
 
     /**
     /**
@@ -109,6 +111,63 @@ export class ObjectExpressionKeysTransformer extends AbstractNodeTransformer {
         );
         );
     }
     }
 
 
+    /**
+     * @param {ObjectExpression} objectExpressionNode
+     * @param {Statement} hostStatement
+     * @returns {boolean}
+     */
+    private static isProhibitedReturnHostStatement (
+        objectExpressionNode: ESTree.ObjectExpression,
+        hostStatement: ESTree.Statement
+    ): boolean {
+        if (!NodeGuards.isReturnStatementNode(hostStatement) || !hostStatement.argument) {
+            return false;
+        }
+
+        return ObjectExpressionKeysTransformer.isProhibitedSequenceExpressionNode(
+            objectExpressionNode,
+            hostStatement.argument
+        );
+    }
+
+    /**
+     * @param {ObjectExpression} objectExpressionNode
+     * @param {Statement} hostStatement
+     * @returns {boolean}
+     */
+    private static isProhibitedExpressionHostStatement (
+        objectExpressionNode: ESTree.ObjectExpression,
+        hostStatement: ESTree.Statement
+    ): boolean {
+        if (!NodeGuards.isExpressionStatementNode(hostStatement)) {
+            return false;
+        }
+
+        return ObjectExpressionKeysTransformer.isProhibitedSequenceExpressionNode(
+            objectExpressionNode,
+            hostStatement.expression
+        );
+    }
+
+    /**
+     * @param {ObjectExpression} objectExpressionNode
+     * @param {Statement} node
+     * @returns {boolean}
+     */
+    private static isProhibitedSequenceExpressionNode (
+        objectExpressionNode: ESTree.ObjectExpression,
+        node: ESTree.Node
+    ): boolean {
+        if (!NodeGuards.isSequenceExpressionNode(node) || !node.expressions.length) {
+            return false;
+        }
+
+        return ObjectExpressionKeysTransformer.isReferencedIdentifierName(
+            objectExpressionNode,
+            node.expressions
+        );
+    }
+
     /**
     /**
      * @param {ObjectExpression} objectExpressionNode
      * @param {ObjectExpression} objectExpressionNode
      * @param {Node[]} nodesToSearch
      * @param {Node[]} nodesToSearch

+ 8 - 0
src/node/NodeGuards.ts

@@ -358,6 +358,14 @@ export class NodeGuards {
         return node.type === NodeType.ReturnStatement;
         return node.type === NodeType.ReturnStatement;
     }
     }
 
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isSequenceExpressionNode (node: ESTree.Node): node is ESTree.SequenceExpression {
+        return node.type === NodeType.SequenceExpression;
+    }
+
     /**
     /**
      * @param {Node} node
      * @param {Node} node
      * @returns {boolean}
      * @returns {boolean}

+ 9 - 4
test/dev/dev.ts

@@ -7,14 +7,19 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
         `
-            var foo = {['foo']: 1};
+            function foo () {
+                var foo;
+                var bar;
+                (foo = {foo: 1}), (bar = {bar: foo.foo});
+                return bar.bar;
+            }
+            
+            console.log(foo());
         `,
         `,
         {
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
             compact: false,
-            unicodeEscapeSequence: true,
-            stringArray: true,
-            stringArrayThreshold: 1
+            transformObjectKeys: true
         }
         }
     ).getObfuscatedCode();
     ).getObfuscatedCode();
 
 

+ 126 - 0
test/functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/ObjectExpressionKeysTransformer.spec.ts

@@ -634,6 +634,71 @@ describe('ObjectExpressionKeysTransformer', () => {
                 });
                 });
             });
             });
         });
         });
+
+        describe('Variant #17: sequence expression object expressions', () => {
+            const match: string = `` +
+                `var ${variableMatch};` +
+                `var ${variableMatch};` +
+                `var ${variableMatch} *= *{};` +
+                `${variableMatch}\\['foo'] *= *0x1;` +
+                `var ${variableMatch} *= *{};` +
+                `${variableMatch}\\['bar'] *= *0x2;` +
+                `${variableMatch} *= *${variableMatch}, *` +
+                `${variableMatch} *= *${variableMatch};` +
+            ``;
+            const regExp: RegExp = new RegExp(match);
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/sequence-expression-object-expressions.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        transformObjectKeys: true
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('shouldn transform sequence expression object expressions keys', () => {
+                assert.match(obfuscatedCode,  regExp);
+            });
+        });
+
+        describe('Variant #18: return statement sequence expression object expressions', () => {
+            const match: string = `` +
+                `var ${variableMatch};` +
+                `var ${variableMatch};` +
+                `var ${variableMatch} *= *{};` +
+                `${variableMatch}\\['foo'] *= *0x1;` +
+                `var ${variableMatch} *= *{};` +
+                `${variableMatch}\\['bar'] *= *0x2;` +
+                `return ${variableMatch} *= *${variableMatch}, *` +
+                `${variableMatch} *= *${variableMatch}, *` +
+                `${variableMatch}\\['bar'];` +
+            ``;
+            const regExp: RegExp = new RegExp(match);
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/return-statement-sequence-expression-object-expressions.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        transformObjectKeys: true
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('shouldn transform sequence expression object expressions keys', () => {
+                assert.match(obfuscatedCode,  regExp);
+            });
+        });
     });
     });
 
 
     describe('member expression as host of object expression', () => {
     describe('member expression as host of object expression', () => {
@@ -1426,5 +1491,66 @@ describe('ObjectExpressionKeysTransformer', () => {
                 assert.match(obfuscatedCode,  regExp);
                 assert.match(obfuscatedCode,  regExp);
             });
             });
         });
         });
+
+        describe('Variant #5: sequence expression identifier reference', () => {
+            const match: string = `` +
+                `var ${variableMatch};` +
+                `var ${variableMatch};` +
+                `var ${variableMatch} *= *{};` +
+                `${variableMatch}\\['foo'] *= *0x1;` +
+                `${variableMatch} *= *${variableMatch}, *` +
+                `${variableMatch} *= *{'bar' *: *${variableMatch}\\['foo']};` +
+            ``;
+            const regExp: RegExp = new RegExp(match);
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/sequence-expression-identifier-reference.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        transformObjectKeys: true
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('shouldn ignore sequence expression object expression if it references other sequence expression identifier', () => {
+                assert.match(obfuscatedCode,  regExp);
+            });
+        });
+
+        describe('Variant #6: return statement sequence expression identifier reference', () => {
+            const match: string = `` +
+                `var ${variableMatch};` +
+                `var ${variableMatch};` +
+                `var ${variableMatch} *= *{};` +
+                `${variableMatch}\\['foo'] *= *0x1;` +
+                `return ${variableMatch} *= *${variableMatch}, *` +
+                `${variableMatch} *= *{'bar' *: *${variableMatch}\\['foo']}, *` +
+                `${variableMatch}\\['bar'];` +
+            ``;
+            const regExp: RegExp = new RegExp(match);
+
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/return-statement-sequence-expression-identifier-reference.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        transformObjectKeys: true
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('shouldn ignore sequence expression object expression if it references other sequence expression identifier', () => {
+                assert.match(obfuscatedCode,  regExp);
+            });
+        });
     });
     });
 });
 });

+ 7 - 0
test/functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/fixtures/return-statement-sequence-expression-identifier-reference.js

@@ -0,0 +1,7 @@
+function foo () {
+    var foo;
+    var bar;
+    return (foo = {foo: 1}),
+        (bar = {bar: foo.foo}),
+        bar.bar;
+}

+ 7 - 0
test/functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/fixtures/return-statement-sequence-expression-object-expressions.js

@@ -0,0 +1,7 @@
+function foo () {
+    var foo;
+    var bar;
+    return (foo = {foo: 1}),
+        (bar = {bar: 2}),
+        bar.bar;
+}

+ 5 - 0
test/functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/fixtures/sequence-expression-identifier-reference.js

@@ -0,0 +1,5 @@
+function foo () {
+    var foo;
+    var bar;
+    (foo = {foo: 1}), (bar = {bar: foo.foo});
+}

+ 5 - 0
test/functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/fixtures/sequence-expression-object-expressions.js

@@ -0,0 +1,5 @@
+function foo () {
+    var foo;
+    var bar;
+    (foo = {foo: 1}), (bar = {bar: 2});
+}

Неке датотеке нису приказане због велике количине промена