mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge pull request #144 from javascript-obfuscator/comments-transformer
Keep comments with specific keywords
This commit is contained in:
+2
-1
@@ -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
|
||||
---
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javascript-obfuscator",
|
||||
"version": "0.13.0-dev.2",
|
||||
"version": "0.13.0-dev.3",
|
||||
"description": "JavaScript obfuscator",
|
||||
"keywords": [
|
||||
"obfuscator",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,6 +1,7 @@
|
||||
export enum NodeTransformer {
|
||||
BlockStatementControlFlowTransformer,
|
||||
ClassDeclarationTransformer,
|
||||
CommentsTransformer,
|
||||
DeadCodeInjectionTransformer,
|
||||
FunctionControlFlowTransformer,
|
||||
CatchClauseTransformer,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
@@ -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,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,0 +1,3 @@
|
||||
// test comment
|
||||
// @license test comment
|
||||
var test = 1;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @license
|
||||
* test
|
||||
*/
|
||||
// test
|
||||
//abc
|
||||
var test = 1;
|
||||
//cde
|
||||
//javascript-obfuscator
|
||||
/** @preserved */
|
||||
+1
@@ -0,0 +1 @@
|
||||
// test comment
|
||||
+1
@@ -0,0 +1 @@
|
||||
// @license
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
// test comment
|
||||
var test = 1;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
// @license test comment
|
||||
var test = 1;
|
||||
+3
-2
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user