Forráskód Böngészése

inversify integration wip

sanex3339 8 éve
szülő
commit
d53d90c295
33 módosított fájl, 620 hozzáadás és 611 törlés
  1. 228 359
      dist/index.js
  2. 1 1
      src/Obfuscator.ts
  3. 9 1
      src/container/InversifyContainerFacade.ts
  4. 5 1
      src/container/ServiceIdentifiers.ts
  5. 40 0
      src/container/modules/node-transformers/NodeControlFlowTransformersModule.ts
  6. 52 0
      src/container/modules/node-transformers/NodeObfuscatorsModule.ts
  7. 28 25
      src/container/modules/node-transformers/NodeTransformersModule.ts
  8. 3 0
      src/enums/container/NodeControlFlowTransformersReplacers.ts
  9. 6 0
      src/enums/container/NodeObfuscatorsReplacers.ts
  10. 0 0
      src/enums/container/NodeTransformers.ts
  11. 4 0
      src/interfaces/container/IContainerServiceIdentifiers.d.ts
  12. 1 0
      src/interfaces/container/IInversifyContainerFacade.d.ts
  13. 8 1
      src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts
  14. 16 0
      src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts
  15. 6 2
      src/node-transformers/node-obfuscators/CatchClauseObfuscator.ts
  16. 5 1
      src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts
  17. 5 1
      src/node-transformers/node-obfuscators/FunctionObfuscator.ts
  18. 5 1
      src/node-transformers/node-obfuscators/LabeledStatementObfuscator.ts
  19. 15 6
      src/node-transformers/node-obfuscators/LiteralObfuscator.ts
  20. 13 3
      src/node-transformers/node-obfuscators/MemberExpressionObfuscator.ts
  21. 13 3
      src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts
  22. 6 2
      src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts
  23. 8 1
      src/node-transformers/node-obfuscators/replacers/AbstractReplacer.ts
  24. 19 0
      src/node-transformers/node-obfuscators/replacers/BooleanLiteralReplacer.ts
  25. 19 0
      src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts
  26. 19 0
      src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts
  27. 18 1
      src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts
  28. 1 1
      src/types/TNodeTransformersFactory.d.ts
  29. 54 0
      test/functional-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec.ts
  30. 12 7
      test/functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts
  31. 1 2
      test/index.spec.ts
  32. 0 104
      test/unit-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec.ts
  33. 0 88
      test/unit-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 228 - 359
dist/index.js


+ 1 - 1
src/Obfuscator.ts

@@ -15,7 +15,7 @@ import { INodeTransformer } from './interfaces/INodeTransformer';
 import { IStackTraceAnalyzer } from './interfaces/stack-trace-analyzer/IStackTraceAnalyzer';
 import { IStorage } from './interfaces/IStorage';
 
-import { NodeTransformers } from './enums/NodeTransformers';
+import { NodeTransformers } from './enums/container/NodeTransformers';
 import { NodeType } from './enums/NodeType';
 import { ObfuscationEvents } from './enums/ObfuscationEvents';
 import { VisitorDirection } from './enums/VisitorDirection';

+ 9 - 1
src/container/InversifyContainerFacade.ts

@@ -1,7 +1,9 @@
 import { Container, interfaces } from 'inversify';
 import { ServiceIdentifiers } from './ServiceIdentifiers';
 
-import { nodeTransformersModule } from './modules/NodeTransformersModule';
+import { nodeControlFlowTransformersModule } from './modules/node-transformers/NodeControlFlowTransformersModule';
+import { nodeObfuscatorsModule } from './modules/node-transformers/NodeObfuscatorsModule';
+import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
 
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 import { IInputOptions } from '../interfaces/IInputOptions';
@@ -65,6 +67,8 @@ export class InversifyContainerFacade {
 
         // modules
         this.container.load(nodeTransformersModule);
+        this.container.load(nodeControlFlowTransformersModule);
+        this.container.load(nodeObfuscatorsModule);
     }
 
     /**
@@ -74,4 +78,8 @@ export class InversifyContainerFacade {
     public get <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>): T {
         return this.container.get<T>(serviceIdentifier);
     }
+
+    public getTagged <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>, key: string, value: any): T {
+        return this.container.getTagged<T>(serviceIdentifier, key, value);
+    }
 }

+ 5 - 1
src/container/ServiceIdentifiers.ts

@@ -1,12 +1,16 @@
 import { IContainerServiceIdentifiers } from '../interfaces/container/IContainerServiceIdentifiers';
 
 let ServiceIdentifiers: IContainerServiceIdentifiers = {
-    'Factory<INodeTransformer[]>': Symbol('INodeTransformersFactory'),
+    'Factory<IControlFlowReplacer>': Symbol('Factory<IControlFlowReplacer>'),
+    'Factory<INodeTransformer[]>': Symbol('Factory<INodeTransformer[]>'),
+    'Factory<IReplacer>': Symbol('Factory<IReplacer>'),
+    IControlFlowReplacer: Symbol('IControlFlowReplacer'),
     IJavaScriptObfuscator: Symbol('IJavaScriptObfuscator'),
     INodeTransformer: Symbol('INodeTransformer'),
     IObfuscationEventEmitter: Symbol('IObfuscationEventEmitter'),
     IObfuscator: Symbol('IObfuscator'),
     IOptions: Symbol('IOptions'),
+    IReplacer: Symbol('IReplacer'),
     IStackTraceAnalyzer: Symbol('IStackTraceAnalyzer'),
     'IStorage<ICustomNode>': Symbol('IStorage<ICustomNode>')
 };

+ 40 - 0
src/container/modules/node-transformers/NodeControlFlowTransformersModule.ts

@@ -0,0 +1,40 @@
+import { ContainerModule, interfaces } from 'inversify';
+import { ServiceIdentifiers } from '../../ServiceIdentifiers';
+
+import { IControlFlowReplacer } from '../../../interfaces/IControlFlowReplacer';
+
+import { NodeControlFlowTransformersReplacers } from '../../../enums/container/NodeControlFlowTransformersReplacers';
+
+import { BinaryExpressionControlFlowReplacer } from '../../../node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer';
+
+export const nodeControlFlowTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
+    const nodeControlFlowTransformersReplacersTag: string = 'nodeControlFlowTransformersReplacers';
+
+    bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
+        .to(BinaryExpressionControlFlowReplacer)
+        .whenTargetTagged(
+            nodeControlFlowTransformersReplacersTag,
+            NodeControlFlowTransformersReplacers.BinaryExpressionControlFlowReplacer
+        );
+
+    bind<IControlFlowReplacer>(ServiceIdentifiers['Factory<IControlFlowReplacer>'])
+        .toFactory<IControlFlowReplacer>((context: interfaces.Context) => {
+            const cache: Map <NodeControlFlowTransformersReplacers, IControlFlowReplacer> = new Map <NodeControlFlowTransformersReplacers, IControlFlowReplacer> ();
+
+            return (replacer: NodeControlFlowTransformersReplacers) => {
+                if (cache.has(replacer)) {
+                    return <IControlFlowReplacer>cache.get(replacer);
+                }
+
+                const controlFlowReplacer: IControlFlowReplacer = context.container.getTagged<IControlFlowReplacer>(
+                    ServiceIdentifiers.IControlFlowReplacer,
+                    nodeControlFlowTransformersReplacersTag,
+                    replacer
+                );
+
+                cache.set(replacer, controlFlowReplacer);
+
+                return controlFlowReplacer;
+            };
+        });
+});

+ 52 - 0
src/container/modules/node-transformers/NodeObfuscatorsModule.ts

@@ -0,0 +1,52 @@
+import { ContainerModule, interfaces } from 'inversify';
+import { ServiceIdentifiers } from '../../ServiceIdentifiers';
+
+import { IReplacer } from '../../../interfaces/IReplacer';
+
+import { NodeObfuscatorsReplacers } from '../../../enums/container/NodeObfuscatorsReplacers';
+
+import { BooleanLiteralReplacer } from '../../../node-transformers/node-obfuscators/replacers/BooleanLiteralReplacer';
+import { IdentifierReplacer } from '../../../node-transformers/node-obfuscators/replacers/IdentifierReplacer';
+import { NumberLiteralReplacer } from '../../../node-transformers/node-obfuscators/replacers/NumberLiteralReplacer';
+import { StringLiteralReplacer } from '../../../node-transformers/node-obfuscators/replacers/StringLiteralReplacer';
+
+export const nodeObfuscatorsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
+    const nodeObfuscatorsReplacersTag: string = 'nodeObfuscatorsReplacers';
+
+    bind<IReplacer>(ServiceIdentifiers.IReplacer)
+        .to(BooleanLiteralReplacer)
+        .whenTargetTagged(nodeObfuscatorsReplacersTag, NodeObfuscatorsReplacers.BooleanReplacer);
+
+    bind<IReplacer>(ServiceIdentifiers.IReplacer)
+        .to(IdentifierReplacer)
+        .whenTargetTagged(nodeObfuscatorsReplacersTag, NodeObfuscatorsReplacers.IdentifierReplacer);
+
+    bind<IReplacer>(ServiceIdentifiers.IReplacer)
+        .to(NumberLiteralReplacer)
+        .whenTargetTagged(nodeObfuscatorsReplacersTag, NodeObfuscatorsReplacers.NumberLiteralReplacer);
+
+    bind<IReplacer>(ServiceIdentifiers.IReplacer)
+        .to(StringLiteralReplacer)
+        .whenTargetTagged(nodeObfuscatorsReplacersTag, NodeObfuscatorsReplacers.StringLiteralReplacer);
+
+    bind<IReplacer>(ServiceIdentifiers['Factory<IReplacer>'])
+        .toFactory<IReplacer>((context: interfaces.Context) => {
+            const cache: Map <NodeObfuscatorsReplacers, IReplacer> = new Map <NodeObfuscatorsReplacers, IReplacer> ();
+
+            return (replacer: NodeObfuscatorsReplacers) => {
+                if (cache.has(replacer)) {
+                    return <IReplacer>cache.get(replacer);
+                }
+
+                const obfuscationReplacer: IReplacer = context.container.getTagged<IReplacer>(
+                    ServiceIdentifiers.IReplacer,
+                    nodeObfuscatorsReplacersTag,
+                    replacer
+                );
+
+                cache.set(replacer, obfuscationReplacer);
+
+                return obfuscationReplacer;
+            };
+        });
+});

+ 28 - 25
src/container/modules/NodeTransformersModule.ts → src/container/modules/node-transformers/NodeTransformersModule.ts

@@ -1,65 +1,68 @@
 import { ContainerModule, interfaces } from 'inversify';
-import { ServiceIdentifiers } from '../ServiceIdentifiers';
+import { ServiceIdentifiers } from '../../ServiceIdentifiers';
 
-import { INodeTransformer } from '../../interfaces/INodeTransformer';
+import { INodeTransformer } from '../../../interfaces/INodeTransformer';
 
-import { NodeTransformers } from '../../enums/NodeTransformers';
+import { NodeTransformers } from '../../../enums/container/NodeTransformers';
 
-import { FunctionControlFlowTransformer } from '../../node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer';
+import { FunctionControlFlowTransformer } from '../../../node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer';
 
-import { CatchClauseObfuscator } from '../../node-transformers/node-obfuscators/CatchClauseObfuscator';
-import { FunctionDeclarationObfuscator } from '../../node-transformers/node-obfuscators/FunctionDeclarationObfuscator';
-import { FunctionObfuscator } from '../../node-transformers/node-obfuscators/FunctionObfuscator';
-import { LabeledStatementObfuscator } from '../../node-transformers/node-obfuscators/LabeledStatementObfuscator';
-import { LiteralObfuscator } from '../../node-transformers/node-obfuscators/LiteralObfuscator';
-import { MemberExpressionObfuscator } from '../../node-transformers/node-obfuscators/MemberExpressionObfuscator';
-import { MethodDefinitionObfuscator } from '../../node-transformers/node-obfuscators/MethodDefinitionObfuscator';
-import { ObjectExpressionObfuscator } from '../../node-transformers/node-obfuscators/ObjectExpressionObfuscator';
-import { VariableDeclarationObfuscator } from '../../node-transformers/node-obfuscators/VariableDeclarationObfuscator';
+import { CatchClauseObfuscator } from '../../../node-transformers/node-obfuscators/CatchClauseObfuscator';
+import { FunctionDeclarationObfuscator } from '../../../node-transformers/node-obfuscators/FunctionDeclarationObfuscator';
+import { FunctionObfuscator } from '../../../node-transformers/node-obfuscators/FunctionObfuscator';
+import { LabeledStatementObfuscator } from '../../../node-transformers/node-obfuscators/LabeledStatementObfuscator';
+import { LiteralObfuscator } from '../../../node-transformers/node-obfuscators/LiteralObfuscator';
+import { MemberExpressionObfuscator } from '../../../node-transformers/node-obfuscators/MemberExpressionObfuscator';
+import { MethodDefinitionObfuscator } from '../../../node-transformers/node-obfuscators/MethodDefinitionObfuscator';
+import { ObjectExpressionObfuscator } from '../../../node-transformers/node-obfuscators/ObjectExpressionObfuscator';
+import { VariableDeclarationObfuscator } from '../../../node-transformers/node-obfuscators/VariableDeclarationObfuscator';
 
 export const nodeTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
-    const tag: string = 'nodeTransformer';
+    const nodeTransformersTag: string = 'nodeTransformers';
 
+    // node control flow transformers
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(FunctionControlFlowTransformer)
-        .whenTargetTagged(tag, NodeTransformers.FunctionControlFlowTransformer);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.FunctionControlFlowTransformer);
 
+    // node obfuscators
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(CatchClauseObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.CatchClauseObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.CatchClauseObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(FunctionDeclarationObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.FunctionDeclarationObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.FunctionDeclarationObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(FunctionObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.FunctionObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.FunctionObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(LabeledStatementObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.LabeledStatementObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.LabeledStatementObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(LiteralObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.LiteralObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.LiteralObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(MemberExpressionObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.MemberExpressionObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.MemberExpressionObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(MethodDefinitionObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.MethodDefinitionObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.MethodDefinitionObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(ObjectExpressionObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.ObjectExpressionObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.ObjectExpressionObfuscator);
 
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(VariableDeclarationObfuscator)
-        .whenTargetTagged(tag, NodeTransformers.VariableDeclarationObfuscator);
+        .whenTargetTagged(nodeTransformersTag, NodeTransformers.VariableDeclarationObfuscator);
 
+    // node transformers factory
     bind<INodeTransformer[]>(ServiceIdentifiers['Factory<INodeTransformer[]>'])
         .toFactory<INodeTransformer[]>((context: interfaces.Context) => {
             const cache: Map <NodeTransformers, INodeTransformer> = new Map <NodeTransformers, INodeTransformer> ();
@@ -76,7 +79,7 @@ export const nodeTransformersModule: interfaces.ContainerModule = new ContainerM
                     } else {
                         nodeTransformer = context.container.getTagged<INodeTransformer>(
                             ServiceIdentifiers.INodeTransformer,
-                            tag,
+                            nodeTransformersTag,
                             transformer
                         );
                         cache.set(transformer, nodeTransformer);

+ 3 - 0
src/enums/container/NodeControlFlowTransformersReplacers.ts

@@ -0,0 +1,3 @@
+export enum NodeControlFlowTransformersReplacers {
+    BinaryExpressionControlFlowReplacer
+}

+ 6 - 0
src/enums/container/NodeObfuscatorsReplacers.ts

@@ -0,0 +1,6 @@
+export enum NodeObfuscatorsReplacers {
+    BooleanReplacer,
+    IdentifierReplacer,
+    NumberLiteralReplacer,
+    StringLiteralReplacer
+}

+ 0 - 0
src/enums/NodeTransformers.ts → src/enums/container/NodeTransformers.ts


+ 4 - 0
src/interfaces/container/IContainerServiceIdentifiers.d.ts

@@ -1,12 +1,16 @@
 import { interfaces } from 'inversify';
 
 export interface IContainerServiceIdentifiers {
+    'Factory<IControlFlowReplacer>': interfaces.ServiceIdentifier<any>;
     'Factory<INodeTransformer[]>': interfaces.ServiceIdentifier<any>;
+    'Factory<IReplacer>': interfaces.ServiceIdentifier<any>;
+    IControlFlowReplacer: interfaces.ServiceIdentifier<any>;
     IJavaScriptObfuscator: interfaces.ServiceIdentifier<any>;
     INodeTransformer: interfaces.ServiceIdentifier<any>;
     IObfuscationEventEmitter: interfaces.ServiceIdentifier<any>;
     IObfuscator: interfaces.ServiceIdentifier<any>;
     IOptions: interfaces.ServiceIdentifier<any>;
+    IReplacer: interfaces.ServiceIdentifier<any>;
     IStackTraceAnalyzer: interfaces.ServiceIdentifier<any>;
     'IStorage<ICustomNode>': interfaces.ServiceIdentifier<any>;
     [key: string]: interfaces.ServiceIdentifier<any>;

+ 1 - 0
src/interfaces/container/IInversifyContainerFacade.d.ts

@@ -2,4 +2,5 @@ import { interfaces } from 'inversify';
 
 export interface IInversifyContainerFacade {
     get <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>): T;
+    getTagged <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>, key: string, value: any): T;
 }

+ 8 - 1
src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts

@@ -1,3 +1,6 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
 import * as ESTree from 'estree';
 
 import { IControlFlowReplacer } from '../../../interfaces/IControlFlowReplacer';
@@ -7,6 +10,7 @@ import { IStorage } from '../../../interfaces/IStorage';
 
 import { Utils } from '../../../Utils';
 
+@injectable()
 export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer {
     /**
      * @type IStorage<ICustomNode>
@@ -22,7 +26,10 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
      * @param customNodesStorage
      * @param options
      */
-    constructor (customNodesStorage: IStorage<ICustomNode>, options: IOptions) {
+    constructor (
+        @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
         this.customNodesStorage = customNodesStorage;
         this.options = options;
     }

+ 16 - 0
src/node-transformers/node-control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer.ts

@@ -1,14 +1,30 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
 import * as escodegen from 'escodegen';
 import * as ESTree from 'estree';
 
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IOptions } from '../../../interfaces/IOptions';
 import { IStorage } from '../../../interfaces/IStorage';
 
 import { AbstractControlFlowReplacer } from './AbstractControlFlowReplacer';
 import { BinaryExpressionFunctionNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode';
 import { ControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/ControlFlowStorageCallNode';
 
+@injectable()
 export class BinaryExpressionControlFlowReplacer extends AbstractControlFlowReplacer {
+    /**
+     * @param customNodesStorage
+     * @param options
+     */
+    constructor (
+        @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(customNodesStorage, options);
+    }
+
     /**
      * @param expressionNode
      * @returns {string}

+ 6 - 2
src/node-transformers/node-obfuscators/CatchClauseObfuscator.ts

@@ -6,8 +6,10 @@ import * as ESTree from 'estree';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
 import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
@@ -28,19 +30,21 @@ export class CatchClauseObfuscator extends AbstractNodeTransformer {
     /**
      * @type {IdentifierReplacer}
      */
-    private readonly identifierReplacer: IdentifierReplacer;
+    private readonly identifierReplacer: IReplacer & IdentifierReplacer;
 
     /**
      * @param customNodesStorage
+     * @param replacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
 
-        this.identifierReplacer = new IdentifierReplacer(this.customNodesStorage, this.options);
+        this.identifierReplacer = <IdentifierReplacer>replacersFactory(NodeObfuscatorsReplacers.IdentifierReplacer);
     }
 
     /**

+ 5 - 1
src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts

@@ -8,8 +8,10 @@ import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
 import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
@@ -35,15 +37,17 @@ export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
 
     /**
      * @param customNodesStorage
+     * @param nodeObfuscatorsReplacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
 
-        this.identifierReplacer = new IdentifierReplacer(this.customNodesStorage, this.options);
+        this.identifierReplacer = <IdentifierReplacer>nodeObfuscatorsReplacersFactory(NodeObfuscatorsReplacers.IdentifierReplacer);
     }
 
     /**

+ 5 - 1
src/node-transformers/node-obfuscators/FunctionObfuscator.ts

@@ -6,8 +6,10 @@ import * as ESTree from 'estree';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
 import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
@@ -32,15 +34,17 @@ export class FunctionObfuscator extends AbstractNodeTransformer {
 
     /**
      * @param customNodesStorage
+     * @param nodeObfuscatorsReplacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
 
-        this.identifierReplacer = new IdentifierReplacer(this.customNodesStorage, this.options);
+        this.identifierReplacer = <IdentifierReplacer>nodeObfuscatorsReplacersFactory(NodeObfuscatorsReplacers.IdentifierReplacer);
     }
 
     /**

+ 5 - 1
src/node-transformers/node-obfuscators/LabeledStatementObfuscator.ts

@@ -6,8 +6,10 @@ import * as ESTree from 'estree';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
 import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
@@ -40,15 +42,17 @@ export class LabeledStatementObfuscator extends AbstractNodeTransformer {
 
     /**
      * @param customNodesStorage
+     * @param nodeObfuscatorsReplacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) nodeObfuscatorsReplacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
 
-        this.identifierReplacer = new IdentifierReplacer(this.customNodesStorage, this.options);
+        this.identifierReplacer = <IdentifierReplacer>nodeObfuscatorsReplacersFactory(NodeObfuscatorsReplacers.IdentifierReplacer);
     }
 
     /**

+ 15 - 6
src/node-transformers/node-obfuscators/LiteralObfuscator.ts

@@ -6,25 +6,34 @@ import * as ESTree from 'estree';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
+
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
-import { BooleanLiteralReplacer } from './replacers/BooleanLiteralReplacer';
 import { Node } from '../../node/Node';
-import { NumberLiteralReplacer } from './replacers/NumberLiteralReplacer';
-import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
 
 @injectable()
 export class LiteralObfuscator extends AbstractNodeTransformer {
+    /**
+     * @type {(replacer: NodeObfuscatorsReplacers) => IReplacer}
+     */
+    private readonly replacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer;
+
     /**
      * @param customNodesStorage
+     * @param replacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
+
+        this.replacersFactory = replacersFactory;
     }
 
     /**
@@ -40,19 +49,19 @@ export class LiteralObfuscator extends AbstractNodeTransformer {
 
         switch (typeof literalNode.value) {
             case 'boolean':
-                content = new BooleanLiteralReplacer(this.customNodesStorage, this.options)
+                content = this.replacersFactory(NodeObfuscatorsReplacers.BooleanReplacer)
                     .replace(<boolean>literalNode.value);
 
                 break;
 
             case 'number':
-                content = new NumberLiteralReplacer(this.customNodesStorage, this.options)
+                content = this.replacersFactory(NodeObfuscatorsReplacers.NumberLiteralReplacer)
                     .replace(<number>literalNode.value);
 
                 break;
 
             case 'string':
-                content = new StringLiteralReplacer(this.customNodesStorage, this.options)
+                content = this.replacersFactory(NodeObfuscatorsReplacers.StringLiteralReplacer)
                     .replace(<string>literalNode.value);
 
                 break;

+ 13 - 3
src/node-transformers/node-obfuscators/MemberExpressionObfuscator.ts

@@ -7,25 +7,35 @@ import * as ESTree from 'estree';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
 import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { Node } from '../../node/Node';
-import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
 
 @injectable()
 export class MemberExpressionObfuscator extends AbstractNodeTransformer {
+    /**
+     * @type {IReplacer}
+     */
+    private readonly stringLiteralReplacer: IReplacer;
+
     /**
      * @param customNodesStorage
+     * @param replacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
+
+        this.stringLiteralReplacer = replacersFactory(NodeObfuscatorsReplacers.StringLiteralReplacer);
     }
 
     /**
@@ -69,7 +79,7 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
         const literalNode: ESTree.Literal = {
             raw: `'${nodeValue}'`,
             'x-verbatim-property': {
-                content : new StringLiteralReplacer(this.customNodesStorage, this.options).replace(nodeValue),
+                content: this.stringLiteralReplacer.replace(nodeValue),
                 precedence: escodegen.Precedence.Primary
             },
             type: NodeType.Literal,
@@ -93,7 +103,7 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
     private obfuscateLiteralProperty (node: ESTree.Literal): void {
         if (typeof node.value === 'string' && !node['x-verbatim-property']) {
             node['x-verbatim-property'] = {
-                content : new StringLiteralReplacer(this.customNodesStorage, this.options).replace(node.value),
+                content : this.stringLiteralReplacer.replace(node.value),
                 precedence: escodegen.Precedence.Primary
             };
         }

+ 13 - 3
src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts

@@ -6,12 +6,14 @@ import * as ESTree from 'estree';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
+
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { Node } from '../../node/Node';
 import { Utils } from '../../Utils';
-import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
 
 /**
  * replaces:
@@ -22,6 +24,11 @@ import { StringLiteralReplacer } from './replacers/StringLiteralReplacer';
  */
 @injectable()
 export class MethodDefinitionObfuscator extends AbstractNodeTransformer {
+    /**
+     * @type {IReplacer}
+     */
+    private readonly stringLiteralReplacer: IReplacer;
+
     /**
      * @type {string[]}
      */
@@ -29,13 +36,17 @@ export class MethodDefinitionObfuscator extends AbstractNodeTransformer {
 
     /**
      * @param customNodesStorage
+     * @param replacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
+
+        this.stringLiteralReplacer = replacersFactory(NodeObfuscatorsReplacers.StringLiteralReplacer);
     }
 
     /**
@@ -58,8 +69,7 @@ export class MethodDefinitionObfuscator extends AbstractNodeTransformer {
                     methodDefinitionNode.computed === false
                 ) {
                     methodDefinitionNode.computed = true;
-                    node.name = new StringLiteralReplacer(this.customNodesStorage, this.options)
-                        .replace(node.name);
+                    node.name = this.stringLiteralReplacer.replace(node.name);
 
                     return;
                 }

+ 6 - 2
src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts

@@ -8,8 +8,10 @@ import { TNodeWithBlockStatement } from '../../types/TNodeWithBlockStatement';
 
 import { ICustomNode } from '../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../interfaces/IOptions';
+import { IReplacer } from '../../interfaces/IReplacer';
 import { IStorage } from '../../interfaces/IStorage';
 
+import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsReplacers';
 import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
@@ -32,19 +34,21 @@ export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
     /**
      * @type {IdentifierReplacer}
      */
-    private readonly identifierReplacer: IdentifierReplacer;
+    private readonly identifierReplacer: IReplacer & IdentifierReplacer;
 
     /**
      * @param customNodesStorage
+     * @param replacersFactory
      * @param options
      */
     constructor(
         @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers['Factory<IReplacer>']) replacersFactory: (replacer: NodeObfuscatorsReplacers) => IReplacer,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         super(customNodesStorage, options);
 
-        this.identifierReplacer = new IdentifierReplacer(this.customNodesStorage, this.options);
+        this.identifierReplacer = <IdentifierReplacer>replacersFactory(NodeObfuscatorsReplacers.IdentifierReplacer);
     }
 
     /**

+ 8 - 1
src/node-transformers/node-obfuscators/replacers/AbstractReplacer.ts

@@ -1,8 +1,12 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../../interfaces/IOptions';
 import { IReplacer } from '../../../interfaces/IReplacer';
 import { IStorage } from '../../../interfaces/IStorage';
 
+@injectable()
 export abstract class AbstractReplacer implements IReplacer {
     /**
      * @type IStorage<ICustomNode>
@@ -18,7 +22,10 @@ export abstract class AbstractReplacer implements IReplacer {
      * @param customNodesStorage
      * @param options
      */
-    constructor (customNodesStorage: IStorage<ICustomNode>, options: IOptions) {
+    constructor (
+        @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
         this.customNodesStorage = customNodesStorage;
         this.options = options;
     }

+ 19 - 0
src/node-transformers/node-obfuscators/replacers/BooleanLiteralReplacer.ts

@@ -1,8 +1,27 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
+import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IOptions } from '../../../interfaces/IOptions';
+import { IStorage } from '../../../interfaces/IStorage';
+
 import { JSFuck } from '../../../enums/JSFuck';
 
 import { AbstractReplacer } from './AbstractReplacer';
 
+@injectable()
 export class BooleanLiteralReplacer extends AbstractReplacer {
+    /**
+     * @param customNodesStorage
+     * @param options
+     */
+    constructor (
+        @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(customNodesStorage, options);
+    }
+
     /**
      * @param nodeValue
      * @returns {string}

+ 19 - 0
src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts

@@ -1,12 +1,31 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
+import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IOptions } from '../../../interfaces/IOptions';
+import { IStorage } from '../../../interfaces/IStorage';
+
 import { AbstractReplacer } from './AbstractReplacer';
 import { Utils } from '../../../Utils';
 
+@injectable()
 export class IdentifierReplacer extends AbstractReplacer {
     /**
      * @type {Map<string, string>}
      */
     private readonly namesMap: Map<string, string> = new Map<string, string>();
 
+    /**
+     * @param customNodesStorage
+     * @param options
+     */
+    constructor (
+        @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(customNodesStorage, options);
+    }
+
     /**
      * @param nodeValue
      * @returns {string}

+ 19 - 0
src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts

@@ -1,7 +1,26 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
+import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
+import { IOptions } from '../../../interfaces/IOptions';
+import { IStorage } from '../../../interfaces/IStorage';
+
 import { AbstractReplacer } from './AbstractReplacer';
 import { Utils } from '../../../Utils';
 
+@injectable()
 export class NumberLiteralReplacer extends AbstractReplacer {
+    /**
+     * @param customNodesStorage
+     * @param options
+     */
+    constructor (
+        @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(customNodesStorage, options);
+    }
+
     /**
      * @param nodeValue
      * @returns {string}

+ 18 - 1
src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts

@@ -1,4 +1,10 @@
+import { injectable, inject } from 'inversify';
+import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
+
+import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
 import { ICustomNodeWithData } from '../../../interfaces/custom-nodes/ICustomNodeWithData';
+import { ICustomNodeWithIdentifier } from '../../../interfaces/custom-nodes/ICustomNodeWithIdentifier';
+import { IOptions } from '../../../interfaces/IOptions';
 import { IStorage } from '../../../interfaces/IStorage';
 
 import { StringArrayEncoding } from '../../../enums/StringArrayEncoding';
@@ -6,8 +12,8 @@ import { StringArrayEncoding } from '../../../enums/StringArrayEncoding';
 import { AbstractReplacer } from './AbstractReplacer';
 import { NumberLiteralReplacer } from './NumberLiteralReplacer';
 import { Utils } from '../../../Utils';
-import { ICustomNodeWithIdentifier } from '../../../interfaces/custom-nodes/ICustomNodeWithIdentifier';
 
+@injectable()
 export class StringLiteralReplacer extends AbstractReplacer {
     /**
      * @type {number}
@@ -20,6 +26,17 @@ export class StringLiteralReplacer extends AbstractReplacer {
     private static readonly rc4Keys: string[] = Utils.getRandomGenerator()
         .n(() => Utils.getRandomGenerator().string({length: 4}), 50);
 
+    /**
+     * @param customNodesStorage
+     * @param options
+     */
+    constructor (
+        @inject(ServiceIdentifiers['IStorage<ICustomNode>']) customNodesStorage: IStorage<ICustomNode>,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(customNodesStorage, options);
+    }
+
     /**
      * @param nodeValue
      * @returns {string}

+ 1 - 1
src/types/TNodeTransformersFactory.d.ts

@@ -1,5 +1,5 @@
 import { INodeTransformer } from '../interfaces/INodeTransformer';
 
-import { NodeTransformers } from '../enums/NodeTransformers';
+import { NodeTransformers } from '../enums/container/NodeTransformers';
 
 export type TNodeTransformersFactory = (nodeTransformersMap: Map<string, NodeTransformers[]>) => (nodeType: string) => INodeTransformer[];

+ 54 - 0
test/functional-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec.ts

@@ -0,0 +1,54 @@
+import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
+
+import { NO_CUSTOM_NODES_PRESET } from '../../../../src/preset-options/NoCustomNodesPreset';
+
+import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
+
+const assert: Chai.AssertStatic = require('chai').assert;
+
+describe('FunctionDeclarationObfuscator', () => {
+    describe('obfuscation of `functionDeclaration` node names', () => {
+        const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+            `
+                function foo () {
+                    function bar () {
+                    }
+                    
+                    if (true) {
+                        bar();
+                    }
+                }
+                
+                if (true) {
+                    foo();
+                }
+            `,
+            Object.assign({}, NO_CUSTOM_NODES_PRESET)
+        );
+        const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
+
+        it('shouldn\'t obfuscate function name if `functionDeclaration` parent block scope is a `ProgramNode`', () => {
+            const functionNameIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/function *foo *\(\) *\{/);
+            const functionCallIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/foo *\( *\);/);
+
+            const functionParamIdentifierName: string = (<RegExpMatchArray>functionNameIdentifierMatch)[1];
+            const functionBodyIdentifierName: string = (<RegExpMatchArray>functionCallIdentifierMatch)[1];
+
+            assert.equal(functionParamIdentifierName, functionBodyIdentifierName);
+        });
+
+        it('should obfuscate function name if `functionDeclaration` parent block scope is not a `ProgramNode`', () => {
+            const functionNameIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/function *_0x[a-z0-9]{4,6} *\(\) *\{/);
+            const functionCallIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
+                .match(/_0x[a-z0-9]{4,6} *\( *\);/);
+
+            const functionParamIdentifierName: string = (<RegExpMatchArray>functionNameIdentifierMatch)[1];
+            const functionBodyIdentifierName: string = (<RegExpMatchArray>functionCallIdentifierMatch)[1];
+
+            assert.equal(functionParamIdentifierName, functionBodyIdentifierName);
+        });
+    });
+});

+ 12 - 7
test/functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts

@@ -8,9 +8,8 @@ const assert: Chai.AssertStatic = require('chai').assert;
 
 describe('FunctionObfuscator', () => {
     describe('identifiers obfuscation inside `FunctionDeclaration` and `FunctionExpression` node body', () => {
-        it('should correct obfuscate both function parameter identifier and function body identifier with same name', () => {
-            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
-                `
+        const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+            `
                     (function () {
                         var test = function (test) {
                             console.log(test);
@@ -19,15 +18,17 @@ describe('FunctionObfuscator', () => {
                                 var test = 5
                             }
                             
+                            variable = 6;
+                            
                             return test;
                         }
                     })();
                 `,
-                Object.assign({}, NO_CUSTOM_NODES_PRESET)
-            );
-
-            const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
+            Object.assign({}, NO_CUSTOM_NODES_PRESET)
+        );
+        const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
 
+        it('should correct obfuscate both function parameter identifier and function body identifier with same name', () => {
             const functionParamIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
                 .match(/var _0x[a-z0-9]{4,6} *= *function *\((_0x[a-z0-9]{4,6})\) *\{/);
             const functionBodyIdentifierMatch: RegExpMatchArray|null = obfuscatedCode
@@ -38,5 +39,9 @@ describe('FunctionObfuscator', () => {
 
             assert.equal(functionParamIdentifierName, functionBodyIdentifierName);
         });
+
+        it('shouldn\'t obfuscate other variables in function body', () => {
+            assert.equal(/variable *= *0x6;/.test(obfuscatedCode), true);
+        });
     });
 });

+ 1 - 2
test/index.spec.ts

@@ -14,8 +14,6 @@ import './unit-tests/OptionsNormalizer.spec';
 import './unit-tests/SourceMapCorrector.spec';
 import './unit-tests/Utils.spec';
 import './unit-tests/cli/CLIUtils.spec';
-import './unit-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec';
-import './unit-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec';
 import './unit-tests/stack-trace-analyzer/StackTraceAnalyzer.spec';
 
 /**
@@ -30,6 +28,7 @@ import './functional-tests/custom-nodes/string-array-nodes/StringArrayCallsWrapp
 import './functional-tests/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.spec';
 import './functional-tests/custom-nodes/string-array-nodes/StringArrayNode.spec';
 import './functional-tests/node-transformers/node-obfuscators/CatchClauseObfuscator.spec';
+import './functional-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec';
 import './functional-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec';
 import './functional-tests/node-transformers/node-obfuscators/LabeledStatementObfuscator.spec';
 import './functional-tests/node-transformers/node-obfuscators/LiteralObfuscator.spec';

+ 0 - 104
test/unit-tests/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.spec.ts

@@ -1,104 +0,0 @@
-import * as ESTree from 'estree';
-
-import { IOptions } from '../../../../src/interfaces/IOptions';
-
-import { DEFAULT_PRESET } from '../../../../src/preset-options/DefaultPreset';
-
-import { CustomNodesStorage } from '../../../../src/storages/custom-nodes/CustomNodesStorage';
-import { FunctionDeclarationObfuscator } from '../../../../src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator';
-import { NodeMocks } from '../../../mocks/NodeMocks';
-import { Options } from '../../../../src/options/Options';
-
-const assert: Chai.AssertStatic = require('chai').assert;
-
-describe('FunctionDeclarationObfuscator', () => {
-    describe('changeControlFlow (functionDeclarationNode: IFunctionDeclarationNode, parentNode: INode): void', () => {
-        let expressionStatementNode: ESTree.ExpressionStatement,
-            functionDeclarationObfuscator: FunctionDeclarationObfuscator,
-            functionDeclarationNode: ESTree.FunctionDeclaration,
-            functionName: string = 'functionDeclaration',
-            programNode: ESTree.Program;
-
-        beforeEach(() => {
-            expressionStatementNode = NodeMocks.getExpressionStatementNode(
-                NodeMocks.getCallExpressionNode(NodeMocks.getIdentifierNode(functionName))
-            );
-
-            const options: IOptions = new Options(DEFAULT_PRESET);
-
-            functionDeclarationObfuscator = new FunctionDeclarationObfuscator(
-                new CustomNodesStorage(options),
-                options
-            );
-
-            functionDeclarationNode = NodeMocks.getFunctionDeclarationNode(
-                functionName,
-                NodeMocks.getBlockStatementNode()
-            );
-        });
-
-        describe('if `functionDeclaration` node parent block scope is not a Program node', () => {
-            let blockStatementNode: ESTree.BlockStatement,
-                functionDeclarationParentNode: ESTree.FunctionDeclaration;
-
-            beforeEach(() => {
-                blockStatementNode = NodeMocks.getBlockStatementNode([
-                    functionDeclarationNode,
-                    expressionStatementNode
-                ]);
-
-                functionDeclarationParentNode = NodeMocks.getFunctionDeclarationNode(
-                    'functionDeclarationParentNode',
-                    blockStatementNode
-                );
-
-                programNode = NodeMocks.getProgramNode([
-                    functionDeclarationParentNode
-                ]);
-
-                programNode['parentNode'] = programNode;
-                functionDeclarationParentNode['parentNode'] = programNode;
-                blockStatementNode['parentNode'] = functionDeclarationParentNode;
-                functionDeclarationNode['parentNode'] = blockStatementNode;
-                expressionStatementNode['parentNode'] = blockStatementNode;
-
-                functionDeclarationObfuscator.transformNode(
-                    functionDeclarationNode,
-                    blockStatementNode
-                );
-            });
-
-            it('should obfuscate function name', () => {
-                assert.match(functionDeclarationNode.id.name, /^_0x\w+$/);
-            });
-
-            it('should obfuscate function name inside `functionDeclaration` parent scope', () => {
-                assert.match((<any>expressionStatementNode).expression.callee.name, /^_0x\w+$/);
-            });
-        });
-
-        describe('if `functionDeclaration` node parent block scope node is a Program node', () => {
-            beforeEach(() => {
-                programNode = NodeMocks.getProgramNode([
-                    functionDeclarationNode
-                ]);
-
-                functionDeclarationNode['parentNode'] = programNode;
-                expressionStatementNode['parentNode'] = programNode;
-
-                functionDeclarationObfuscator.transformNode(
-                    functionDeclarationNode,
-                    programNode
-                );
-            });
-
-            it('shouldn\'t obfuscate function name inside `programNode` scope', () => {
-                assert.equal(functionDeclarationNode.id.name, functionName);
-            });
-
-            it('should\'t obfuscate function name in `functionDeclaration` calls inside `programNode`', () => {
-                assert.equal((<any>expressionStatementNode).expression.callee.name, functionName);
-            });
-        });
-    });
-});

+ 0 - 88
test/unit-tests/node-transformers/node-obfuscators/FunctionObfuscator.spec.ts

@@ -1,88 +0,0 @@
-import * as ESTree from 'estree';
-
-import { IOptions } from '../../../../src/interfaces/IOptions';
-
-import { DEFAULT_PRESET } from '../../../../src/preset-options/DefaultPreset';
-
-import { CustomNodesStorage } from '../../../../src/storages/custom-nodes/CustomNodesStorage';
-import { FunctionObfuscator } from '../../../../src/node-transformers/node-obfuscators/FunctionObfuscator';
-import { NodeMocks } from '../../../mocks/NodeMocks';
-import { Options } from '../../../../src/options/Options';
-
-
-const assert: Chai.AssertStatic = require('chai').assert;
-
-describe('FunctionObfuscator', () => {
-    describe('changeControlFlow (functionNode: IFunctionNode): void', () => {
-        let blockStatementNode: ESTree.BlockStatement,
-            expressionStatementNode1: ESTree.ExpressionStatement,
-            expressionStatementNode2: ESTree.ExpressionStatement,
-            functionObfuscator: FunctionObfuscator,
-            functionDeclarationNode: ESTree.FunctionDeclaration,
-            functionName: string = 'functionDeclaration',
-            identifierName: string = 'identifierName',
-            identifierNode1: ESTree.Identifier,
-            identifierNode2: ESTree.Identifier,
-            identifierNode3: ESTree.Identifier,
-            paramName: string = 'param1',
-            programNode: ESTree.Program;
-
-        before(() => {
-            identifierNode1 = NodeMocks.getIdentifierNode(paramName);
-            identifierNode2 = NodeMocks.getIdentifierNode(paramName);
-            identifierNode3 = NodeMocks.getIdentifierNode(identifierName);
-
-            expressionStatementNode1 = NodeMocks.getExpressionStatementNode(
-                NodeMocks.getCallExpressionNode(identifierNode2)
-            );
-
-            expressionStatementNode2 = NodeMocks.getExpressionStatementNode(
-                NodeMocks.getCallExpressionNode(identifierNode3)
-            );
-
-            blockStatementNode = NodeMocks.getBlockStatementNode([
-                expressionStatementNode1
-            ]);
-
-            functionDeclarationNode = NodeMocks.getFunctionDeclarationNode(
-                functionName,
-                blockStatementNode,
-                [
-                    identifierNode1
-                ]
-            );
-
-            programNode = NodeMocks.getProgramNode([
-                functionDeclarationNode
-            ]);
-
-            programNode['parentNode'] = programNode;
-            functionDeclarationNode['parentNode'] = programNode;
-            blockStatementNode['parentNode'] = functionDeclarationNode;
-            identifierNode1['parentNode'] = functionDeclarationNode;
-            expressionStatementNode1['parentNode'] = blockStatementNode;
-
-            const options: IOptions = new Options(DEFAULT_PRESET);
-
-            functionObfuscator = new FunctionObfuscator(
-                new CustomNodesStorage(options),
-                options
-            );
-
-            functionObfuscator.transformNode(functionDeclarationNode);
-        });
-
-        it('should obfuscate function parameter', () => {
-            assert.match(identifierNode1.name, /^_0x\w+$/);
-        });
-
-        it('should obfuscate function parameter in function body', () => {
-            assert.match(identifierNode2.name, /^_0x\w+$/);
-            assert.equal(identifierNode2.name, identifierNode1.name);
-        });
-
-        it('shouldn\'t obfuscate other identifiers in function body', () => {
-            assert.equal(identifierNode3.name, identifierName);
-        });
-    });
-});

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott