瀏覽代碼

Fixed dead code injection runtime error caused by identifiers conflict

sanex3339 7 年之前
父節點
當前提交
87a4638159

文件差異過大導致無法顯示
+ 0 - 0
dist/index.js


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

@@ -10,9 +10,11 @@ import { TNodeWithBlockScope } from '../../types/node/TNodeWithBlockScope';
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+import { ITransformersRunner } from '../../interfaces/node-transformers/ITransformersRunner';
 import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
 
 import { DeadCodeInjectionCustomNode } from '../../enums/custom-nodes/DeadCodeInjectionCustomNode';
+import { NodeTransformer } from '../../enums/node-transformers/NodeTransformer';
 import { NodeType } from '../../enums/node/NodeType';
 import { TransformationStage } from '../../enums/node-transformers/TransformationStage';
 
@@ -38,6 +40,18 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
      */
     private static readonly minCollectedBlockStatementsCount: number = 5;
 
+    /**
+     * @type {NodeTransformer[]}
+     */
+    private static readonly transformersToRenameBlockScopeIdentifiers: NodeTransformer[] = [
+        NodeTransformer.CatchClauseTransformer,
+        NodeTransformer.ClassDeclarationTransformer,
+        NodeTransformer.FunctionDeclarationTransformer,
+        NodeTransformer.FunctionTransformer,
+        NodeTransformer.LabeledStatementTransformer,
+        NodeTransformer.VariableDeclarationTransformer
+    ];
+
     /**
      * @type {Set <BlockStatement>}
      */
@@ -58,20 +72,28 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
      */
     private readonly deadCodeInjectionCustomNodeFactory: TDeadNodeInjectionCustomNodeFactory;
 
+    /**
+     * @type {ITransformersRunner}
+     */
+    private readonly transformersRunner: ITransformersRunner;
+
     /**
      * @param {TControlFlowCustomNodeFactory} deadCodeInjectionCustomNodeFactory
+     * @param {ITransformersRunner} transformersRunner
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
         @inject(ServiceIdentifiers.Factory__IDeadCodeInjectionCustomNode)
             deadCodeInjectionCustomNodeFactory: TDeadNodeInjectionCustomNodeFactory,
+        @inject(ServiceIdentifiers.ITransformersRunner) transformersRunner: ITransformersRunner,
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(randomGenerator, options);
 
         this.deadCodeInjectionCustomNodeFactory = deadCodeInjectionCustomNodeFactory;
+        this.transformersRunner = transformersRunner;
     }
 
     /**
@@ -159,12 +181,22 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
                     return;
                 }
 
-                const clonedBlockStatementNode: ESTree.BlockStatement = NodeUtils.clone(node);
+                let clonedBlockStatementNode: ESTree.BlockStatement = NodeUtils.clone(node);
 
                 if (!DeadCodeInjectionTransformer.isValidBlockStatementNode(clonedBlockStatementNode)) {
                     return;
                 }
 
+                /**
+                 * We should transform identifiers in the dead code block statement to avoid conflicts with original code
+                 */
+                NodeUtils.parentizeNode(clonedBlockStatementNode, clonedBlockStatementNode);
+                clonedBlockStatementNode = this.transformersRunner.transform(
+                    clonedBlockStatementNode,
+                    DeadCodeInjectionTransformer.transformersToRenameBlockScopeIdentifiers,
+                    TransformationStage.Obfuscating
+                );
+
                 this.collectedBlockStatements.push(clonedBlockStatementNode);
             }
         });

+ 10 - 0
src/node/NodeUtils.ts

@@ -180,6 +180,16 @@ export class NodeUtils {
             throw new ReferenceError('`parentNode` property of given node is `undefined`');
         }
 
+        /**
+         * Stage 1: process root block statement node of the slice of AST-tree
+         */
+        if (NodeGuards.isBlockStatementNode(node) && parentNode === node) {
+            blockScopes.push(node);
+        }
+
+        /**
+         * Stage 2: process any other nodes
+         */
         if (
             /**
              * we can add program node instantly

部分文件因文件數量過多而無法顯示