Ver código fonte

Dead code injection improvements #1

sanex3339 7 anos atrás
pai
commit
6378ea500d

+ 1 - 0
.npmignore

@@ -4,3 +4,4 @@
 coverage
 images
 test/fixtures/compile-performance.js
+test-tmp

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/index.js


+ 12 - 8
src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts

@@ -100,7 +100,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
      * @param {Node} blockStatementNode
      * @returns {boolean}
      */
-    private static isValidBlockStatementNode (blockStatementNode: ESTree.Node): boolean {
+    private static isValidCollectedBlockStatementNode (blockStatementNode: ESTree.Node): boolean {
         const isProhibitedNode: (node: ESTree.Node) => boolean =
             (node: ESTree.Node): boolean => NodeGuards.isBreakStatementNode(node) ||
                 NodeGuards.isContinueStatementNode(node) ||
@@ -183,7 +183,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
 
                 let clonedBlockStatementNode: ESTree.BlockStatement = NodeUtils.clone(node);
 
-                if (!DeadCodeInjectionTransformer.isValidBlockStatementNode(clonedBlockStatementNode)) {
+                if (!DeadCodeInjectionTransformer.isValidCollectedBlockStatementNode(clonedBlockStatementNode)) {
                     return;
                 }
 
@@ -210,15 +210,17 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
      * @returns {NodeGuards | VisitorOption}
      */
     public transformNode (blockStatementNode: ESTree.BlockStatement, parentNode: ESTree.Node): ESTree.Node | estraverse.VisitorOption {
-        if (this.collectedBlockStatementsTotalLength < DeadCodeInjectionTransformer.minCollectedBlockStatementsCount) {
-            return estraverse.VisitorOption.Break;
-        }
+        const canBreakTraverse: boolean = !this.collectedBlockStatements.length
+            || this.collectedBlockStatementsTotalLength < DeadCodeInjectionTransformer.minCollectedBlockStatementsCount;
 
-        if (!this.collectedBlockStatements.length) {
+        if (canBreakTraverse) {
             return estraverse.VisitorOption.Break;
         }
 
-        if (this.randomGenerator.getMathRandom() > this.options.deadCodeInjectionThreshold) {
+        const isInvalidBlockStatementNode: boolean = !blockStatementNode.body.length
+            || this.randomGenerator.getMathRandom() > this.options.deadCodeInjectionThreshold;
+
+        if (isInvalidBlockStatementNode) {
             return blockStatementNode;
         }
 
@@ -233,8 +235,10 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
         const maxInteger: number = this.collectedBlockStatements.length - 1;
         const randomIndex: number = this.randomGenerator.getRandomInteger(minInteger, maxInteger);
         const randomBlockStatementNode: ESTree.BlockStatement = this.collectedBlockStatements.splice(randomIndex, 1)[0];
+        const isInvalidRandomBlockStatementNode: boolean = randomBlockStatementNode === blockStatementNode
+            || !randomBlockStatementNode.body.length;
 
-        if (randomBlockStatementNode === blockStatementNode) {
+        if (isInvalidRandomBlockStatementNode) {
             return blockStatementNode;
         }
 

+ 24 - 6
test/dev/dev.ts

@@ -6,18 +6,36 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-        var bar = 1;
-        var baz = 2;
         (function(){
-            var bark = bar + baz;
+            function foo () {
+                function inner1 () {}
+                inner1();
+            }
+            function bar () {
+                function inner2 () {}
+                inner2();
+            }
+            function baz () {
+                function inner3 () {}
+                inner3();
+            }
+            function bark () {
+                function inner4 () {}
+                inner4();
+            }
+            function hawk () {
+                function inner5 () {}
+                inner5();
+            }
         })();
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
-            identifiersPrefix: 'foo',
-            identifierNamesGenerator: 'mangled',
-            renameGlobals: true
+            stringArray: true,
+            stringArrayThreshold: 1,
+            deadCodeInjection: true,
+            deadCodeInjectionThreshold: 1
         }
     ).getObfuscatedCode();
 

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

@@ -481,5 +481,41 @@ describe('DeadCodeInjectionTransformer', () => {
                 assert.notEqual(returnIdentifierName, variableDeclarationIdentifierName);
             });
         });
+
+        describe('variant #11 - block statements with empty body', () => {
+            const regExp: RegExp = new RegExp(
+                `function *${variableMatch} *\\(\\) *{ *} *` +
+                `${variableMatch} *\\(\\); *`,
+                'g'
+            );
+            const expectedMatchesLength: number = 5;
+
+            let matchesLength: number = 0;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/block-statement-empty-body.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        stringArray: true,
+                        stringArrayThreshold: 1,
+                        deadCodeInjection: true,
+                        deadCodeInjectionThreshold: 1
+                    }
+                );
+
+                const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
+                const functionMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(regExp);
+
+                if (functionMatches) {
+                    matchesLength = functionMatches.length;
+                }
+            });
+
+            it('shouldn\'t add dead code conditions to the block empty block statements', () => {
+                assert.isAtLeast(matchesLength, expectedMatchesLength);
+            });
+        });
     });
 });

+ 22 - 0
test/functional-tests/node-transformers/dead-code-injection-transformers/fixtures/block-statement-empty-body.js

@@ -0,0 +1,22 @@
+(function(){
+    function foo () {
+        function inner1 () {}
+        inner1();
+    }
+    function bar () {
+        function inner2 () {}
+        inner2();
+    }
+    function baz () {
+        function inner3 () {}
+        inner3();
+    }
+    function bark () {
+        function inner4 () {}
+        inner4();
+    }
+    function hawk () {
+        function inner5 () {}
+        inner5();
+    }
+})();

+ 22 - 0
test/functional-tests/node-transformers/dead-code-injection-transformers/fixtures/block-statement-wtith-scope-hoisting.js

@@ -0,0 +1,22 @@
+(function(){
+    function foo () {
+        inner1();
+        function inner1 () {}
+    }
+    function bar () {
+        inner2();
+        function inner2 () {}
+    }
+    function baz () {
+        inner3();
+        function inner3 () {}
+    }
+    function bark () {
+        inner4();
+        function inner4 () {}
+    }
+    function hawk () {
+        inner5();
+        function inner5 () {}
+    }
+})();

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff