瀏覽代碼

DictionaryIdentifierNamesGenerator refactoring

sanex3339 5 年之前
父節點
當前提交
36918c351c

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


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


+ 1 - 1
src/cli/JavaScriptObfuscatorCLI.ts

@@ -261,7 +261,7 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
             )
             .option(
                 '--identifiers-dictionary <list> (comma separated, without whitespaces)',
-                'Identifiers dictionary (comma separated)',
+                'Identifiers dictionary (comma separated) for `--identifier-names-generator dictionary` option',
                 ArraySanitizer
             )
             .option(

+ 11 - 11
src/container/modules/generators/GeneratorsModule.ts

@@ -6,12 +6,17 @@ import { IOptions } from '../../../interfaces/options/IOptions';
 
 import { IdentifierNamesGenerator } from '../../../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
 
+import { DictionaryIdentifierNamesGenerator } from '../../../generators/identifier-names-generators/DictionaryIdentifierNamesGenerator';
 import { HexadecimalIdentifierNamesGenerator } from '../../../generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator';
 import { MangledIdentifierNamesGenerator } from '../../../generators/identifier-names-generators/MangledIdentifierNamesGenerator';
-import { DictionaryNamesGenerator } from '../../../generators/identifier-names-generators/DictionaryNamesGenerator';
 
 export const generatorsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
     // identifier name generators
+    bind<IIdentifierNamesGenerator>(ServiceIdentifiers.IIdentifierNamesGenerator)
+        .to(DictionaryIdentifierNamesGenerator)
+        .inSingletonScope()
+        .whenTargetNamed(IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator);
+
     bind<IIdentifierNamesGenerator>(ServiceIdentifiers.IIdentifierNamesGenerator)
         .to(HexadecimalIdentifierNamesGenerator)
         .inSingletonScope()
@@ -22,11 +27,6 @@ export const generatorsModule: interfaces.ContainerModule = new ContainerModule(
         .inSingletonScope()
         .whenTargetNamed(IdentifierNamesGenerator.MangledIdentifierNamesGenerator);
 
-    bind<IIdentifierNamesGenerator>(ServiceIdentifiers.IIdentifierNamesGenerator)
-        .to(DictionaryNamesGenerator)
-        .inSingletonScope()
-        .whenTargetNamed(IdentifierNamesGenerator.DictionaryNamesGenerator);
-
     // identifier name generator factory
     bind<IIdentifierNamesGenerator>(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
         .toFactory<IIdentifierNamesGenerator>((context: interfaces.Context): (options: IOptions) => IIdentifierNamesGenerator => {
@@ -40,18 +40,18 @@ export const generatorsModule: interfaces.ContainerModule = new ContainerModule(
                 let identifierNamesGenerator: IIdentifierNamesGenerator;
 
                 switch (options.identifierNamesGenerator) {
-                    case IdentifierNamesGenerator.MangledIdentifierNamesGenerator:
+                    case IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator:
                         identifierNamesGenerator = context.container.getNamed<IIdentifierNamesGenerator>(
                             ServiceIdentifiers.IIdentifierNamesGenerator,
-                            IdentifierNamesGenerator.MangledIdentifierNamesGenerator
+                            IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
                         );
 
                         break;
-                    
-                    case IdentifierNamesGenerator.DictionaryNamesGenerator:
+
+                    case IdentifierNamesGenerator.MangledIdentifierNamesGenerator:
                         identifierNamesGenerator = context.container.getNamed<IIdentifierNamesGenerator>(
                             ServiceIdentifiers.IIdentifierNamesGenerator,
-                            IdentifierNamesGenerator.DictionaryNamesGenerator
+                            IdentifierNamesGenerator.MangledIdentifierNamesGenerator
                         );
 
                         break;

+ 2 - 2
src/enums/generators/identifier-names-generators/IdentifierNamesGenerator.ts

@@ -1,5 +1,5 @@
 export enum IdentifierNamesGenerator {
+    DictionaryIdentifierNamesGenerator = 'dictionary',
     HexadecimalIdentifierNamesGenerator = 'hexadecimal',
-    MangledIdentifierNamesGenerator = 'mangled',
-    DictionaryNamesGenerator = 'dictionary'
+    MangledIdentifierNamesGenerator = 'mangled'
 }

+ 128 - 0
src/generators/identifier-names-generators/DictionaryIdentifierNamesGenerator.ts

@@ -0,0 +1,128 @@
+import { inject, injectable } from 'inversify';
+import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
+
+import { IArrayUtils } from '../../interfaces/utils/IArrayUtils';
+import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+
+import { AbstractIdentifierNamesGenerator } from './AbstractIdentifierNamesGenerator';
+
+@injectable()
+export class DictionaryIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator {
+    /**
+     * @type {IArrayUtils}
+     */
+    private readonly arrayUtils: IArrayUtils;
+
+    /**
+     * @type {string[]}
+     */
+    private identifierNames: string[] = [];
+    
+    /**
+     * @type {IterableIterator<string>}
+     */
+    private identifiersIterator: IterableIterator<string>;
+
+    /**
+     * @param {IRandomGenerator} randomGenerator
+     * @param {IOptions} options
+     * @param {IArrayUtils} arrayUtils
+     */
+    constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions,
+        @inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils,
+    ) {
+        super(randomGenerator, options);
+
+        this.arrayUtils = arrayUtils;
+        this.identifierNames = this.getInitialIdentifierNames(this.options.identifiersDictionary);
+        this.identifiersIterator = this.identifierNames.values();
+    }
+
+    /**
+     * @param {string} identifierName
+     * @returns {string | null}
+     */
+    private static incrementIdentifierName (identifierName: string): string | null {
+        let newIdentifierName: string = '';
+        let isSuccess: boolean = false;
+
+        for (const character of identifierName) {
+            if (!isSuccess && character === character.toUpperCase()) {
+                newIdentifierName += character.toLowerCase();
+            } else if (!isSuccess && character === character.toLowerCase()) {
+                newIdentifierName += character.toUpperCase();
+                isSuccess = true;
+            } else {
+                newIdentifierName += character;
+            }
+        }
+
+        if (isSuccess) {
+            return newIdentifierName;
+        }
+
+        return null;
+    }
+
+    public generate (): string {
+        if (!this.identifierNames.length) {
+            throw new Error('Too many identifiers in the code, add more words to identifiers dictionary');
+        }
+
+        const iteratorResult: IteratorResult<string> = this.identifiersIterator.next();
+
+        if (!iteratorResult.done) {
+            return iteratorResult.value;
+        }
+
+        this.identifierNames = this.getIncrementedIdentifierNames(this.identifierNames);
+        this.identifiersIterator = this.identifierNames.values();
+
+        return this.generate();
+    }
+
+    /**
+     * @returns {string}
+     */
+    public generateWithPrefix (): string {
+        const prefix: string = this.options.identifiersPrefix ?
+            `${this.options.identifiersPrefix}_`
+            : '';
+        const identifierName: string = this.generate();
+
+        return `${prefix}${identifierName}`.replace('__', '_');
+    }
+
+    /**
+     * @param {string[]} identifierNames
+     * @returns {string[]}
+     */
+    private getInitialIdentifierNames (identifierNames: string[]): string[] {
+        const formattedIdentifierNames: string[] = identifierNames
+            .map((identifierName: string) => identifierName.toLowerCase());
+
+        return this.arrayUtils.shuffle(formattedIdentifierNames);
+    }
+
+    /**
+     * @param {string[]} identifierNames
+     * @returns {string[]}
+     */
+    private getIncrementedIdentifierNames (identifierNames: string[]): string[] {
+        const formattedIdentifierNames: string[] = [];
+
+        for (const identifierName of identifierNames) {
+            const newIdentifierName: string | null = DictionaryIdentifierNamesGenerator
+                .incrementIdentifierName(identifierName);
+
+            if (newIdentifierName) {
+                formattedIdentifierNames.push(newIdentifierName);
+            }
+        }
+
+        return this.arrayUtils.shuffle(formattedIdentifierNames);
+    }
+}

+ 0 - 118
src/generators/identifier-names-generators/DictionaryNamesGenerator.ts

@@ -1,118 +0,0 @@
-import { inject, injectable } from 'inversify';
-import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
-
-import { IOptions } from '../../interfaces/options/IOptions';
-import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
-
-import { AbstractIdentifierNamesGenerator } from './AbstractIdentifierNamesGenerator';
-
-@injectable()
-export class DictionaryNamesGenerator extends AbstractIdentifierNamesGenerator {
-    /**
-     * @type {string[]}
-     */
-    private identifiers: string[] = [];
-    
-    /**
-     * @type {IterableIterator<string>}
-     */
-    private it: IterableIterator<string>;
-
-    /**
-     * @param {IRandomGenerator} randomGenerator
-     * @param {IOptions} options
-     */
-    constructor (
-        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
-        @inject(ServiceIdentifiers.IOptions) options: IOptions
-    ) {
-        super(randomGenerator, options);
-        for (const dict of options.identifiersDictionary) {
-            this.identifiers[this.identifiers.length] = dict.toLowerCase();
-        }
-        this.shuffle(this.identifiers);
-        this.it = this.identifiers.values();
-    }
-
-    /**
-     * @param {string} str
-     * @returns {string | null}
-     */
-    private static increment (str: string): string | null {
-        let newString: string = "";
-        let success: boolean = false;
-        
-        for (const i of str) {
-            if (!success && i === i.toUpperCase()) {
-                newString += i.toLowerCase();
-            } else if (!success && i === i.toLowerCase()) {
-                newString += i.toUpperCase();
-                success = true;
-            } else {
-                newString += i;
-            }
-        }
-        if (success) {
-            return newString;
-        }
-
-        return null;
-    }
-
-    /**
-     * @param {string[]} arr
-     * @returns {string[]}
-     */
-    private static incrementArr (arr: string[]): string[] {
-        const newArr: string[] = [];
-        for (const dict of arr) {
-            const newDict: string | null = DictionaryNamesGenerator.increment(dict);
-            if (newDict) {
-                newArr[newArr.length] = newDict;
-            }
-        }
-
-        return newArr;
-    }
-
-    public generate (): string {
-        if (this.identifiers.length === 0) {
-            throw new Error("identifiersDictionary is empty. Add more words to identifiersDictionary");
-        }
-        let itResult: IteratorResult<string> = this.it.next();
-        if (itResult.done) {
-            this.identifiers = DictionaryNamesGenerator.incrementArr(this.identifiers);
-            this.shuffle(this.identifiers);
-            this.it = this.identifiers.values();
-            itResult = this.it.next();
-        }
-        if (itResult.done) {
-            throw new Error("Too many identifiers in JS code, add more words to identifiersDictionary");
-        }
-        const identifierName: string = itResult.value;
-
-        return identifierName;
-    }
-
-    /**
-     * @returns {string}
-     */
-    public generateWithPrefix (): string {
-        const prefix: string = this.options.identifiersPrefix ?
-            `${this.options.identifiersPrefix}_`
-            : '';
-        const identifierName: string = this.generate();
-
-        return `${prefix}${identifierName}`.replace('__', '_');;
-    }
-
-    /**
-     * @param {string[]} arr
-     */
-    private shuffle (arr: string[]): void {
-        for (let i: number = arr.length - 1; i > 0; i--) {
-            const j: number = this.randomGenerator.getRandomInteger(0, i);
-            [arr[i], arr[j]] = [arr[j], arr[i]];
-        }
-    }
-}

+ 1 - 1
src/interfaces/options/IOptions.d.ts

@@ -15,8 +15,8 @@ export interface IOptions {
     readonly disableConsoleOutput: boolean;
     readonly domainLock: string[];
     readonly identifierNamesGenerator: IdentifierNamesGenerator;
-    readonly identifiersPrefix: string;
     readonly identifiersDictionary: string[];
+    readonly identifiersPrefix: string;
     readonly inputFileName: string;
     readonly log: boolean;
     readonly renameGlobals: boolean;

+ 7 - 2
src/options/Options.ts

@@ -2,6 +2,7 @@ import { inject, injectable } from 'inversify';
 import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
 
 import {
+    ArrayNotEmpty,
     ArrayUnique,
     IsArray,
     IsBoolean,
@@ -107,9 +108,9 @@ export class Options implements IOptions {
      * @type {IdentifierNamesGenerator}
      */
     @IsIn([
+        IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
         IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
-        IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
-        IdentifierNamesGenerator.DictionaryNamesGenerator
+        IdentifierNamesGenerator.MangledIdentifierNamesGenerator
     ])
     public readonly identifierNamesGenerator!: IdentifierNamesGenerator;
 
@@ -124,6 +125,10 @@ export class Options implements IOptions {
     @IsString({
         each: true
     })
+    @ValidateIf((options: IOptions) =>
+        options.identifierNamesGenerator === IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
+    )
+    @ArrayNotEmpty()
     public readonly identifiersDictionary!: string[];
 
     /**

+ 1 - 1
src/options/presets/Default.ts

@@ -18,7 +18,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     exclude: [],
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifiersPrefix: '',
-    identifiersDictionary: ["qwertyuiop", "asdfghjkl", "zxcvbnm"],
+    identifiersDictionary: [],
     inputFileName: '',
     log: false,
     renameGlobals: false,

+ 1 - 1
src/options/presets/NoCustomNodes.ts

@@ -17,7 +17,7 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
     exclude: [],
     identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
     identifiersPrefix: '',
-    identifiersDictionary: ["qwertyuiop", "asdfghjkl", "zxcvbnm"],
+    identifiersDictionary: [],
     inputFileName: '',
     log: false,
     renameGlobals: false,

+ 4 - 0
src/storages/string-array/StringArrayStorage.ts

@@ -50,6 +50,10 @@ export class StringArrayStorage extends ArrayStorage <string> {
     public initialize (): void {
         super.initialize();
 
+        if (!this.options.stringArray) {
+            return;
+        }
+
         const baseStringArrayName: string = this.identifierNamesGenerator
             .generate(StringArrayStorage.stringArrayNameLength);
         const baseStringArrayCallsWrapperName: string = this.identifierNamesGenerator

+ 5 - 6
test/dev/dev.ts

@@ -6,16 +6,15 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-        var s = {
-            'abcdefg': 'abcdefg'
-        };
+            var abc = 1;
+            var cde = 1;
+            var fg = 1;
+            var sss = 1;
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
             compact: false,
-            splitStrings: true,
-            splitStringsChunkLength: 4,
-            transformObjectKeys: true
+            renameGlobals: true
         }
     ).getObfuscatedCode();
 

+ 2 - 2
test/functional-tests/node-transformers/obfuscating-transformers/class-declaration-transformer/ClassDeclarationTransformer.spec.ts

@@ -121,8 +121,8 @@ describe('ClassDeclarationTransformer', () => {
         });
 
         describe('Variant #3: already renamed identifiers shouldn\'t be renamed twice', () => {
-            const classDeclarationRegExp: RegExp = /class *d *{/;
-            const variableDeclarationsRegExp: RegExp = /let *e, *f, *g, *h;/;
+            const classDeclarationRegExp: RegExp = /class *b *{/;
+            const variableDeclarationsRegExp: RegExp = /let *c, *d, *e, *f;/;
 
             let obfuscatedCode: string;
 

+ 2 - 2
test/functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec.ts

@@ -145,8 +145,8 @@ describe('FunctionDeclarationTransformer', () => {
 
         describe('Variant #5: already renamed identifiers shouldn\'t be renamed twice', () => {
             describe('Variant #1', () => {
-                const functionDeclarationRegExp: RegExp = /function *d\(\) *{/;
-                const variableDeclarationsRegExp: RegExp = /let *e, *f, *g, *h;/;
+                const functionDeclarationRegExp: RegExp = /function *b\(\) *{/;
+                const variableDeclarationsRegExp: RegExp = /let *c, *d, *e, *f;/;
 
                 let obfuscatedCode: string;
 

+ 9 - 9
test/functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec.ts

@@ -426,11 +426,11 @@ describe('VariableDeclarationTransformer', () => {
 
     describe('Variant #13: already renamed identifiers shouldn\'t be renamed twice', () => {
         describe('Variant #1', () => {
-            const variableDeclarationRegExp: RegExp = /var *d *= *0x1;/;
-            const functionDeclarationRegExp1: RegExp = /function *e *\(\) *{}/;
-            const functionDeclarationRegExp2: RegExp = /function *f *\(\) *{}/;
-            const functionDeclarationRegExp3: RegExp = /function *g *\(\) *{}/;
-            const functionDeclarationRegExp4: RegExp = /function *h *\(\) *{}/;
+            const variableDeclarationRegExp: RegExp = /var *b *= *0x1;/;
+            const functionDeclarationRegExp1: RegExp = /function *c *\(\) *{}/;
+            const functionDeclarationRegExp2: RegExp = /function *d *\(\) *{}/;
+            const functionDeclarationRegExp3: RegExp = /function *e *\(\) *{}/;
+            const functionDeclarationRegExp4: RegExp = /function *f *\(\) *{}/;
 
             let obfuscatedCode: string;
 
@@ -468,10 +468,10 @@ describe('VariableDeclarationTransformer', () => {
         });
 
         describe('Variant #2', () => {
-            const variableDeclarationRegExp1: RegExp = /var *d *= *0x1;/;
-            const variableDeclarationRegExp2: RegExp = /var *e;/;
-            const functionDeclarationRegExp: RegExp = /function *f *\(\) *{/;
-            const variableDeclarationRegExp3: RegExp = /var *f *= *function *\(\) *{}/;
+            const variableDeclarationRegExp1: RegExp = /var *b *= *0x1;/;
+            const variableDeclarationRegExp2: RegExp = /var *c;/;
+            const functionDeclarationRegExp: RegExp = /function *d *\(\) *{/;
+            const variableDeclarationRegExp3: RegExp = /var *d *= *function *\(\) *{}/;
 
             let obfuscatedCode: string;
 

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