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: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Change Log

v2.2.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/745

v2.2.0
---
* **New option (enabled by default):** `stringArrayWrappersCount` sets the count of wrappers for the `string array` inside each root or function scope
Expand Down
8 changes: 4 additions & 4 deletions 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.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "2.2.0",
"version": "2.2.1",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { TNodeWithLexicalScope } from '../../../types/node/TNodeWithLexicalScope';
import { TNodeWithLexicalScopeStatements } from '../../../types/node/TNodeWithLexicalScopeStatements';
import { TStringArrayScopeCallsWrapperDataByEncoding } from '../../../types/node-transformers/string-array-transformers/TStringArrayScopeCallsWrapperDataByEncoding';

import { IMapStorage } from '../IMapStorage';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IStringArrayScopeCallsWrapperDataStorage extends IMapStorage<
TNodeWithLexicalScope,
TNodeWithLexicalScopeStatements,
TStringArrayScopeCallsWrapperDataByEncoding
> {}
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { TNodeWithLexicalScopeAndStatements } from '../../../types/node/TNodeWithLexicalScopeAndStatements';
import { TNodeWithLexicalScopeStatements } from '../../../types/node/TNodeWithLexicalScopeStatements';

import { IArrayStorage } from '../IArrayStorage';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IVisitedLexicalScopeNodesStackStorage extends IArrayStorage<TNodeWithLexicalScopeAndStatements> {
export interface IVisitedLexicalScopeNodesStackStorage extends IArrayStorage<TNodeWithLexicalScopeStatements> {
/**
* @returns {TNodeWithLexicalScopeAndStatements | undefined}
* @returns {TNodeWithLexicalScopeStatements | undefined}
*/
getLastElement (): TNodeWithLexicalScopeAndStatements | undefined;
getLastElement (): TNodeWithLexicalScopeStatements | undefined;

/**
* @returns {TNodeWithLexicalScopeAndStatements | undefined}
* @returns {TNodeWithLexicalScopeStatements | undefined}
*/
pop (): TNodeWithLexicalScopeAndStatements | undefined;
pop (): TNodeWithLexicalScopeStatements | undefined;

/**
* @param {TNodeWithLexicalScopeAndStatements} lexicalScopeNode
* @param {TNodeWithLexicalScopeStatements} lexicalScopeBodyNode
*/
push (lexicalScopeNode: TNodeWithLexicalScopeAndStatements): void;
push (lexicalScopeBodyNode: TNodeWithLexicalScopeStatements): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as ESTree from 'estree';

import { TInitialData } from '../../types/TInitialData';
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
import { TNodeWithLexicalScopeAndStatements } from '../../types/node/TNodeWithLexicalScopeAndStatements';
import { TNodeWithLexicalScopeStatements } from '../../types/node/TNodeWithLexicalScopeStatements';
import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
import { TStringArrayScopeCallsWrapperDataByEncoding } from '../../types/node-transformers/string-array-transformers/TStringArrayScopeCallsWrapperDataByEncoding';
import { TStringArrayTransformerCustomNodeFactory } from '../../types/container/custom-nodes/TStringArrayTransformerCustomNodeFactory';
Expand Down Expand Up @@ -86,13 +85,13 @@ export class StringArrayScopeCallsWrapperTransformer extends AbstractNodeTransfo
switch (nodeTransformationStage) {
case NodeTransformationStage.StringArray:
return {
enter: (node: ESTree.Node): void => {
if (NodeGuards.isNodeWithLexicalScopeAndStatements(node)) {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): void => {
if (parentNode && NodeGuards.isNodeWithLexicalScopeStatements(node, parentNode)) {
this.onLexicalScopeNodeEnter(node);
}
},
leave: (node: ESTree.Node): ESTree.Node | undefined => {
if (NodeGuards.isNodeWithLexicalScopeAndStatements(node)) {
leave: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node | undefined => {
if (parentNode && NodeGuards.isNodeWithLexicalScopeStatements(node, parentNode)) {
this.onLexicalScopeNodeLeave();

return this.transformNode(node);
Expand All @@ -106,20 +105,17 @@ export class StringArrayScopeCallsWrapperTransformer extends AbstractNodeTransfo
}

/**
* @param {TNodeWithLexicalScopeAndStatements} lexicalScopeNode
* @returns {TNodeWithLexicalScopeAndStatements}
* @param {TNodeWithLexicalScopeStatements} lexicalScopeBodyNode
* @returns {TNodeWithLexicalScopeStatements}
*/
public transformNode (lexicalScopeNode: TNodeWithLexicalScopeAndStatements): TNodeWithLexicalScopeAndStatements {
const lexicalScopeBodyNode: ESTree.Program | ESTree.BlockStatement =
NodeGuards.isProgramNode(lexicalScopeNode)
? lexicalScopeNode
: lexicalScopeNode.body;

public transformNode (
lexicalScopeBodyNode: TNodeWithLexicalScopeStatements
): TNodeWithLexicalScopeStatements {
const stringArrayScopeCallsWrapperDataByEncoding: TStringArrayScopeCallsWrapperDataByEncoding | null =
this.stringArrayScopeCallsWrapperDataStorage.get(lexicalScopeNode) ?? null;
this.stringArrayScopeCallsWrapperDataStorage.get(lexicalScopeBodyNode) ?? null;

if (!stringArrayScopeCallsWrapperDataByEncoding) {
return lexicalScopeNode;
return lexicalScopeBodyNode;
}

const stringArrayScopeCallsWrapperDataList: (IStringArrayScopeCallsWrapperData | undefined)[] =
Expand Down Expand Up @@ -159,7 +155,7 @@ export class StringArrayScopeCallsWrapperTransformer extends AbstractNodeTransfo
}
}

return lexicalScopeNode;
return lexicalScopeBodyNode;
}

/**
Expand All @@ -181,14 +177,15 @@ export class StringArrayScopeCallsWrapperTransformer extends AbstractNodeTransfo
return rootStringArrayCallsWrapperName;
}

const parentLexicalScope: TNodeWithLexicalScope | undefined = this.visitedLexicalScopeNodesStackStorage.getLastElement();
const parentLexicalScopeBodyNode: TNodeWithLexicalScopeStatements | undefined =
this.visitedLexicalScopeNodesStackStorage.getLastElement();

if (!parentLexicalScope) {
if (!parentLexicalScopeBodyNode) {
return rootStringArrayCallsWrapperName;
}

const parentLexicalScopeDataByEncoding = this.stringArrayScopeCallsWrapperDataStorage
.get(parentLexicalScope) ?? null;
.get(parentLexicalScopeBodyNode) ?? null;
const parentLexicalScopeNames: string[] | null = parentLexicalScopeDataByEncoding?.[encoding]?.names ?? null;

return parentLexicalScopeNames?.length
Expand All @@ -199,10 +196,10 @@ export class StringArrayScopeCallsWrapperTransformer extends AbstractNodeTransfo
}

/**
* @param {TNodeWithLexicalScopeAndStatements} lexicalScopeNode
* @param {TNodeWithLexicalScopeStatements} lexicalScopeBodyNode
*/
private onLexicalScopeNodeEnter (lexicalScopeNode: TNodeWithLexicalScopeAndStatements): void {
this.visitedLexicalScopeNodesStackStorage.push(lexicalScopeNode);
private onLexicalScopeNodeEnter (lexicalScopeBodyNode: TNodeWithLexicalScopeStatements): void {
this.visitedLexicalScopeNodesStackStorage.push(lexicalScopeBodyNode);
}

private onLexicalScopeNodeLeave (): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as ESTree from 'estree';

import { TInitialData } from '../../types/TInitialData';
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
import { TNodeWithLexicalScopeStatements } from '../../types/node/TNodeWithLexicalScopeStatements';
import { TStatement } from '../../types/node/TStatement';
import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
import { TStringArrayScopeCallsWrapperDataByEncoding } from '../../types/node-transformers/string-array-transformers/TStringArrayScopeCallsWrapperDataByEncoding';
Expand Down Expand Up @@ -251,14 +251,15 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
* @returns {string}
*/
private getUpperStringArrayCallsWrapperName (encoding: TStringArrayEncoding): string {
const currentLexicalScopeNode: TNodeWithLexicalScope | undefined = this.visitedLexicalScopeNodesStackStorage.getLastElement();
const currentLexicalScopeBodyNode: TNodeWithLexicalScopeStatements | undefined =
this.visitedLexicalScopeNodesStackStorage.getLastElement();

if (!currentLexicalScopeNode) {
throw new Error('Cannot find current lexical scope node');
if (!currentLexicalScopeBodyNode) {
throw new Error('Cannot find current lexical scope body node');
}

const stringArrayScopeCallsWrapperDataByEncoding: TStringArrayScopeCallsWrapperDataByEncoding =
this.stringArrayScopeCallsWrapperDataStorage.get(currentLexicalScopeNode) ?? {};
this.stringArrayScopeCallsWrapperDataStorage.get(currentLexicalScopeBodyNode) ?? {};
const stringArrayScopeCallsWrapperNames: string[] = stringArrayScopeCallsWrapperDataByEncoding[encoding]?.names ?? [];
const isFilledScopeCallsWrapperNamesList: boolean = stringArrayScopeCallsWrapperNames.length === this.options.stringArrayWrappersCount;

Expand All @@ -272,7 +273,7 @@ export class StringArrayTransformer extends AbstractNodeTransformer {
};

this.stringArrayScopeCallsWrapperDataStorage.set(
currentLexicalScopeNode,
currentLexicalScopeBodyNode,
stringArrayScopeCallsWrapperDataByEncoding
);
}
Expand Down
29 changes: 2 additions & 27 deletions src/node/NodeGuards.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ESTree from 'estree';

import { TNodeWithLexicalScope } from '../types/node/TNodeWithLexicalScope';
import { TNodeWithLexicalScopeAndStatements } from '../types/node/TNodeWithLexicalScopeAndStatements';
import { TNodeWithLexicalScopeStatements } from '../types/node/TNodeWithLexicalScopeStatements';
import { TNodeWithStatements } from '../types/node/TNodeWithStatements';

import { NodeType } from '../enums/node/NodeType';
Expand Down Expand Up @@ -271,31 +271,6 @@ export class NodeGuards {
return NodeGuards.isNodeWithLexicalScope(node) || NodeGuards.isBlockStatementNode(node);
}

/**
* @param {Node} node
* @returns {node is TNodeWithLexicalScopeAndStatements}
*/
public static isNodeWithLexicalScopeAndStatements (node: ESTree.Node): node is TNodeWithLexicalScopeAndStatements {
if (!NodeGuards.isNodeWithLexicalScope(node)) {
return false;
}

const lexicalScopeBodyNode: ESTree.Program | ESTree.BlockStatement | ESTree.Expression =
NodeGuards.isProgramNode(node)
? node
: node.body;

// invalid lexical scope node
if (
!lexicalScopeBodyNode.parentNode
|| !NodeGuards.isNodeWithLexicalScopeStatements(lexicalScopeBodyNode, lexicalScopeBodyNode.parentNode)
) {
return false;
}

return true;
}

/**
* @param {Node} node
* @param {Node} parentNode
Expand All @@ -304,7 +279,7 @@ export class NodeGuards {
public static isNodeWithLexicalScopeStatements (
node: ESTree.Node,
parentNode: ESTree.Node
): node is TNodeWithStatements {
): node is TNodeWithLexicalScopeStatements {
return NodeGuards.isProgramNode(node)
|| (NodeGuards.isBlockStatementNode(node) && NodeGuards.nodesWithLexicalStatements.includes(parentNode.type));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';

import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';
import { TNodeWithLexicalScopeStatements } from '../../types/node/TNodeWithLexicalScopeStatements';
import { TStringArrayScopeCallsWrapperDataByEncoding } from '../../types/node-transformers/string-array-transformers/TStringArrayScopeCallsWrapperDataByEncoding';

import { IOptions } from '../../interfaces/options/IOptions';
Expand All @@ -12,7 +12,7 @@ import { MapStorage } from '../MapStorage';

@injectable()
export class StringArrayScopeCallsWrapperDataStorage extends MapStorage <
TNodeWithLexicalScope,
TNodeWithLexicalScopeStatements,
TStringArrayScopeCallsWrapperDataByEncoding
> implements IStringArrayScopeCallsWrapperDataStorage {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';

import { TNodeWithLexicalScopeAndStatements } from '../../types/node/TNodeWithLexicalScopeAndStatements';
import { TNodeWithLexicalScopeStatements } from '../../types/node/TNodeWithLexicalScopeStatements';

import { IArrayUtils } from '../../interfaces/utils/IArrayUtils';
import { IOptions } from '../../interfaces/options/IOptions';
Expand All @@ -11,7 +11,7 @@ import { IVisitedLexicalScopeNodesStackStorage } from '../../interfaces/storages
import { ArrayStorage } from '../ArrayStorage';

@injectable()
export class VisitedLexicalScopeNodesStackStorage extends ArrayStorage <TNodeWithLexicalScopeAndStatements> implements IVisitedLexicalScopeNodesStackStorage {
export class VisitedLexicalScopeNodesStackStorage extends ArrayStorage <TNodeWithLexicalScopeStatements> implements IVisitedLexicalScopeNodesStackStorage {
/**
* @type {IArrayUtils}
*/
Expand All @@ -33,23 +33,23 @@ export class VisitedLexicalScopeNodesStackStorage extends ArrayStorage <TNodeWit
}

/**
* @returns {TNodeWithLexicalScopeAndStatements | undefined}
* @returns {TNodeWithLexicalScopeStatements | undefined}
*/
public getLastElement (): TNodeWithLexicalScopeAndStatements | undefined {
public getLastElement (): TNodeWithLexicalScopeStatements | undefined {
return this.arrayUtils.getLastElement(this.getStorage());
}

/**
* @param {TNodeWithLexicalScopeAndStatements} lexicalScopeNode
* @param {TNodeWithLexicalScopeStatements} nodeWithLexicalScopeStatements
*/
public push (lexicalScopeNode: TNodeWithLexicalScopeAndStatements): void {
this.storage.push(lexicalScopeNode);
public push (nodeWithLexicalScopeStatements: TNodeWithLexicalScopeStatements): void {
this.storage.push(nodeWithLexicalScopeStatements);
}

/**
* @returns {TNodeWithLexicalScopeAndStatements | undefined}
* @returns {TNodeWithLexicalScopeStatements| undefined}
*/
public pop (): TNodeWithLexicalScopeAndStatements | undefined {
public pop (): TNodeWithLexicalScopeStatements | undefined {
return this.storage.pop();
}
}
8 changes: 0 additions & 8 deletions src/types/node/TNodeWithLexicalScopeAndStatements.ts

This file was deleted.

3 changes: 3 additions & 0 deletions src/types/node/TNodeWithLexicalScopeStatements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as ESTree from 'estree';

export type TNodeWithLexicalScopeStatements = ESTree.Program | ESTree.BlockStatement;
7 changes: 4 additions & 3 deletions test/dev/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import { IdentifierNamesGenerator } from '../../src/enums/generators/identifier-
const bar = 'bar';
const baz = 'baz';

function test () {
const bark = 'bark'
function test (arg = 'bark') {
const hawk = 'hawk';
const eagle = 'eagle';

console.log(arg, hawk, eagle);
}

console.log(foo, bar, baz);
test();
`,
{
...NO_ADDITIONAL_NODES_PRESET,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,38 @@ describe('StringArrayScopeCallsWrapperTransformer', function () {
assert.match(obfuscatedCode, stringArrayCallRegExp);
});
});

describe('Variant #4: correct wrapper for the function default parameter', () => {
const stringArrayCallRegExp: RegExp = new RegExp(
'const e *= *b;' +
'const foo *= *e\\(\'0x0\'\\);' +
'function test *\\(c *= *e\\(\'0x1\'\\)\\) *{' +
'const f *= *b;' +
'const d *= *f\\(\'0x2\'\\);' +
'}'
);

let obfuscatedCode: string;

before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/wrapper-for-the-function-default-parameter.js');

obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
stringArray: true,
stringArrayThreshold: 1,
stringArrayWrappersCount: 1
}
).getObfuscatedCode();
});

it('should add scope calls wrappers', () => {
assert.match(obfuscatedCode, stringArrayCallRegExp);
});
});
});

describe('Variant #3: prohibited scopes', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const foo = 'foo'

function test (bar = 'bar') {
const baz = 'baz'
}
Loading