Pārlūkot izejas kodu

Merge pull request #770 from javascript-obfuscator/dead-code-injection-prevent-for-await-of

Fixed `for-await-of` construction add when `deadCodeInjection` option is enabled
Timofey Kachalov 4 gadi atpakaļ
vecāks
revīzija
c459acdcf4

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 
+v2.4.3
+---
+* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/769
+
 v2.4.2
 ---
 * Fixed `URI-malformed` when `splitStrings` and `stringArrayEncoding` options are enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/530

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/index.browser.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/index.cli.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/index.js


+ 1 - 1
package.json

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

+ 2 - 1
src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts

@@ -106,7 +106,8 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
             || NodeGuards.isContinueStatementNode(targetNode)
             || NodeGuards.isAwaitExpressionNode(targetNode)
             || NodeGuards.isYieldExpressionNode(targetNode)
-            || NodeGuards.isSuperNode(targetNode);
+            || NodeGuards.isSuperNode(targetNode)
+            || (NodeGuards.isForOfStatementNode(targetNode) && targetNode.await);
     }
 
     /**

+ 8 - 0
src/node/NodeGuards.ts

@@ -141,6 +141,14 @@ export class NodeGuards {
             && !('directive' in node);
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isForOfStatementNode (node: ESTree.Node): node is ESTree.ForOfStatement {
+        return node.type === NodeType.ForOfStatement;
+    }
+
     /**
      * @param {Node} node
      * @returns {boolean}

+ 51 - 0
test/functional-tests/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.spec.ts

@@ -438,6 +438,57 @@ describe('DeadCodeInjectionTransformer', () => {
                     assert.equal(superExpressionMatchesLength, expectedSuperExpressionMatchesLength);
                 });
             });
+
+            describe('Variant #6 - for-await expression in block statement', () => {
+                const functionRegExp: RegExp = new RegExp(
+                    `var ${variableMatch} *= *function *\\(\\) *\\{` +
+                        `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
+                    `\\};`,
+                    'g'
+                );
+                const awaitExpressionRegExp: RegExp = new RegExp(
+                    `for await *\\(const ${variableMatch} of *\\[]\\){}`,
+                    'g'
+                );
+                const expectedFunctionMatchesLength: number = 4;
+                const expectedAwaitExpressionMatchesLength: number = 1;
+
+                let functionMatchesLength: number = 0,
+                    awaitExpressionMatchesLength: number = 0;
+
+                before(() => {
+                    const code: string = readFileAsString(__dirname + '/fixtures/for-await-expression.js');
+
+                    const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
+                        code,
+                        {
+                            ...NO_ADDITIONAL_NODES_PRESET,
+                            deadCodeInjection: true,
+                            deadCodeInjectionThreshold: 1,
+                            stringArray: true,
+                            stringArrayThreshold: 1
+                        }
+                    ).getObfuscatedCode();
+                    const functionMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(functionRegExp);
+                    const awaitExpressionMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(awaitExpressionRegExp);
+
+                    if (functionMatches) {
+                        functionMatchesLength = functionMatches.length;
+                    }
+
+                    if (awaitExpressionMatches) {
+                        awaitExpressionMatchesLength = awaitExpressionMatches.length;
+                    }
+                });
+
+                it('match #1: shouldn\'t add dead code', () => {
+                    assert.equal(functionMatchesLength, expectedFunctionMatchesLength);
+                });
+
+                it('match #2: shouldn\'t add dead code', () => {
+                    assert.equal(awaitExpressionMatchesLength, expectedAwaitExpressionMatchesLength);
+                });
+            });
         });
 
         describe('Variant #5 - chance of `IfStatement` variant', () => {

+ 25 - 0
test/functional-tests/node-transformers/dead-code-injection-transformers/fixtures/for-await-expression.js

@@ -0,0 +1,25 @@
+(async function(){
+    if (true) {
+        var foo = function () {
+            console.log('abc');
+        };
+        var bar = function () {
+            console.log('def');
+        };
+        var baz = function () {
+            console.log('ghi');
+        };
+        var bark = function () {
+            console.log('jkl');
+        };
+
+        if (true) {
+            for await (const item of []) {}
+        }
+
+        foo();
+        bar();
+        baz();
+        bark();
+    }
+})();

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels