Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,10 @@ jobs:
node-version: 12.x
- os: ubuntu-latest,
node-version: 14.x
- os: ubuntu-latest,
node-version: 15.x
- os: ubuntu-latest,
node-version: 16.x
- os: windows-latest,
node-version: 14.x
- os: windows-latest,
node-version: 15.x
- os: windows-latest,
node-version: 16.x

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ npm-debug.log
/tmp
/test/benchmark/**/**
*dockerfile
/test*.js
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
Change Log

v2.18.0
---
* Added support of `es2022` features: private identifiers and class properties
* Dropped support for `node@15`.
* Increased minimum supported `node` versions: `^12.22.0 || ^14.17.0 || >=16.0.0`

v2.17.0
---
* **New option**: `sourceMapSourcesMode` allows to control `sources` and `sourcesContent` fields of the source map
Expand Down
2 changes: 1 addition & 1 deletion dist/index.browser.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.cli.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "2.17.0",
"version": "2.18.0",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand All @@ -12,7 +12,7 @@
"js obfuscator"
],
"engines": {
"node": ">=12"
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"main": "dist/index.js",
"browser": "dist/index.browser.js",
Expand All @@ -30,7 +30,7 @@
"chance": "1.1.7",
"class-validator": "0.13.1",
"commander": "8.0.0",
"eslint-scope": "5.1.1",
"eslint-scope": "6.0.0",
"fast-deep-equal": "3.1.3",
"inversify": "5.1.1",
"js-string-escape": "1.0.1",
Expand All @@ -55,9 +55,9 @@
"@types/js-string-escape": "1.0.0",
"@types/md5": "2.3.1",
"@types/mkdirp": "1.0.2",
"@types/mocha": "8.2.3",
"@types/mocha": "9.0.0",
"@types/multimatch": "4.0.0",
"@types/node": "16.3.3",
"@types/node": "16.4.1",
"@types/rimraf": "3.0.1",
"@types/sinon": "10.0.2",
"@types/string-template": "1.0.2",
Expand All @@ -69,7 +69,7 @@
"cross-env": "7.0.3",
"eslint": "7.31.0",
"eslint-plugin-import": "2.23.4",
"eslint-plugin-jsdoc": "35.4.5",
"eslint-plugin-jsdoc": "35.5.1",
"eslint-plugin-no-null": "1.0.2",
"eslint-plugin-prefer-arrow": "1.2.3",
"eslint-plugin-unicorn": "34.0.1",
Expand All @@ -85,8 +85,8 @@
"threads": "1.6.5",
"ts-loader": "9.2.3",
"ts-node": "10.1.0",
"typescript": "4.3.5",
"webpack": "5.45.1",
"typescript": "4.4.0-beta",
"webpack": "5.46.0",
"webpack-cli": "4.7.2",
"webpack-node-externals": "3.0.0"
},
Expand Down
4 changes: 3 additions & 1 deletion src/ASTParserFacade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ export class ASTParserFacade {
errorMessage: string,
position: ESTree.Position | null
): never {
if (!position || !position.line || !position.column) {
const isMissingLocationData = !position || !position.line || !position.column;

if (isMissingLocationData) {
throw new Error(errorMessage);
}

Expand Down
2 changes: 1 addition & 1 deletion src/JavaScriptObfuscator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
NodeTransformer.BooleanLiteralTransformer,
NodeTransformer.BlockStatementControlFlowTransformer,
NodeTransformer.BlockStatementSimplifyTransformer,
NodeTransformer.ClassFieldTransformer,
NodeTransformer.CommentsTransformer,
NodeTransformer.CustomCodeHelpersTransformer,
NodeTransformer.DeadCodeInjectionTransformer,
Expand All @@ -79,7 +80,6 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
NodeTransformer.RenamePropertiesTransformer,
NodeTransformer.MemberExpressionTransformer,
NodeTransformer.MetadataTransformer,
NodeTransformer.MethodDefinitionTransformer,
NodeTransformer.NumberLiteralTransformer,
NodeTransformer.NumberToNumericalExpressionTransformer,
NodeTransformer.ObfuscatingGuardsTransformer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { BasePropertiesExtractor } from '../../../node-transformers/converting-t
import { BooleanLiteralTransformer } from '../../../node-transformers/converting-transformers/BooleanLiteralTransformer';
import { ExportSpecifierTransformer } from '../../../node-transformers/converting-transformers/ExportSpecifierTransformer';
import { MemberExpressionTransformer } from '../../../node-transformers/converting-transformers/MemberExpressionTransformer';
import { MethodDefinitionTransformer } from '../../../node-transformers/converting-transformers/MethodDefinitionTransformer';
import { ClassFieldTransformer } from '../../../node-transformers/converting-transformers/ClassFieldTransformer';
import { NumberLiteralTransformer } from '../../../node-transformers/converting-transformers/NumberLiteralTransformer';
import { NumberToNumericalExpressionTransformer } from '../../../node-transformers/converting-transformers/NumberToNumericalExpressionTransformer';
import { ObjectExpressionKeysTransformer } from '../../../node-transformers/converting-transformers/ObjectExpressionKeysTransformer';
Expand All @@ -37,8 +37,8 @@ export const convertingTransformersModule: interfaces.ContainerModule = new Cont
.whenTargetNamed(NodeTransformer.MemberExpressionTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(MethodDefinitionTransformer)
.whenTargetNamed(NodeTransformer.MethodDefinitionTransformer);
.to(ClassFieldTransformer)
.whenTargetNamed(NodeTransformer.ClassFieldTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(NumberLiteralTransformer)
Expand Down
3 changes: 2 additions & 1 deletion src/decorators/Initializable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ const initializeMethodName: 'initialize' = 'initialize';
export function initializable (): (target: IInitializable, propertyKey: string | symbol) => any {
return (target: IInitializable, propertyKey: string | symbol): PropertyDescriptor => {
const initializeMethod: Function = target[initializeMethodName];
const isInvalidInitializeMethod = !initializeMethod || typeof initializeMethod !== 'function';

if (!initializeMethod || typeof initializeMethod !== 'function') {
if (isInvalidInitializeMethod) {
throw new Error(`\`${initializeMethodName}\` method with initialization logic not ` +
`found. \`@${decoratorName}\` decorator requires \`${initializeMethodName}\` method`);
}
Expand Down
2 changes: 1 addition & 1 deletion src/enums/node-transformers/NodeTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export enum NodeTransformer {
BooleanLiteralTransformer = 'BooleanLiteralTransformer',
BlockStatementControlFlowTransformer = 'BlockStatementControlFlowTransformer',
BlockStatementSimplifyTransformer = 'BlockStatementSimplifyTransformer',
ClassFieldTransformer = 'ClassFieldTransformer',
CommentsTransformer = 'CommentsTransformer',
CustomCodeHelpersTransformer = 'CustomCodeHelpersTransformer',
DeadCodeInjectionIdentifiersTransformer = 'DeadCodeInjectionIdentifiersTransformer',
Expand All @@ -16,7 +17,6 @@ export enum NodeTransformer {
LabeledStatementTransformer = 'LabeledStatementTransformer',
MemberExpressionTransformer = 'MemberExpressionTransformer',
MetadataTransformer = 'MetadataTransformer',
MethodDefinitionTransformer = 'MethodDefinitionTransformer',
NumberLiteralTransformer = 'NumberLiteralTransformer',
NumberToNumericalExpressionTransformer = 'NumberToNumericalExpressionTransformer',
ObfuscatingGuardsTransformer = 'ObfuscatingGuardsTransformer',
Expand Down
2 changes: 2 additions & 0 deletions src/enums/node/NodeType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum NodeType {
CallExpression = 'CallExpression',
CatchClause = 'CatchClause',
ChainExpression = 'ChainExpression',
ClassBody = 'ClassBody',
ClassDeclaration = 'ClassDeclaration',
ConditionalExpression = 'ConditionalExpression',
ContinueStatement = 'ContinueStatement',
Expand Down Expand Up @@ -40,6 +41,7 @@ export enum NodeType {
ObjectPattern = 'ObjectPattern',
Program = 'Program',
Property = 'Property',
PropertyDefinition = 'PropertyDefinition',
RestElement = 'RestElement',
ReturnStatement = 'ReturnStatement',
SequenceExpression = 'SequenceExpression',
Expand Down
3 changes: 2 additions & 1 deletion src/node-transformers/NodeTransformersRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,9 @@ export class NodeTransformersRunner implements INodeTransformersRunner {
}

const visitorResult: TVisitorResult = visitorFunction(node, parentNode);
const isValidVisitorResult = visitorResult && NodeGuards.isNode(visitorResult);

if (!visitorResult || !NodeGuards.isNode(visitorResult)) {
if (!isValidVisitorResult) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ import { NodeGuards } from '../../node/NodeGuards';
/**
* replaces:
* foo () { //... };
* foo = 1;
*
* or
* 'foo' () { //... };
* 'foo' = 1;
*
* on:
* ['foo'] { //... };
* ['foo'] () { //... };
* ['foo'] = 1;
*
* Literal node will be obfuscated by LiteralTransformer
*/
@injectable()
export class MethodDefinitionTransformer extends AbstractNodeTransformer {
export class ClassFieldTransformer extends AbstractNodeTransformer {
/**
* @type {string[]}
*/
Expand All @@ -52,7 +55,13 @@ export class MethodDefinitionTransformer extends AbstractNodeTransformer {
case NodeTransformationStage.Converting:
return {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node | undefined => {
if (parentNode && NodeGuards.isMethodDefinitionNode(node)) {
if (
parentNode
&& (
NodeGuards.isMethodDefinitionNode(node)
|| NodeGuards.isPropertyDefinitionNode(node)
)
) {
return this.transformNode(node, parentNode);
}
}
Expand All @@ -64,69 +73,62 @@ export class MethodDefinitionTransformer extends AbstractNodeTransformer {
}

/**
* replaces:
* object.identifier = 1;
*
* on:
* object['identifier'] = 1;
*
* and skip:
* object[identifier] = 1;
* Literal node will be obfuscated by LiteralTransformer
*
* @param {MethodDefinition} methodDefinitionNode
* @param {MethodDefinition | PropertyDefinition} classFieldNode
* @param {NodeGuards} parentNode
* @returns {NodeGuards}
*/
public transformNode (methodDefinitionNode: ESTree.MethodDefinition, parentNode: ESTree.Node): ESTree.Node {
if (NodeGuards.isIdentifierNode(methodDefinitionNode.key)) {
return this.replaceIdentifierKey(methodDefinitionNode, methodDefinitionNode.key);
public transformNode (
classFieldNode: ESTree.MethodDefinition | ESTree.PropertyDefinition,
parentNode: ESTree.Node
): ESTree.Node {
if (NodeGuards.isIdentifierNode(classFieldNode.key)) {
return this.replaceIdentifierKey(classFieldNode, classFieldNode.key);
}

if (NodeGuards.isLiteralNode(methodDefinitionNode.key)) {
return this.replaceLiteralKey(methodDefinitionNode, methodDefinitionNode.key);
if (NodeGuards.isLiteralNode(classFieldNode.key)) {
return this.replaceLiteralKey(classFieldNode, classFieldNode.key);
}

return methodDefinitionNode;
return classFieldNode;
}

/**
* @param {MethodDefinition} methodDefinitionNode
* @param {MethodDefinition | PropertyDefinition} classFieldNode
* @param {Identifier} keyNode
* @returns {MethodDefinition}
* @returns {MethodDefinition | PropertyDefinition}
*/
private replaceIdentifierKey (
methodDefinitionNode: ESTree.MethodDefinition,
classFieldNode: ESTree.MethodDefinition | ESTree.PropertyDefinition,
keyNode: ESTree.Identifier
): ESTree.MethodDefinition {
): ESTree.MethodDefinition | ESTree.PropertyDefinition {
if (
!MethodDefinitionTransformer.ignoredNames.includes(keyNode.name)
&& !methodDefinitionNode.computed
!ClassFieldTransformer.ignoredNames.includes(keyNode.name)
&& !classFieldNode.computed
) {
methodDefinitionNode.computed = true;
methodDefinitionNode.key = NodeFactory.literalNode(keyNode.name);
classFieldNode.computed = true;
classFieldNode.key = NodeFactory.literalNode(keyNode.name);
}

return methodDefinitionNode;
return classFieldNode;
}

/**
* @param {MethodDefinition} methodDefinitionNode
* @param {MethodDefinition | PropertyDefinition} classFieldNode
* @param {Literal} keyNode
* @returns {MethodDefinition}
* @returns {MethodDefinition | PropertyDefinition}
*/
private replaceLiteralKey (
methodDefinitionNode: ESTree.MethodDefinition,
classFieldNode: ESTree.MethodDefinition | ESTree.PropertyDefinition,
keyNode: ESTree.Literal
): ESTree.MethodDefinition {
): ESTree.MethodDefinition | ESTree.PropertyDefinition {
if (
typeof keyNode.value === 'string'
&& !MethodDefinitionTransformer.ignoredNames.includes(keyNode.value)
&& !methodDefinitionNode.computed
&& !ClassFieldTransformer.ignoredNames.includes(keyNode.value)
&& !classFieldNode.computed
) {
methodDefinitionNode.computed = true;
classFieldNode.computed = true;
}

return methodDefinitionNode;
return classFieldNode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
* @returns {boolean}
*/
private static isValidPropertyNode<
TNode extends ESTree.Property | ESTree.MemberExpression | ESTree.MethodDefinition
TNode extends ESTree.Property
| ESTree.PropertyDefinition
| ESTree.MemberExpression
| ESTree.MethodDefinition
> (
propertyNode: TNode,
propertyKeyNode: ESTree.Expression | ESTree.PrivateIdentifier
Expand Down Expand Up @@ -107,6 +110,10 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
return this.transformPropertyNode(node);
}

if (NodeGuards.isPropertyDefinitionNode(node)) {
return this.transformPropertyDefinitionNode(node);
}

if (NodeGuards.isMemberExpressionNode(node)) {
return this.transformMemberExpressionNode(node);
}
Expand All @@ -133,6 +140,20 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
return propertyNode;
}

/**
* @param {PropertyDefinition} propertyNode
* @returns {PropertyDefinition}
*/
private transformPropertyDefinitionNode (propertyNode: ESTree.PropertyDefinition): ESTree.PropertyDefinition {
const propertyKeyNode: ESTree.Expression | ESTree.PrivateIdentifier = propertyNode.key;

if (RenamePropertiesTransformer.isValidPropertyNode(propertyNode, propertyKeyNode)) {
propertyNode.key = this.renamePropertiesReplacer.replace(propertyKeyNode);
}

return propertyNode;
}

/**
* @param {Property} memberExpressionNode
* @returns {Property}
Expand Down Expand Up @@ -165,6 +186,7 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
* @param {Node} node
* @param {Node} parentNode
*/
// eslint-disable-next-line complexity
private analyzeAutoExcludedPropertyNames (
node: ESTree.Node,
parentNode: ESTree.Node
Expand All @@ -177,6 +199,7 @@ export class RenamePropertiesTransformer extends AbstractNodeTransformer {
(NodeGuards.isPropertyNode(parentNode) && parentNode.key === node)
|| NodeGuards.isMemberExpressionNode(parentNode) && parentNode.property === node
|| NodeGuards.isMethodDefinitionNode(parentNode) && parentNode.key === node
|| NodeGuards.isPropertyDefinitionNode(parentNode) && parentNode.key === node
) {
return;
}
Expand Down
Loading