소스 검색

Merge pull request #144 from javascript-obfuscator/comments-transformer

Keep comments with specific keywords
Timofey Kachalov 7 년 전
부모
커밋
7bf1f84f2b
24개의 변경된 파일284개의 추가작업 그리고 5개의 파일을 삭제
  1. 2 1
      CHANGELOG.md
  2. 0 0
      dist/index.js
  3. 1 1
      package.json
  4. 7 1
      src/JavaScriptObfuscator.ts
  5. 5 0
      src/container/modules/node-transformers/PreparingTransformersModule.ts
  6. 1 0
      src/enums/node-transformers/NodeTransformer.ts
  7. 85 0
      src/node-transformers/preparing-transformers/CommentsTransformer.ts
  8. 8 0
      src/node/NodeGuards.ts
  9. 4 0
      test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  10. 149 0
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec.ts
  11. 3 0
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/combined-words-1.js
  12. 10 0
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/combined-words-2.js
  13. 1 0
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/comments-only-1.js
  14. 1 0
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/comments-only-2.js
  15. 2 0
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/no-preserved-words.js
  16. 2 0
      test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/preserved-words.js
  17. 0 0
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec.ts
  18. 0 0
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/fixtures/use-strict-operator.js
  19. 0 0
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec.ts
  20. 0 0
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/dead-code-injection.js
  21. 0 0
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/disable-and-enable-comments.js
  22. 0 0
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/disable-from-beginning.js
  23. 0 0
      test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/simple.js
  24. 3 2
      test/index.spec.ts

+ 2 - 1
CHANGELOG.md

@@ -4,8 +4,9 @@ v0.13.0
 ---
 * **Breaking change:** `mangle` option was removed.
 * **New option:** `identifierNamesGenerator` allows to set identifier names generator (`hexadecimal` or `mangled`).
-* **Breaking change:** all CLI options were renamed to `kebab-case` format (`--disableConsoleOutout` -> `--disable-console-output`)
+* **Breaking change:** all CLI options were renamed to `kebab-case` format (`--disableConsoleOutout` -> `--disable-console-output`).
 * Implemented custom `mangle` option algorithm without `esmangle`; fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/110
+* Comments with `@license`, `@preserve` and `javascript-obfuscator` words won't be removed from obfuscated code.
 
 v0.12.5
 ---

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
dist/index.js


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.13.0-dev.2",
+  "version": "0.13.0-dev.3",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",

+ 7 - 1
src/JavaScriptObfuscator.ts

@@ -32,6 +32,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
      * @type {GenerateOptions}
      */
     private static readonly escodegenParams: escodegen.GenerateOptions = {
+        comment: true,
         verbatim: 'x-verbatim-property',
         sourceMapWithCode: true
     };
@@ -78,6 +79,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
      * @type {NodeTransformer[]}
      */
     private static readonly preparingTransformersList: NodeTransformer[] = [
+        NodeTransformer.CommentsTransformer,
         NodeTransformer.ObfuscatingGuardsTransformer,
         NodeTransformer.ParentificationTransformer
     ];
@@ -193,7 +195,11 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
      * @returns {Program}
      */
     private transformAstTree (astTree: ESTree.Program): ESTree.Program {
-        if (NodeGuards.isProgramNode(astTree) && !astTree.body.length) {
+        const isEmptyAstTree: boolean = NodeGuards.isProgramNode(astTree)
+            && !astTree.body.length
+            && !astTree.leadingComments;
+
+        if (isEmptyAstTree) {
             this.logger.warn(LoggingMessage.EmptySourceCode);
 
             return astTree;

+ 5 - 0
src/container/modules/node-transformers/PreparingTransformersModule.ts

@@ -9,12 +9,17 @@ import { NodeTransformer } from '../../../enums/node-transformers/NodeTransforme
 import { ObfuscatingGuard } from '../../../enums/node-transformers/preparing-transformers/obfuscating-guards/ObfuscatingGuard';
 
 import { BlackListObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/BlackListObfuscatingGuard';
+import { CommentsTransformer } from '../../../node-transformers/preparing-transformers/CommentsTransformer';
 import { ConditionalCommentObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/ConditionalCommentObfuscatingGuard';
 import { ObfuscatingGuardsTransformer } from '../../../node-transformers/preparing-transformers/ObfuscatingGuardsTransformer';
 import { ParentificationTransformer } from '../../../node-transformers/preparing-transformers/ParentificationTransformer';
 
 export const preparingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
     // preparing transformers
+    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
+        .to(CommentsTransformer)
+        .whenTargetNamed(NodeTransformer.CommentsTransformer);
+
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(ObfuscatingGuardsTransformer)
         .whenTargetNamed(NodeTransformer.ObfuscatingGuardsTransformer);

+ 1 - 0
src/enums/node-transformers/NodeTransformer.ts

@@ -1,6 +1,7 @@
 export enum NodeTransformer {
     BlockStatementControlFlowTransformer,
     ClassDeclarationTransformer,
+    CommentsTransformer,
     DeadCodeInjectionTransformer,
     FunctionControlFlowTransformer,
     CatchClauseTransformer,

+ 85 - 0
src/node-transformers/preparing-transformers/CommentsTransformer.ts

@@ -0,0 +1,85 @@
+import { inject, injectable, } from 'inversify';
+import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
+
+import * as ESTree from 'estree';
+
+import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
+
+import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
+import { NodeGuards } from '../../node/NodeGuards';
+
+@injectable()
+export class CommentsTransformer extends AbstractNodeTransformer {
+    /**
+     * @type {string[]}
+     */
+    private static preservedWords: string[] = ['@license', '@preserve', 'javascript-obfuscator'];
+
+    /**
+     * @param {IRandomGenerator} randomGenerator
+     * @param {IOptions} options
+     */
+    constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        super(randomGenerator, options);
+    }
+
+    /**
+     * @return {IVisitor}
+     */
+    public getVisitor (): IVisitor {
+        return {
+            enter: (node: ESTree.Node, parentNode: ESTree.Node | null) => {
+                if (parentNode && NodeGuards.isNodeWithComments(node)) {
+                    return this.transformNode(node, parentNode);
+                }
+            }
+        };
+    }
+
+    /**
+     * Removes all comments from node except comments that contain
+     * `@license`, `@preserve` or `javascript-obfuscator` words
+     *
+     * @param {Node} node
+     * @param {Node} parentNode
+     * @returns {NodeGuards}
+     */
+    public transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node {
+        if (node.leadingComments) {
+            node.leadingComments = this.transformComments(node.leadingComments);
+        }
+
+        if (node.trailingComments) {
+            node.trailingComments = this.transformComments(node.trailingComments);
+        }
+
+        return node;
+    }
+
+    /**
+     * @param {Comment[]} comments
+     * @returns {Comment[]}
+     */
+    private transformComments (comments: ESTree.Comment[]): ESTree.Comment[] {
+        let i: number = comments.length;
+
+        while (i--) {
+            const comment: ESTree.Comment = comments[i];
+            const commentHasPreservedWords: boolean = CommentsTransformer.preservedWords
+                .some((availableWord: string) => comment.value.includes(availableWord));
+
+            if (commentHasPreservedWords) {
+                continue;
+            }
+
+            comments.splice(i, 1);
+        }
+
+        return comments;
+    }
+}

+ 8 - 0
src/node/NodeGuards.ts

@@ -178,6 +178,14 @@ export class NodeGuards {
         return Array.isArray((<TNodeWithBlockStatement>node).body);
     }
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isNodeWithComments (node: ESTree.Node): node is ESTree.Node {
+        return Boolean(node.leadingComments) || Boolean(node.trailingComments);
+    }
+
     /**
      * @param {Node} node
      * @returns {boolean}

+ 4 - 0
test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts

@@ -67,6 +67,10 @@ describe('JavaScriptObfuscator', () => {
                 const code: string = readFileAsString(__dirname + '/fixtures/comments-only.js');
                 const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
                     code,
+                    {
+                        controlFlowFlattening: true,
+                        deadCodeInjection: true
+                    }
                 );
 
                 obfuscatedCode = obfuscationResult.getObfuscatedCode();

+ 149 - 0
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec.ts

@@ -0,0 +1,149 @@
+import { assert } from 'chai';
+
+import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult';
+
+import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
+
+import { readFileAsString } from '../../../../helpers/readFileAsString';
+
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
+
+describe('CommentsTransformer', () => {
+    describe('variant #1: simple comment without preserved words', () => {
+        const regExp: RegExp = /^var *test *= *0x1;$/;
+
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/no-preserved-words.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        });
+
+        it('should remove comments without preserved words', () => {
+            assert.match(obfuscatedCode, regExp);
+        });
+    });
+
+    describe('variant #2: simple comment with preserved words', () => {
+        const regExp: RegExp = /^\/\/ *@license *test *comment *\n*var *test *= *0x1;$/;
+
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/preserved-words.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        });
+
+        it('should keep comments with preserved words', () => {
+            assert.match(obfuscatedCode, regExp);
+        });
+    });
+
+    describe('variant #3: comment with preserved and non-preserved words', () => {
+        const regExp: RegExp = /^\/\/ *@license *test *comment *\n*var *test *= *0x1;$/;
+
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/combined-words-1.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        });
+
+        it('should keep comments with preserved words', () => {
+            assert.match(obfuscatedCode, regExp);
+        });
+    });
+
+    describe('variant #4: comment with preserved and non-preserved words', () => {
+        const regExp: RegExp = new RegExp(``+
+            `^\\/\\*\\* *\\n` +
+            ` *\\* *@license *\\n` +
+            ` *\\* *test\\n` +
+            ` *\\*\\/\\n` +
+            `var *test *= *0x1;` +
+            `\\/\\/javascript-obfuscator\\n` +
+            ` *\\/\\*\\* *@preserved *\\*\\/$` +
+        ``);
+
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/combined-words-2.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        });
+
+        it('should keep comments with preserved words', () => {
+            assert.match(obfuscatedCode, regExp);
+        });
+    });
+
+    describe('variant #5: only comment without preserved words', () => {
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/comments-only-1.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        });
+
+        it('should remove comment without preserved words', () => {
+            assert.isNotOk(obfuscatedCode);
+        });
+    });
+
+    describe('variant #5: only comment with preserved words', () => {
+        const regExp: RegExp = /^\/\/ *@license$/;
+
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/comments-only-2.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        });
+
+        it('should keep comments with preserved words', () => {
+            assert.match(obfuscatedCode, regExp);
+        });
+    });
+});

+ 3 - 0
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/combined-words-1.js

@@ -0,0 +1,3 @@
+// test comment
+// @license test comment
+var test = 1;

+ 10 - 0
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/combined-words-2.js

@@ -0,0 +1,10 @@
+/**
+ * @license
+ * test
+ */
+// test
+//abc
+var test = 1;
+//cde
+//javascript-obfuscator
+/** @preserved */

+ 1 - 0
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/comments-only-1.js

@@ -0,0 +1 @@
+// test comment

+ 1 - 0
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/comments-only-2.js

@@ -0,0 +1 @@
+// @license

+ 2 - 0
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/no-preserved-words.js

@@ -0,0 +1,2 @@
+// test comment
+var test = 1;

+ 2 - 0
test/functional-tests/node-transformers/preparing-transformers/comments-transformer/fixtures/preserved-words.js

@@ -0,0 +1,2 @@
+// @license test comment
+var test = 1;

+ 0 - 0
test/functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec.ts → test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec.ts


+ 0 - 0
test/functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/black-list-obfuscating-guard/fixtures/use-strict-operator.js → test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/fixtures/use-strict-operator.js


+ 0 - 0
test/functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec.ts → test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec.ts


+ 0 - 0
test/functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/dead-code-injection.js → test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/dead-code-injection.js


+ 0 - 0
test/functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/disable-and-enable-comments.js → test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/disable-and-enable-comments.js


+ 0 - 0
test/functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/disable-from-beginning.js → test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/disable-from-beginning.js


+ 0 - 0
test/functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/simple.js → test/functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/fixtures/simple.js


+ 3 - 2
test/index.spec.ts

@@ -61,8 +61,9 @@ import './functional-tests/node-transformers/obfuscating-transformers/labeled-st
 import './functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/object-expression-transformer/ObjectExpressionTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec';
-import './functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec';
-import './functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
+import './functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec';
+import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec';
+import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
 import './functional-tests/templates/custom-nodes/debug-protection-nodes/DebufProtectionFunctionCallTemplate.spec';
 import './functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec';
 import './functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec';

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.