Explorar o código

Merge pull request #663 from javascript-obfuscator/prevent-mangled-generator-name-sequence-mutation

Prevented mutation of the name sequences of `mangled` identifier name generators
Timofey Kachalov %!s(int64=4) %!d(string=hai) anos
pai
achega
160ff20ca4

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 
+v1.5.2
+---
+* Prevented mutation of the name sequences of `mangled` identifier name generators
+
 v1.5.1
 ---
 * Fixed runtime error when `IfStatement` contains only single `let` or `const` variable declaration when `simlify` option enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/661

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.browser.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.cli.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.js


+ 1 - 1
package.json

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

+ 2 - 5
src/custom-code-helpers/console-output/group/ConsoleOutputCodeHelperGroup.ts

@@ -22,7 +22,6 @@ import { CallsControllerFunctionCodeHelper } from '../../calls-controller/CallsC
 import { ConsoleOutputDisableCodeHelper } from '../ConsoleOutputDisableCodeHelper';
 import { NodeAppender } from '../../../node/NodeAppender';
 import { NodeLexicalScopeUtils } from '../../../node/NodeLexicalScopeUtils';
-import { NodeGuards } from '../../../node/NodeGuards';
 
 @injectable()
 export class ConsoleOutputCodeHelperGroup extends AbstractCustomCodeHelperGroup {
@@ -82,13 +81,11 @@ export class ConsoleOutputCodeHelperGroup extends AbstractCustomCodeHelperGroup
             .getLexicalScope(consoleOutputDisableHostNode) ?? null;
 
         const consoleOutputDisableFunctionName: string = consoleOutputDisableLexicalScopeNode
-            && NodeGuards.isProgramNode(consoleOutputDisableLexicalScopeNode)
             ? this.identifierNamesGenerator.generate(consoleOutputDisableLexicalScopeNode)
-            : this.randomGenerator.getRandomString(5);
+            : this.identifierNamesGenerator.generateNext();
         const callsControllerFunctionName: string = consoleOutputDisableLexicalScopeNode
-            && NodeGuards.isProgramNode(consoleOutputDisableLexicalScopeNode)
             ? this.identifierNamesGenerator.generate(consoleOutputDisableLexicalScopeNode)
-            : this.randomGenerator.getRandomString(5);
+            : this.identifierNamesGenerator.generateNext();
 
         // consoleOutputDisableExpression helper nodes append
         this.appendCustomNodeIfExist(

+ 2 - 4
src/custom-code-helpers/debug-protection/group/DebugProtectionCodeHelperGroup.ts

@@ -84,13 +84,11 @@ export class DebugProtectionCodeHelperGroup extends AbstractCustomCodeHelperGrou
             .getLexicalScope(debugProtectionFunctionCallHostNode) ?? null;
 
         const debugProtectionFunctionName: string = debugProtectionFunctionCallScopeNode
-            && NodeGuards.isProgramNode(debugProtectionFunctionCallScopeNode)
             ? this.identifierNamesGenerator.generate(debugProtectionFunctionCallScopeNode)
-            : this.randomGenerator.getRandomString(5);
+            : this.identifierNamesGenerator.generateNext();
         const callsControllerFunctionName: string = debugProtectionFunctionCallScopeNode
-            && NodeGuards.isProgramNode(debugProtectionFunctionCallScopeNode)
             ? this.identifierNamesGenerator.generate(debugProtectionFunctionCallScopeNode)
-            : this.randomGenerator.getRandomString(5);
+            : this.identifierNamesGenerator.generateNext();
 
         // debugProtectionFunctionCall helper nodes append
         this.appendCustomNodeIfExist(

+ 0 - 3
src/custom-code-helpers/domain-lock/group/DomainLockCustomCodeHelperGroup.ts

@@ -22,7 +22,6 @@ import { CallsControllerFunctionCodeHelper } from '../../calls-controller/CallsC
 import { DomainLockCodeHelper } from '../DomainLockCodeHelper';
 import { NodeAppender } from '../../../node/NodeAppender';
 import { NodeLexicalScopeUtils } from '../../../node/NodeLexicalScopeUtils';
-import { NodeGuards } from '../../../node/NodeGuards';
 
 @injectable()
 export class DomainLockCustomCodeHelperGroup extends AbstractCustomCodeHelperGroup {
@@ -82,11 +81,9 @@ export class DomainLockCustomCodeHelperGroup extends AbstractCustomCodeHelperGro
             .getLexicalScope(domainLockFunctionHostNode) ?? null;
 
         const domainLockFunctionName: string = domainLockFunctionLexicalScopeNode
-            && NodeGuards.isProgramNode(domainLockFunctionLexicalScopeNode)
             ? this.identifierNamesGenerator.generate(domainLockFunctionLexicalScopeNode)
             : this.identifierNamesGenerator.generateNext();
         const callsControllerFunctionName: string = domainLockFunctionLexicalScopeNode
-            && NodeGuards.isProgramNode(domainLockFunctionLexicalScopeNode)
             ? this.identifierNamesGenerator.generate(domainLockFunctionLexicalScopeNode)
             : this.identifierNamesGenerator.generateNext();
 

+ 18 - 19
src/generators/identifier-names-generators/MangledIdentifierNamesGenerator.ts

@@ -1,9 +1,8 @@
-import { inject, injectable, postConstruct } from 'inversify';
+import { inject, injectable } from 'inversify';
 import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
 
 import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
 
-import { IInitializable } from '../../interfaces/IInitializable';
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 
@@ -15,12 +14,7 @@ import { AbstractIdentifierNamesGenerator } from './AbstractIdentifierNamesGener
 import { NodeLexicalScopeUtils } from '../../node/NodeLexicalScopeUtils';
 
 @injectable()
-export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator implements IInitializable {
-    /**
-     * @type {string[]}
-     */
-    protected static nameSequence: string[];
-
+export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGenerator {
     /**
      * @type {string}
      */
@@ -31,6 +25,13 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
      */
     private static readonly lastMangledNameInScopeMap: WeakMap <TNodeWithLexicalScope, string> = new WeakMap();
 
+    /**
+     * @type {string[]}
+     */
+    private static readonly nameSequence: string[] = [
+        ...`${numbersString}${alphabetString}${alphabetStringUppercase}`
+    ];
+
     /**
      * Reserved JS words with length of 2-4 symbols that can be possible generated with this replacer
      *
@@ -58,15 +59,6 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
         super(randomGenerator, options);
     }
 
-    @postConstruct()
-    public initialize (): void {
-        if (!MangledIdentifierNamesGenerator.nameSequence) {
-            MangledIdentifierNamesGenerator.nameSequence = [
-                ...`${numbersString}${alphabetString}${alphabetStringUppercase}`
-            ];
-        }
-    }
-
     /**
      * We can only ignore limited nameLength, it has no sense here
      * @param {number} nameLength
@@ -138,13 +130,20 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
             && !MangledIdentifierNamesGenerator.reservedNamesSet.has(mangledName);
     }
 
+    /**
+     * @returns {string[]}
+     */
+    protected getNameSequence (): string[] {
+        return MangledIdentifierNamesGenerator.nameSequence;
+    }
+
     /**
      * @param {string} previousMangledName
      * @returns {string}
      */
-    private generateNewMangledName (previousMangledName: string): string {
+    protected generateNewMangledName (previousMangledName: string): string {
         const generateNewMangledName: (name: string) => string = (name: string): string => {
-            const nameSequence: string[] = MangledIdentifierNamesGenerator.nameSequence;
+            const nameSequence: string[] = this.getNameSequence();
             const nameSequenceLength: number = nameSequence.length;
             const nameLength: number = name.length;
 

+ 32 - 5
src/generators/identifier-names-generators/MangledShuffledIdentifierNamesGenerator.ts

@@ -13,6 +13,11 @@ import { MangledIdentifierNamesGenerator } from './MangledIdentifierNamesGenerat
 
 @injectable()
 export class MangledShuffledIdentifierNamesGenerator extends MangledIdentifierNamesGenerator {
+    /**
+     * @type {string[]}
+     */
+    protected static shuffledNameSequence: string[];
+
     /**
      * @type {IArrayUtils}
      */
@@ -35,11 +40,33 @@ export class MangledShuffledIdentifierNamesGenerator extends MangledIdentifierNa
 
     @postConstruct()
     public initialize (): void {
-        if (!MangledIdentifierNamesGenerator.nameSequence) {
-            MangledIdentifierNamesGenerator.nameSequence = [
-                ...`${numbersString}`,
-                ...this.arrayUtils.shuffle([...`${alphabetString}${alphabetStringUppercase}`])
-            ];
+        this.initializeNameSequence([
+            ...`${numbersString}`,
+            ...this.arrayUtils.shuffle([...`${alphabetString}${alphabetStringUppercase}`])
+        ]);
+    }
+
+    /**
+     * @param {string[]} nameSequence
+     */
+    protected initializeNameSequence (nameSequence: string[]): void {
+        if (!this.getNameSequence()) {
+            MangledShuffledIdentifierNamesGenerator.shuffledNameSequence = nameSequence;
         }
     }
+
+    /**
+     * @returns {string[]}
+     */
+    protected getNameSequence (): string[] {
+        return MangledShuffledIdentifierNamesGenerator.shuffledNameSequence;
+    }
+
+    /**
+     * @param {string} previousMangledName
+     * @returns {string}
+     */
+    protected generateNewMangledName (previousMangledName: string): string {
+        return super.generateNewMangledName(previousMangledName);
+    }
 }

+ 44 - 0
test/functional-tests/generators/identifier-names-generators/mangled-shuffled-identifier-names-generator/MangledShuffledIdentifierNamesGenerator.spec.ts

@@ -0,0 +1,44 @@
+import { assert } from 'chai';
+
+import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
+
+import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
+
+import { readFileAsString } from '../../../../helpers/readFileAsString';
+
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
+
+describe('MangledShuffledIdentifierNamesGenerator', () => {
+    describe('Variant #1: prevent name sequence mutation of base `mangled` generator', () => {
+        const functionsRegExp: RegExp = new RegExp(
+            'function foo *\\(a, *b\\) *{} *' +
+            'function foo *\\(a, *b\\) *{} *' +
+            'function foo *\\(a, *b\\) *{} *' +
+            'function foo *\\(a, *b\\) *{}'
+        );
+
+        let obfuscatedCode: string = '';
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/prevent-name-sequence-mutation.js');
+
+            for (let i = 0; i < 4; i++) {
+                const identifierNamesGenerator = i % 2 === 0
+                    ? IdentifierNamesGenerator.MangledIdentifierNamesGenerator
+                    : IdentifierNamesGenerator.MangledShuffledIdentifierNamesGenerator;
+
+                obfuscatedCode += JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        identifierNamesGenerator
+                    }
+                ).getObfuscatedCode();
+            }
+        });
+
+        it('Should not mutate name sequences between mangled generators', () => {
+            assert.notMatch(obfuscatedCode, functionsRegExp);
+        });
+    });
+});

+ 1 - 0
test/functional-tests/generators/identifier-names-generators/mangled-shuffled-identifier-names-generator/fixtures/prevent-name-sequence-mutation.js

@@ -0,0 +1 @@
+function foo (bar, baz) {}

+ 1 - 0
test/index.spec.ts

@@ -72,6 +72,7 @@ import './functional-tests/custom-code-helpers/string-array/templates/string-arr
 import './functional-tests/custom-code-helpers/string-array/templates/string-array-rotate-function-template/StringArrayRotateFunctionTemplate.spec';
 import './functional-tests/generators/identifier-names-generators/dictionary-identifier-names-generator/DictionaryIdentifierNamesGenerator.spec';
 import './functional-tests/generators/identifier-names-generators/mangled-identifier-names-generator/MangledIdentifierNamesGenerator.spec';
+import './functional-tests/generators/identifier-names-generators/mangled-shuffled-identifier-names-generator/MangledShuffledIdentifierNamesGenerator.spec';
 import './functional-tests/issues/issue321.spec';
 import './functional-tests/issues/issue355.spec';
 import './functional-tests/issues/issue419.spec';

+ 1 - 1
test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts

@@ -210,7 +210,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
                         evaluationResult = result;
                     })
                     .catch((error: Error) => {
-                        evaluationResult = `${error.message}. ${error.stack}`;
+                        evaluationResult = `${error.message}. ${error.stack}. Code: ${obfuscatedCode}`;
                     });
             });
 

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio