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
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Change Log
v5.9.1
---
* Fixed `splitStrings`/`stringArray` breaking a quoted `constructor` class key. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1464
* Fixed identifiers inside functions nested in class field initializers being neither renamed nor preserved. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1462

v5.9.0
---
Expand All @@ -12,8 +13,8 @@ v5.9.0

v5.8.1
---
* Fixed `transformObjectKeys` making default parameter objects shared across calls. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1455
* Fixed `controlFlowFlattening` breaking short-circuit evaluation of `&&`, `||` and `??`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1456
* Fixed `transformObjectKeys` making default parameter objects shared across calls. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1455
* Fixed `controlFlowFlattening` breaking short-circuit evaluation of `&&`, `||` and `??`. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1456

v5.8.0
---
Expand All @@ -22,7 +23,7 @@ v5.8.0

v5.7.0
---
* **New option:** `advertisement` allows to control the display of the JavaScript Obfuscator Pro advertisement message in the console. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1448
* **New option:** `advertisement` allows to control the display of the JavaScript Obfuscator Pro advertisement message in the console. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1448

v5.6.0
---
Expand Down
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": "5.9.0",
"version": "5.9.1",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand Down
62 changes: 29 additions & 33 deletions src/node/ScopeIdentifiersTraverser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,30 +87,28 @@ export class ScopeIdentifiersTraverser implements IScopeIdentifiersTraverser {
: null;
const isGlobalDeclaration: boolean = ScopeIdentifiersTraverser.globalScopeNames.includes(variableScope.type);

if (!variableLexicalScopeNode) {
return;
}

for (const variable of currentScope.variables) {
if (variable.name === ScopeIdentifiersTraverser.argumentsVariableName) {
continue;
if (variableLexicalScopeNode) {
for (const variable of currentScope.variables) {
if (variable.name === ScopeIdentifiersTraverser.argumentsVariableName) {
continue;
}

const isBubblingDeclaration: boolean = variable.identifiers.some(
(identifier: ESTree.Node) =>
identifier.parentNode &&
NodeGuards.isPropertyNode(identifier.parentNode) &&
identifier.parentNode.shorthand
);

callback({
isGlobalDeclaration,
isBubblingDeclaration,
rootScope,
variable,
variableScope,
variableLexicalScopeNode
});
}

const isBubblingDeclaration: boolean = variable.identifiers.some(
(identifier: ESTree.Node) =>
identifier.parentNode &&
NodeGuards.isPropertyNode(identifier.parentNode) &&
identifier.parentNode.shorthand
);

callback({
isGlobalDeclaration,
isBubblingDeclaration,
rootScope,
variable,
variableScope,
variableLexicalScopeNode
});
}

for (const childScope of currentScope.childScopes) {
Expand All @@ -136,16 +134,14 @@ export class ScopeIdentifiersTraverser implements IScopeIdentifiersTraverser {
: null;
const isGlobalDeclaration: boolean = ScopeIdentifiersTraverser.globalScopeNames.includes(variableScope.type);

if (!variableLexicalScopeNode) {
return;
}

for (const reference of currentScope.through) {
callback({
isGlobalDeclaration,
reference,
variableLexicalScopeNode
});
if (variableLexicalScopeNode) {
for (const reference of currentScope.through) {
callback({
isGlobalDeclaration,
reference,
variableLexicalScopeNode
});
}
}

for (const childScope of currentScope.childScopes) {
Expand Down
88 changes: 88 additions & 0 deletions test/functional-tests/issues/issue1462.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { assert } from 'chai';

import { IdentifierNamesGenerator } from '../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';

import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';

//
// https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1462
//
describe('Issue #1462', () => {
describe('Identifiers inside functions nested in class field initializers should be renamed', () => {
describe('Variant #1: arrow function inside a static field initializer', () => {
const code: string = `
function register (options) {
return options;
}

class Foo {
static staticField = register({
onChange: (b) => {
return b['value'] + b['suffix'];
}
});
}

module.exports = Foo.staticField.onChange({ value: 'foo', suffix: 'bar' });
`;

let result: string;

before(() => {
const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(code, {
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
stringArray: true,
stringArrayThreshold: 1,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: false
}).getObfuscatedCode();

const moduleExports: { exports: string } = { exports: '' };
new Function('module', obfuscatedCode)(moduleExports);
result = moduleExports.exports;
});

it('should obfuscate the nested function without a runtime error', () => {
assert.equal(result, 'foobar');
});
});

describe('Variant #2: arrow function inside an instance field initializer', () => {
const code: string = `
function register (options) {
return options;
}

class Foo {
instanceField = register({
onChange: (b) => {
return b['value'] + b['suffix'];
}
});
}

module.exports = new Foo().instanceField.onChange({ value: 'foo', suffix: 'bar' });
`;

let result: string;

before(() => {
const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(code, {
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
stringArray: true,
stringArrayThreshold: 1,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: false
}).getObfuscatedCode();

const moduleExports: { exports: string } = { exports: '' };
new Function('module', obfuscatedCode)(moduleExports);
result = moduleExports.exports;
});

it('should obfuscate the nested function without a runtime error', () => {
assert.equal(result, 'foobar');
});
});
});
});
Loading