浏览代码

Added prefixes to the generated global identifiers of the added code

sanex3339 5 年之前
父节点
当前提交
6d03a2bacf
共有 28 个文件被更改,包括 336 次插入200 次删除
  1. 4 0
      CHANGELOG.md
  2. 7 0
      README.md
  3. 0 0
      dist/index.browser.js
  4. 0 0
      dist/index.cli.js
  5. 0 0
      dist/index.js
  6. 9 9
      package.json
  7. 2 2
      src/custom-code-helpers/domain-lock/group/DomainLockCustomCodeHelperGroup.ts
  8. 2 2
      src/custom-code-helpers/self-defending/group/SelfDefendingCodeHelperGroup.ts
  9. 2 2
      src/custom-code-helpers/string-array/StringArrayRotateFunctionCodeHelper.ts
  10. 1 1
      src/generators/identifier-names-generators/AbstractIdentifierNamesGenerator.ts
  11. 20 20
      src/generators/identifier-names-generators/DictionaryIdentifierNamesGenerator.ts
  12. 9 9
      src/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.ts
  13. 23 23
      src/generators/identifier-names-generators/MangledIdentifierNamesGenerator.ts
  14. 1 1
      src/interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator.ts
  15. 1 1
      src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts
  16. 3 3
      src/node/NodeUtils.ts
  17. 2 2
      src/storages/string-array/StringArrayStorage.ts
  18. 66 14
      test/functional-tests/custom-code-helpers/domain-lock/DomainLockCodeHelper.spec.ts
  19. 3 0
      test/functional-tests/custom-code-helpers/domain-lock/fixtures/append-inside-function-scope.js
  20. 59 0
      test/functional-tests/custom-code-helpers/self-defending/SelfDefendingCodeHelper.spec.ts
  21. 3 0
      test/functional-tests/custom-code-helpers/self-defending/fixtures/append-inside-function-scope.js
  22. 1 0
      test/functional-tests/custom-code-helpers/self-defending/fixtures/simple-input.js
  23. 4 3
      test/functional-tests/issues/issue437.spec.ts
  24. 7 6
      test/index.spec.ts
  25. 40 40
      test/unit-tests/generators/identifier-names-generators/DictionarylIdentifierNamesGenerator.spec.ts
  26. 4 4
      test/unit-tests/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.spec.ts
  27. 14 14
      test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts
  28. 49 44
      yarn.lock

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 
+v0.25.3
+---
+* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/568
+
 v0.25.2
 ---
 * Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/563

+ 7 - 0
README.md

@@ -270,6 +270,13 @@ For example:
 
 Kind of variables of inserted nodes will auto-detected, based on most prevailing kind of variables of source code.
 
+## Conflicts of identifier names between different files
+
+During obfuscation of the different files, the same names can be generated for the global identifiers between these files.
+To prevent this set the unique prefix for all global identifiers for each obfuscated file with [`identifiersPrefix`](#identifiersPrefix) option. 
+
+When using CLI this prefix will be added automatically.
+
 ## Antiviruses false positive virus alerts
 
 Some input source code that will obfuscated with some obfuscation options can trigger false positive alerts in a few antiviruses. If you will get this false positive triggers, try to play with obfuscation options.

文件差异内容过多而无法显示
+ 0 - 0
dist/index.browser.js


文件差异内容过多而无法显示
+ 0 - 0
dist/index.cli.js


文件差异内容过多而无法显示
+ 0 - 0
dist/index.js


+ 9 - 9
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.25.2",
+  "version": "0.25.3",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",
@@ -23,7 +23,7 @@
   "dependencies": {
     "@gradecam/tsenum": "1.2.0",
     "@nuxtjs/opencollective": "0.2.2",
-    "acorn": "7.1.0",
+    "acorn": "7.1.1",
     "acorn-import-meta": "1.0.0",
     "chalk": "3.0.0",
     "chance": "1.1.4",
@@ -45,7 +45,7 @@
     "tslib": "1.11.1"
   },
   "devDependencies": {
-    "@types/chai": "4.2.9",
+    "@types/chai": "4.2.10",
     "@types/chance": "1.0.8",
     "@types/escodegen": "0.0.6",
     "@types/eslint-scope": "3.7.0",
@@ -53,20 +53,20 @@
     "@types/estree": "0.0.42",
     "@types/md5": "2.1.33",
     "@types/mkdirp": "1.0.0",
-    "@types/mocha": "7.0.1",
+    "@types/mocha": "7.0.2",
     "@types/multimatch": "4.0.0",
     "@types/node": "12.12.14",
     "@types/rimraf": "2.0.3",
     "@types/sinon": "7.5.2",
     "@types/string-template": "1.0.2",
     "@types/webpack-env": "1.15.1",
-    "@typescript-eslint/eslint-plugin": "2.21.0",
-    "@typescript-eslint/parser": "2.21.0",
+    "@typescript-eslint/eslint-plugin": "2.22.0",
+    "@typescript-eslint/parser": "2.22.0",
     "chai": "4.2.0",
     "coveralls": "3.0.9",
     "eslint": "6.8.0",
     "eslint-plugin-import": "2.20.1",
-    "eslint-plugin-jsdoc": "21.0.0",
+    "eslint-plugin-jsdoc": "22.0.0",
     "eslint-plugin-no-null": "1.0.2",
     "eslint-plugin-prefer-arrow": "1.1.7",
     "eslint-plugin-unicorn": "16.1.1",
@@ -81,8 +81,8 @@
     "threads": "1.3.0",
     "ts-loader": "6.2.1",
     "ts-node": "6.1.0",
-    "typescript": "3.8.2",
-    "webpack": "4.41.6",
+    "typescript": "3.8.3",
+    "webpack": "4.42.0",
     "webpack-cli": "3.3.11",
     "webpack-node-externals": "1.7.2"
   },

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

@@ -84,11 +84,11 @@ export class DomainLockCustomCodeHelperGroup extends AbstractCustomCodeHelperGro
         const domainLockFunctionName: string = domainLockFunctionLexicalScopeNode
             && NodeGuards.isProgramNode(domainLockFunctionLexicalScopeNode)
             ? this.identifierNamesGenerator.generate(domainLockFunctionLexicalScopeNode)
-            : this.randomGenerator.getRandomString(5);
+            : this.identifierNamesGenerator.generateNext();
         const callsControllerFunctionName: string = domainLockFunctionLexicalScopeNode
             && NodeGuards.isProgramNode(domainLockFunctionLexicalScopeNode)
             ? this.identifierNamesGenerator.generate(domainLockFunctionLexicalScopeNode)
-            : this.randomGenerator.getRandomString(5);
+            : this.identifierNamesGenerator.generateNext();
 
         // domainLock helper nodes append
         this.appendCustomNodeIfExist(

+ 2 - 2
src/custom-code-helpers/self-defending/group/SelfDefendingCodeHelperGroup.ts

@@ -82,10 +82,10 @@ export class SelfDefendingCodeHelperGroup extends AbstractCustomCodeHelperGroup
 
         const selfDefendingFunctionName: string = selfDefendingFunctionLexicalScopeNode
             ? this.identifierNamesGenerator.generate(selfDefendingFunctionLexicalScopeNode)
-            : this.identifierNamesGenerator.generateForGlobalScope();
+            : this.identifierNamesGenerator.generateNext();
         const callsControllerFunctionName: string = selfDefendingFunctionLexicalScopeNode
             ? this.identifierNamesGenerator.generate(selfDefendingFunctionLexicalScopeNode)
-            : this.identifierNamesGenerator.generateForGlobalScope();
+            : this.identifierNamesGenerator.generateNext();
 
         // selfDefendingUnicode helper nodes append
         this.appendCustomNodeIfExist(

+ 2 - 2
src/custom-code-helpers/string-array/StringArrayRotateFunctionCodeHelper.ts

@@ -90,8 +90,8 @@ export class StringArrayRotateFunctionCodeHelper extends AbstractCustomCodeHelpe
      * @returns {string}
      */
     protected getCodeHelperTemplate (): string {
-        const timesName: string = this.identifierNamesGenerator.generateForGlobalScope();
-        const whileFunctionName: string = this.identifierNamesGenerator.generateForGlobalScope();
+        const timesName: string = this.identifierNamesGenerator.generateNext();
+        const whileFunctionName: string = this.identifierNamesGenerator.generateNext();
         const preservedNames: string[] = [`^${this.stringArrayName}$`];
 
         let code: string = '';

+ 1 - 1
src/generators/identifier-names-generators/AbstractIdentifierNamesGenerator.ts

@@ -138,5 +138,5 @@ export abstract class AbstractIdentifierNamesGenerator implements IIdentifierNam
      * @param {number} nameLength
      * @returns {string}
      */
-    public abstract generateWithPrefix (nameLength?: number): string;
+    public abstract generateNext (nameLength?: number): string;
 }

+ 20 - 20
src/generators/identifier-names-generators/DictionaryIdentifierNamesGenerator.ts

@@ -69,7 +69,7 @@ export class DictionaryIdentifierNamesGenerator extends AbstractIdentifierNamesG
         return null;
     }
 
-    public generateForGlobalScope (): string {
+    public generateNext (): string {
         const identifierName: string = this.generateNewDictionaryName();
 
         this.preserveName(identifierName);
@@ -78,42 +78,42 @@ export class DictionaryIdentifierNamesGenerator extends AbstractIdentifierNamesG
     }
 
     /**
-     * @param {TNodeWithLexicalScope} lexicalScopeNode
      * @returns {string}
      */
-    public generateForLexicalScope (lexicalScopeNode: TNodeWithLexicalScope): string {
-        const lexicalScopes: TNodeWithLexicalScope[] = [
-            lexicalScopeNode,
-            ...NodeLexicalScopeUtils.getLexicalScopes(lexicalScopeNode)
-        ];
+    public generateForGlobalScope (): string {
+        const prefix: string = this.options.identifiersPrefix ?
+            `${this.options.identifiersPrefix}`
+            : '';
         const identifierName: string = this.generateNewDictionaryName();
+        const identifierNameWithPrefix: string = `${prefix}${identifierName}`;
 
-        if (!this.isValidIdentifierNameInLexicalScopes(identifierName, lexicalScopes)) {
-            return this.generateForLexicalScope(lexicalScopeNode);
+        if (!this.isValidIdentifierName(identifierNameWithPrefix)) {
+            return this.generateForGlobalScope();
         }
 
-        this.preserveNameForLexicalScope(identifierName, lexicalScopeNode);
+        this.preserveName(identifierNameWithPrefix);
 
-        return identifierName;
+        return identifierNameWithPrefix;
     }
 
     /**
+     * @param {TNodeWithLexicalScope} lexicalScopeNode
      * @returns {string}
      */
-    public generateWithPrefix (): string {
-        const prefix: string = this.options.identifiersPrefix ?
-            `${this.options.identifiersPrefix}`
-            : '';
+    public generateForLexicalScope (lexicalScopeNode: TNodeWithLexicalScope): string {
+        const lexicalScopes: TNodeWithLexicalScope[] = [
+            lexicalScopeNode,
+            ...NodeLexicalScopeUtils.getLexicalScopes(lexicalScopeNode)
+        ];
         const identifierName: string = this.generateNewDictionaryName();
-        const identifierNameWithPrefix: string = `${prefix}${identifierName}`;
 
-        if (!this.isValidIdentifierName(identifierNameWithPrefix)) {
-            return this.generateWithPrefix();
+        if (!this.isValidIdentifierNameInLexicalScopes(identifierName, lexicalScopes)) {
+            return this.generateForLexicalScope(lexicalScopeNode);
         }
 
-        this.preserveName(identifierNameWithPrefix);
+        this.preserveNameForLexicalScope(identifierName, lexicalScopeNode);
 
-        return identifierNameWithPrefix;
+        return identifierName;
     }
 
     /**

+ 9 - 9
src/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.ts

@@ -32,7 +32,7 @@ export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNames
      * @param {number} nameLength
      * @returns {string}
      */
-    public generateForGlobalScope (nameLength?: number): string {
+    public generateNext (nameLength?: number): string {
         const rangeMinInteger: number = 10000;
         const rangeMaxInteger: number = 99_999_999;
         const randomInteger: number = this.randomGenerator.getRandomInteger(rangeMinInteger, rangeMaxInteger);
@@ -45,7 +45,7 @@ export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNames
         const identifierName: string = `_${Utils.hexadecimalPrefix}${baseIdentifierName}`;
 
         if (!this.isValidIdentifierName(identifierName)) {
-            return this.generateForGlobalScope(nameLength);
+            return this.generateNext(nameLength);
         }
 
         this.preserveName(identifierName);
@@ -54,21 +54,21 @@ export class HexadecimalIdentifierNamesGenerator extends AbstractIdentifierNames
     }
 
     /**
-     * @param {TNodeWithLexicalScope} lexicalScopeNode
      * @param {number} nameLength
      * @returns {string}
      */
-    public generateForLexicalScope (lexicalScopeNode: TNodeWithLexicalScope, nameLength?: number): string {
-        return this.generateForGlobalScope(nameLength);
+    public generateForGlobalScope (nameLength?: number): string {
+        const identifierName: string = this.generateNext(nameLength);
+
+        return `${this.options.identifiersPrefix}${identifierName}`.replace('__', '_');
     }
 
     /**
+     * @param {TNodeWithLexicalScope} lexicalScopeNode
      * @param {number} nameLength
      * @returns {string}
      */
-    public generateWithPrefix (nameLength?: number): string {
-        const identifierName: string = this.generateForGlobalScope(nameLength);
-
-        return `${this.options.identifiersPrefix}${identifierName}`.replace('__', '_');
+    public generateForLexicalScope (lexicalScopeNode: TNodeWithLexicalScope, nameLength?: number): string {
+        return this.generateNext(nameLength);
     }
 }

+ 23 - 23
src/generators/identifier-names-generators/MangledIdentifierNamesGenerator.ts

@@ -58,7 +58,7 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
      * @param {number} nameLength
      * @returns {string}
      */
-    public generateForGlobalScope (nameLength?: number): string {
+    public generateNext (nameLength?: number): string {
         const identifierName: string = this.generateNewMangledName(this.previousMangledName);
 
         this.previousMangledName = identifierName;
@@ -67,6 +67,28 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
         return identifierName;
     }
 
+    /**
+     * @param {number} nameLength
+     * @returns {string}
+     */
+    public generateForGlobalScope (nameLength?: number): string {
+        const prefix: string = this.options.identifiersPrefix ?
+            `${this.options.identifiersPrefix}`
+            : '';
+        const identifierName: string = this.generateNewMangledName(this.previousMangledName);
+        const identifierNameWithPrefix: string = `${prefix}${identifierName}`;
+
+        this.previousMangledName = identifierName;
+
+        if (!this.isValidIdentifierName(identifierNameWithPrefix)) {
+            return this.generateForGlobalScope(nameLength);
+        }
+
+        this.preserveName(identifierNameWithPrefix);
+
+        return identifierNameWithPrefix;
+    }
+
     /**
      * @param {TNodeWithLexicalScope} lexicalScopeNode
      * @param {number} nameLength
@@ -93,28 +115,6 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
         return identifierName;
     }
 
-    /**
-     * @param {number} nameLength
-     * @returns {string}
-     */
-    public generateWithPrefix (nameLength?: number): string {
-        const prefix: string = this.options.identifiersPrefix ?
-            `${this.options.identifiersPrefix}`
-            : '';
-        const identifierName: string = this.generateNewMangledName(this.previousMangledName);
-        const identifierNameWithPrefix: string = `${prefix}${identifierName}`;
-
-        this.previousMangledName = identifierName;
-
-        if (!this.isValidIdentifierName(identifierNameWithPrefix)) {
-            return this.generateWithPrefix(nameLength);
-        }
-
-        this.preserveName(identifierNameWithPrefix);
-
-        return identifierNameWithPrefix;
-    }
-
     /**
      * @param {string} mangledName
      * @returns {boolean}

+ 1 - 1
src/interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator.ts

@@ -26,7 +26,7 @@ export interface IIdentifierNamesGenerator {
      * @param {number} nameLength
      * @returns {string}
      */
-    generateWithPrefix (nameLength?: number): string;
+    generateNext (nameLength?: number): string;
 
     /**
      * @param {string} identifierName

+ 1 - 1
src/node-transformers/obfuscating-transformers/obfuscating-replacers/identifier-obfuscating-replacers/BaseIdentifierObfuscatingReplacer.ts

@@ -72,7 +72,7 @@ export class BaseIdentifierObfuscatingReplacer extends AbstractObfuscatingReplac
             return;
         }
 
-        const newIdentifierName: string = this.identifierNamesGenerator.generateWithPrefix();
+        const newIdentifierName: string = this.identifierNamesGenerator.generateForGlobalScope();
 
         if (!this.blockScopesMap.has(lexicalScopeNode)) {
             this.blockScopesMap.set(lexicalScopeNode, new Map());

+ 3 - 3
src/node/NodeUtils.ts

@@ -10,8 +10,8 @@ import { NodeMetadata } from './NodeMetadata';
 
 export class NodeUtils {
     /**
-     * @param {T} literalNode
-     * @returns {T}
+     * @param {ESTree.Literal} literalNode
+     * @returns {ESTree.Literal}
      */
     public static addXVerbatimPropertyTo (literalNode: ESTree.Literal): ESTree.Literal {
         literalNode['x-verbatim-property'] = {
@@ -32,7 +32,7 @@ export class NodeUtils {
 
     /**
      * @param {string} code
-     * @returns {Statement[]}
+     * @returns {ESTree.Statement[]}
      */
     public static convertCodeToStructure (code: string): ESTree.Statement[] {
         const structure: ESTree.Program = ASTParserFacade.parse(

+ 2 - 2
src/storages/string-array/StringArrayStorage.ts

@@ -162,7 +162,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
     public getStorageId (): string {
         if (!this.stringArrayStorageName) {
             this.stringArrayStorageName = this.identifierNamesGenerator
-                .generateWithPrefix(StringArrayStorage.stringArrayNameLength);
+                .generateForGlobalScope(StringArrayStorage.stringArrayNameLength);
         }
 
         return this.stringArrayStorageName;
@@ -174,7 +174,7 @@ export class StringArrayStorage extends MapStorage <string, IStringArrayStorageI
     public getStorageCallsWrapperName (): string {
         if (!this.stringArrayStorageCallsWrapperName) {
             this.stringArrayStorageCallsWrapperName = this.identifierNamesGenerator
-                .generateWithPrefix(StringArrayStorage.stringArrayNameLength);
+                .generateForGlobalScope(StringArrayStorage.stringArrayNameLength);
         }
 
         return this.stringArrayStorageCallsWrapperName;

+ 66 - 14
test/functional-tests/custom-code-helpers/domain-lock/DomainLockCodeHelper.spec.ts

@@ -1,5 +1,7 @@
 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';
@@ -7,29 +9,79 @@ import { readFileAsString } from '../../../helpers/readFileAsString';
 import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscatorFacade';
 
 describe('DomainLockCodeHelper', () => {
-    const regExp: RegExp = /var _0x([a-f0-9]){4,6} *= *new RegExp/;
-
     describe('`domainLock` option is set', () => {
-        let obfuscatedCode: string;
+        describe('Variant #1: base behaviour', () => {
+            const regExp: RegExp = /var _0x([a-f0-9]){4,6} *= *new RegExp/;
 
-        before(() => {
-            const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
+            let obfuscatedCode: string;
 
-            obfuscatedCode = JavaScriptObfuscator.obfuscate(
-                code,
-                {
-                    ...NO_ADDITIONAL_NODES_PRESET,
-                    domainLock: ['.example.com']
-                }
-            ).getObfuscatedCode();
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        domainLock: ['.example.com']
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('should correctly append code helper into the obfuscated code', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
         });
 
-        it('should correctly append code helper into the obfuscated code', () => {
-            assert.match(obfuscatedCode, regExp);
+        describe('Variant #2: identifier names when appended inside global scope', () => {
+            const regExp: RegExp = /var foo[a-z] *= *foo[a-z]\(this, *function *\(\) *{/;
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        domainLock: ['.example.com'],
+                        identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
+                        identifiersPrefix: 'foo'
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('should add prefix to the helper identifiers inside global scope', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
+        });
+
+        describe('Variant #3: identifier names when appended inside function scope', () => {
+            const regExp: RegExp = /var [a-z] *= *[a-z]\(this, *function *\(\) *{/;
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/append-inside-function-scope.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        domainLock: ['.example.com'],
+                        identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
+                        identifiersPrefix: 'foo'
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('should not add prefix to the helper identifiers inside global scope', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
         });
     });
 
     describe('`domainLock` option isn\'t set', () => {
+        const regExp: RegExp = /var _0x([a-f0-9]){4,6} *= *new RegExp/;
+
         let obfuscatedCode: string;
 
         before(() => {

+ 3 - 0
test/functional-tests/custom-code-helpers/domain-lock/fixtures/append-inside-function-scope.js

@@ -0,0 +1,3 @@
+(function () {
+    var test = 'test';
+})();

+ 59 - 0
test/functional-tests/custom-code-helpers/self-defending/SelfDefendingCodeHelper.spec.ts

@@ -0,0 +1,59 @@
+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('SelfDefendingCodeHelper', () => {
+    describe('`selfDefending` option is set', () => {
+        describe('Variant #1: identifier names when appended inside global scope', () => {
+            const regExp: RegExp = /var foo[a-z] *= *foo[a-z]\(this, *function *\(\) *{/;
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
+                        identifiersPrefix: 'foo',
+                        selfDefending: true
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('should add prefix to the helper identifiers inside global scope', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
+        });
+
+        describe('Variant #2: identifier names when appended inside function scope', () => {
+            const regExp: RegExp = /var [a-z] *= *[a-z]\(this, *function *\(\) *{/;
+            let obfuscatedCode: string;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/append-inside-function-scope.js');
+
+                obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_ADDITIONAL_NODES_PRESET,
+                        identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
+                        identifiersPrefix: 'foo',
+                        selfDefending: true
+                    }
+                ).getObfuscatedCode();
+            });
+
+            it('should not add prefix to the helper identifiers inside global scope', () => {
+                assert.match(obfuscatedCode, regExp);
+            });
+        });
+    });
+});

+ 3 - 0
test/functional-tests/custom-code-helpers/self-defending/fixtures/append-inside-function-scope.js

@@ -0,0 +1,3 @@
+(function () {
+    var test = 'test';
+})();

+ 1 - 0
test/functional-tests/custom-code-helpers/self-defending/fixtures/simple-input.js

@@ -0,0 +1 @@
+var test = 'test';

+ 4 - 3
test/functional-tests/issues/issue437.spec.ts

@@ -8,11 +8,12 @@ import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';
 //
 describe('Issue #437', () => {
     describe('Fixture code should not break on obfuscating', () => {
-        let doObfuscate: Function;
+        let testFunc: () => string;
 
         before(() => {
             const code: string = readFileAsString(__dirname + '/fixtures/issue437.js');
-            doObfuscate = () => JavaScriptObfuscator.obfuscate(
+
+            testFunc = () => JavaScriptObfuscator.obfuscate(
                 code,
                 {
                     ...NO_ADDITIONAL_NODES_PRESET,
@@ -22,7 +23,7 @@ describe('Issue #437', () => {
         });
 
         it('does not break on obfuscating', () => {
-            assert.doesNotThrow(doObfuscate);
+            assert.doesNotThrow(testFunc);
         });
     });
 });

+ 7 - 6
test/index.spec.ts

@@ -54,11 +54,18 @@ import './unit-tests/utils/Utils.spec';
 import './functional-tests/analyzers/calls-graph-analyzer/CallsGraphAnalyzer.spec';
 import './functional-tests/cli/JavaScriptObfuscatorCLI.spec';
 import './functional-tests/custom-code-helpers/console-output/ConsoleOutputDisableExpressionCodeHelper.spec';
+import './functional-tests/custom-code-helpers/common/templates/GlobalVariableNoEvalTemplate.spec';
+import './functional-tests/custom-code-helpers/debug-protection/templates/DebugProtectionFunctionCallTemplate.spec';
 import './functional-tests/custom-code-helpers/domain-lock/DomainLockCodeHelper.spec';
+import './functional-tests/custom-code-helpers/domain-lock/templates/DomainLockNodeTemplate.spec';
+import './functional-tests/custom-code-helpers/self-defending/SelfDefendingCodeHelper.spec';
 import './functional-tests/custom-code-helpers/self-defending/templates/SelfDefendingTemplate.spec';
 import './functional-tests/custom-code-helpers/string-array/StringArrayCallsWrapperCodeHelper.spec';
 import './functional-tests/custom-code-helpers/string-array/StringArrayRotateFunctionCodeHelper.spec';
 import './functional-tests/custom-code-helpers/string-array/StringArrayCodeHelper.spec';
+import './functional-tests/custom-code-helpers/string-array/templates/string-array-template/StringArrayTemplate.spec';
+import './functional-tests/custom-code-helpers/string-array/templates/string-array-calls-wrapper-node-template/StringArrayCallsWrapperNodeTemplate.spec';
+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/issues/issue321.spec';
@@ -99,12 +106,6 @@ import './functional-tests/node-transformers/preparing-transformers/variable-pre
 import './functional-tests/options/OptionsNormalizer.spec';
 import './functional-tests/options/domain-lock/Validation.spec';
 import './functional-tests/storages/string-array-storage/StringArrayStorage.spec';
-import './functional-tests/custom-code-helpers/debug-protection/templates/DebugProtectionFunctionCallTemplate.spec';
-import './functional-tests/custom-code-helpers/domain-lock/templates/DomainLockNodeTemplate.spec';
-import './functional-tests/custom-code-helpers/common/templates/GlobalVariableNoEvalTemplate.spec';
-import './functional-tests/custom-code-helpers/string-array/templates/string-array-template/StringArrayTemplate.spec';
-import './functional-tests/custom-code-helpers/string-array/templates/string-array-calls-wrapper-node-template/StringArrayCallsWrapperNodeTemplate.spec';
-import './functional-tests/custom-code-helpers/string-array/templates/string-array-rotate-function-template/StringArrayRotateFunctionTemplate.spec';
 
 /**
  * Performance tests

+ 40 - 40
test/unit-tests/generators/identifier-names-generators/DictionarylIdentifierNamesGenerator.spec.ts

@@ -12,10 +12,10 @@ import { IdentifierNamesGenerator } from '../../../../src/enums/generators/ident
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
 
 describe('DictionaryIdentifierNamesGenerator', () => {
-    describe('generateForGlobalScope', () => {
-        let identifierNamesGenerator: IIdentifierNamesGenerator,
-            dictionaryIdentifierName: string;
+    let identifierNamesGenerator: IIdentifierNamesGenerator,
+        dictionaryIdentifierName: string;
 
+    describe('generateNext', () => {
         describe('Base behaviour', () => {
             before(() => {
                 const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
@@ -33,7 +33,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                 const expectedDictionaryIdentifierNameRegExp: RegExp = /[a|b]/;
 
                 beforeEach(() => {
-                    dictionaryIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    dictionaryIdentifierName = identifierNamesGenerator.generateNext();
                 });
 
                 it('Match #1: should return first identifier name', () => {
@@ -49,7 +49,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                 const expectedDictionaryIdentifierNameRegExp: RegExp = /[A|B]/;
 
                 beforeEach(() => {
-                    dictionaryIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    dictionaryIdentifierName = identifierNamesGenerator.generateNext();
                 });
 
                 it('Match #1: should return third identifier name', () => {
@@ -79,7 +79,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                 const expectedDictionaryIdentifierNameRegExp: RegExp = /[a|A]/;
 
                 beforeEach(() => {
-                    dictionaryIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    dictionaryIdentifierName = identifierNamesGenerator.generateNext();
                 });
 
                 it('Match #1: should return first identifier name', () => {
@@ -112,7 +112,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                 const expectedFourthIterationIdentifierName: string = 'AA';
 
                 beforeEach(() => {
-                    dictionaryIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    dictionaryIdentifierName = identifierNamesGenerator.generateNext();
                 });
 
                 it('Match #1: should return first identifier name', () => {
@@ -133,37 +133,6 @@ describe('DictionaryIdentifierNamesGenerator', () => {
             });
         });
 
-        describe('Generate with prefix', () => {
-            before(() => {
-                const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
-
-                inversifyContainerFacade.load('', '', {
-                    identifiersDictionary: ['a'],
-                    identifiersPrefix: 'foo'
-                });
-                identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
-                    ServiceIdentifiers.IIdentifierNamesGenerator,
-                    IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
-                );
-            });
-
-            describe('Variant #1: Should generate identifier names with prefix', () => {
-                const expectedDictionaryIdentifierNameRegExp: RegExp = /foo[a|A]/;
-
-                beforeEach(() => {
-                    dictionaryIdentifierName = identifierNamesGenerator.generateWithPrefix();
-                });
-
-                it('Match #1: should return first identifier name', () => {
-                    assert.match(dictionaryIdentifierName, expectedDictionaryIdentifierNameRegExp);
-                });
-
-                it('Match #2: should return second identifier name', () => {
-                    assert.match(dictionaryIdentifierName, expectedDictionaryIdentifierNameRegExp);
-                });
-            });
-        });
-
         describe('Errors', () => {
             let inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
 
@@ -185,7 +154,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                         IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
                     );
 
-                    testFunc = () => identifierNamesGenerator.generateForGlobalScope();
+                    testFunc = () => identifierNamesGenerator.generateNext();
                 });
 
                 it('Match #1: should return first identifier name', () => {
@@ -215,7 +184,7 @@ describe('DictionaryIdentifierNamesGenerator', () => {
                         IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
                     );
 
-                    testFunc = () => identifierNamesGenerator.generateForGlobalScope();
+                    testFunc = () => identifierNamesGenerator.generateNext();
                 });
 
                 it('Should throw an error when identifiers dictionary is empty', () => {
@@ -224,4 +193,35 @@ describe('DictionaryIdentifierNamesGenerator', () => {
             });
         });
     });
+
+    describe('generateForGlobalScope', () => {
+        before(() => {
+            const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
+
+            inversifyContainerFacade.load('', '', {
+                identifiersDictionary: ['a'],
+                identifiersPrefix: 'foo'
+            });
+            identifierNamesGenerator = inversifyContainerFacade.getNamed<IIdentifierNamesGenerator>(
+                ServiceIdentifiers.IIdentifierNamesGenerator,
+                IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
+            );
+        });
+
+        describe('Variant #1: Should generate identifier names with prefix', () => {
+            const expectedDictionaryIdentifierNameRegExp: RegExp = /foo[a|A]/;
+
+            beforeEach(() => {
+                dictionaryIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+            });
+
+            it('Match #1: should return first identifier name', () => {
+                assert.match(dictionaryIdentifierName, expectedDictionaryIdentifierNameRegExp);
+            });
+
+            it('Match #2: should return second identifier name', () => {
+                assert.match(dictionaryIdentifierName, expectedDictionaryIdentifierNameRegExp);
+            });
+        });
+    });
 });

+ 4 - 4
test/unit-tests/generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator.spec.ts

@@ -12,7 +12,7 @@ import { IdentifierNamesGenerator } from '../../../../src/enums/generators/ident
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
 
 describe('HexadecimalIdentifierNamesGenerator', () => {
-    describe('generateForGlobalScope', () => {
+    describe('generateNext', () => {
         let identifierNamesGenerator: IIdentifierNamesGenerator,
             hexadecimalIdentifierName: string,
             regExp: RegExp;
@@ -26,7 +26,7 @@ describe('HexadecimalIdentifierNamesGenerator', () => {
                 IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
             );
 
-            hexadecimalIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+            hexadecimalIdentifierName = identifierNamesGenerator.generateNext();
             regExp = /^_0x(\w){4,6}$/;
         });
 
@@ -35,7 +35,7 @@ describe('HexadecimalIdentifierNamesGenerator', () => {
         })
     });
 
-    describe('generateWithPrefix (): string', () => {
+    describe('generateForGlobalScope', () => {
         const regExp: RegExp = /^foo_0x(\w){4,6}$/;
 
         let identifierNamesGenerator: IIdentifierNamesGenerator,
@@ -52,7 +52,7 @@ describe('HexadecimalIdentifierNamesGenerator', () => {
                 IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
             );
 
-            hexadecimalIdentifierName = identifierNamesGenerator.generateWithPrefix();
+            hexadecimalIdentifierName = identifierNamesGenerator.generateForGlobalScope();
         });
 
         it('should return hexadecimal name with prefix', () => {

+ 14 - 14
test/unit-tests/generators/identifier-names-generators/MangledlIdentifierNamesGenerator.spec.ts

@@ -12,7 +12,7 @@ import { IdentifierNamesGenerator } from '../../../../src/enums/generators/ident
 import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
 
 describe('MangledIdentifierNamesGenerator', () => {
-    describe('generateForGlobalScope', () => {
+    describe('generateNext', () => {
         let identifierNamesGenerator: IIdentifierNamesGenerator,
             mangledIdentifierName: string;
 
@@ -30,7 +30,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             const expectedMangledIdentifierName: string = 'a';
 
             beforeEach(() => {
-                mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                mangledIdentifierName = identifierNamesGenerator.generateNext();
             });
 
             it('should return mangled name', () => {
@@ -44,7 +44,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    mangledIdentifierName = identifierNamesGenerator.generateNext();
                 }
             });
 
@@ -59,7 +59,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    mangledIdentifierName = identifierNamesGenerator.generateNext();
                 }
             });
 
@@ -74,7 +74,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    mangledIdentifierName = identifierNamesGenerator.generateNext();
                 }
             });
 
@@ -89,7 +89,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    mangledIdentifierName = identifierNamesGenerator.generateNext();
                 }
             });
 
@@ -109,7 +109,7 @@ describe('MangledIdentifierNamesGenerator', () => {
 
             beforeEach(() => {
                 for (let i: number = 0; i <= expectedMangledIdentifierPosition2; i++) {
-                    mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                    mangledIdentifierName = identifierNamesGenerator.generateNext();
 
                     if (i === expectedMangledIdentifierPosition1) {
                         mangledIdentifierName1 = mangledIdentifierName;
@@ -129,7 +129,7 @@ describe('MangledIdentifierNamesGenerator', () => {
         });
     });
 
-    describe('generateWithPrefix (): string', () => {
+    describe('generateForGlobalScope', () => {
         let identifierNamesGenerator: IIdentifierNamesGenerator,
             mangledIdentifierName: string;
 
@@ -149,7 +149,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             const expectedMangledIdentifierName: string = 'fooa';
 
             beforeEach(() => {
-                mangledIdentifierName = identifierNamesGenerator.generateWithPrefix();
+                mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
             });
 
             it('should return mangled name with prefix', () => {
@@ -161,7 +161,7 @@ describe('MangledIdentifierNamesGenerator', () => {
             const expectedMangledIdentifierName: string = 'foob';
 
             beforeEach(() => {
-                mangledIdentifierName = identifierNamesGenerator.generateWithPrefix();
+                mangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
             });
 
             it('should return mangled name with prefix', () => {
@@ -189,8 +189,8 @@ describe('MangledIdentifierNamesGenerator', () => {
                     IdentifierNamesGenerator.MangledIdentifierNamesGenerator
                 );
 
-                firstMangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
-                secondMangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                firstMangledIdentifierName = identifierNamesGenerator.generateNext();
+                secondMangledIdentifierName = identifierNamesGenerator.generateNext();
             });
 
             it('should generate first identifier', () => {
@@ -220,8 +220,8 @@ describe('MangledIdentifierNamesGenerator', () => {
                     IdentifierNamesGenerator.MangledIdentifierNamesGenerator
                 );
 
-                firstMangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
-                secondMangledIdentifierName = identifierNamesGenerator.generateForGlobalScope();
+                firstMangledIdentifierName = identifierNamesGenerator.generateNext();
+                secondMangledIdentifierName = identifierNamesGenerator.generateNext();
             });
 
             it('should generate first identifier', () => {

+ 49 - 44
yarn.lock

@@ -185,10 +185,10 @@
   resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
   integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
 
-"@types/[email protected].9":
-  version "4.2.9"
-  resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.9.tgz#194332625ed2ae914aef00b8d5ca3b77e7924cc6"
-  integrity sha512-NeXgZj+MFL4izGqA4sapdYzkzQG+MtGra9vhQ58dnmDY++VgJaRUws+aLVV5zRJCYJl/8s9IjMmhiUw1WsKSmw==
+"@types/[email protected].10":
+  version "4.2.10"
+  resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.10.tgz#1122da40faabb81795580dc9f06c1e71e2ebbbe4"
+  integrity sha512-TlWWgb21+0LdkuFqEqfmy7NEgfB/7Jjux15fWQAh3P93gbmXuwTM/vxEdzW89APIcI2BgKR48yjeAkdeH+4qvQ==
 
 "@types/[email protected]":
   version "1.0.8"
@@ -276,10 +276,10 @@
   dependencies:
     "@types/node" "*"
 
-"@types/[email protected].1":
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.1.tgz#5d7ec2a789a1f77c59b7ad071b9d50bf1abbfc9e"
-  integrity sha512-L/Nw/2e5KUaprNJoRA33oly+M8X8n0K+FwLTbYqwTcR14wdPWeRkigBLfSFpN/Asf9ENZTMZwLxjtjeYucAA4Q==
+"@types/[email protected].2":
+  version "7.0.2"
+  resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce"
+  integrity sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==
 
 "@types/[email protected]":
   version "4.0.0"
@@ -331,40 +331,40 @@
   resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.1.tgz#c8e84705e08eed430b5e15b39c65b0944e4d1422"
   integrity sha512-eWN5ElDTeBc5lRDh95SqA8x18D0ll2pWudU3uWiyfsRmIZcmUXpEsxPU+7+BsdCrO2vfLRC629u/MmjbmF+2tA==
 
-"@typescript-eslint/[email protected]1.0":
-  version "2.21.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.21.0.tgz#a34de84a0791cae0357c4dda805c5b4e8203b6c6"
-  integrity sha512-b5jjjDMxzcjh/Sbjuo7WyhrQmVJg0WipTHQgXh5Xwx10uYm6nPWqN1WGOsaNq4HR3Zh4wUx4IRQdDkCHwyewyw==
+"@typescript-eslint/[email protected]2.0":
+  version "2.22.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.22.0.tgz#218ce6d4aa0244c6a40baba39ca1e021b26bb017"
+  integrity sha512-BvxRLaTDVQ3N+Qq8BivLiE9akQLAOUfxNHIEhedOcg8B2+jY8Rc4/D+iVprvuMX1AdezFYautuGDwr9QxqSxBQ==
   dependencies:
-    "@typescript-eslint/experimental-utils" "2.21.0"
+    "@typescript-eslint/experimental-utils" "2.22.0"
     eslint-utils "^1.4.3"
     functional-red-black-tree "^1.0.1"
     regexpp "^3.0.0"
     tsutils "^3.17.1"
 
-"@typescript-eslint/[email protected]1.0":
-  version "2.21.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.21.0.tgz#71de390a3ec00b280b69138d80733406e6e86bfa"
-  integrity sha512-olKw9JP/XUkav4lq0I7S1mhGgONJF9rHNhKFn9wJlpfRVjNo3PPjSvybxEldvCXnvD+WAshSzqH5cEjPp9CsBA==
+"@typescript-eslint/[email protected]2.0":
+  version "2.22.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.22.0.tgz#4d00c91fbaaa68e56e7869be284999a265707f85"
+  integrity sha512-sJt1GYBe6yC0dWOQzXlp+tiuGglNhJC9eXZeC8GBVH98Zv9jtatccuhz0OF5kC/DwChqsNfghHx7OlIDQjNYAQ==
   dependencies:
     "@types/json-schema" "^7.0.3"
-    "@typescript-eslint/typescript-estree" "2.21.0"
+    "@typescript-eslint/typescript-estree" "2.22.0"
     eslint-scope "^5.0.0"
 
-"@typescript-eslint/[email protected]1.0":
-  version "2.21.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.21.0.tgz#4f200995517c3d5fc5ef51b17527bc948992e438"
-  integrity sha512-VrmbdrrrvvI6cPPOG7uOgGUFXNYTiSbnRq8ZMyuGa4+qmXJXVLEEz78hKuqupvkpwJQNk1Ucz1TenrRP90gmBg==
+"@typescript-eslint/[email protected]2.0":
+  version "2.22.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.22.0.tgz#8eeb6cb6de873f655e64153397d4790898e149d0"
+  integrity sha512-FaZKC1X+nvD7qMPqKFUYHz3H0TAioSVFGvG29f796Nc5tBluoqfHgLbSFKsh7mKjRoeTm8J9WX2Wo9EyZWjG7w==
   dependencies:
     "@types/eslint-visitor-keys" "^1.0.0"
-    "@typescript-eslint/experimental-utils" "2.21.0"
-    "@typescript-eslint/typescript-estree" "2.21.0"
+    "@typescript-eslint/experimental-utils" "2.22.0"
+    "@typescript-eslint/typescript-estree" "2.22.0"
     eslint-visitor-keys "^1.1.0"
 
-"@typescript-eslint/[email protected]1.0":
-  version "2.21.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.21.0.tgz#7e4be29f2e338195a2e8c818949ed0ff727cc943"
-  integrity sha512-NC/nogZNb9IK2MEFQqyDBAciOT8Lp8O3KgAfvHx2Skx6WBo+KmDqlU3R9KxHONaijfTIKtojRe3SZQyMjr3wBw==
+"@typescript-eslint/[email protected]2.0":
+  version "2.22.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.22.0.tgz#a16ed45876abf743e1f5857e2f4a1c3199fd219e"
+  integrity sha512-2HFZW2FQc4MhIBB8WhDm9lVFaBDy6h9jGrJ4V2Uzxe/ON29HCHBTj3GkgcsgMWfsl2U5as+pTOr30Nibaw7qRQ==
   dependencies:
     debug "^4.1.1"
     eslint-visitor-keys "^1.1.0"
@@ -540,16 +540,21 @@ acorn-jsx@^5.1.0:
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384"
   integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==
 
[email protected].0, acorn@^7.1.0:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
-  integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
[email protected]:
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
+  integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
 
 acorn@^6.2.1:
   version "6.4.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784"
   integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==
 
+acorn@^7.1.0:
+  version "7.1.0"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
+  integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
+
 aggregate-error@^3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0"
@@ -1776,10 +1781,10 @@ [email protected]:
     read-pkg-up "^2.0.0"
     resolve "^1.12.0"
 
-eslint-plugin-jsdoc@21.0.0:
-  version "21.0.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-21.0.0.tgz#36bc215c5d22b320312a633dda6dfe81c34393af"
-  integrity sha512-CdLGe2oyw5YAX9rxq9bVz7H2PK+r8PVwdGuvYGMBstpbVD/66yUAgRFQRsJwAsRKLmReo58Lw1jFdNcxdOc4eg==
+eslint-plugin-jsdoc@22.0.0:
+  version "22.0.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-22.0.0.tgz#371f1dbf4f61ee6e11c23fa1ea3275962f1bceaf"
+  integrity sha512-dLqUtIL6tvOoV+9IDdP3FqOnQ/sxklzs4hxZa91kt0TGI2o1fSqIuc6wa71oWtWKEyvaQj7m6CnzQxcBC9CEsg==
   dependencies:
     comment-parser "^0.7.2"
     debug "^4.1.1"
@@ -5229,10 +5234,10 @@ typedarray@^0.0.6:
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
[email protected].2:
-  version "3.8.2"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.2.tgz#91d6868aaead7da74f493c553aeff76c0c0b1d5a"
-  integrity sha512-EgOVgL/4xfVrCMbhYKUQTdF37SQn4Iw73H5BgCrF1Abdun7Kwy/QZsE/ssAy0y4LxBbvua3PIbFsbRczWWnDdQ==
[email protected].3:
+  version "3.8.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
+  integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
 
 union-value@^1.0.0:
   version "1.0.1"
@@ -5396,10 +5401,10 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1:
     source-list-map "^2.0.0"
     source-map "~0.6.1"
 
[email protected]1.6:
-  version "4.41.6"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.6.tgz#12f2f804bf6542ef166755050d4afbc8f66ba7e1"
-  integrity sha512-yxXfV0Zv9WMGRD+QexkZzmGIh54bsvEs+9aRWxnN8erLWEOehAKUTeNBoUbA6HPEZPlRo7KDi2ZcNveoZgK9MA==
[email protected]2.0:
+  version "4.42.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.0.tgz#b901635dd6179391d90740a63c93f76f39883eb8"
+  integrity sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==
   dependencies:
     "@webassemblyjs/ast" "1.8.5"
     "@webassemblyjs/helper-module-context" "1.8.5"

部分文件因为文件数量过多而无法显示