mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Fixed deadCodeInjection causing SyntaxError when arguments from collected block statements was injected into class field initializers or static initialization blocks (#1377)
This commit is contained in:
@@ -4,6 +4,7 @@ v5.2.1
|
||||
---
|
||||
* Fixed `transformObjectKeys` incorrectly hoisting object literal outside of loop when loop body is a single statement without braces, causing all iterations to share the same object reference. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1300
|
||||
* Fixed parsing error when `await` is used as an identifier in non-async context. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1127
|
||||
* Fixed `deadCodeInjection` causing SyntaxError when `arguments` from collected block statements was injected into class field initializers or static initialization blocks. Fixes https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1166
|
||||
|
||||
v5.2.0
|
||||
---
|
||||
|
||||
+4
-1
@@ -101,6 +101,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
* @param {Node} targetNode
|
||||
* @returns {boolean}
|
||||
*/
|
||||
// eslint-disable-next-line complexity
|
||||
private static isProhibitedNodeInsideCollectedBlockStatement(targetNode: ESTree.Node): boolean {
|
||||
return (
|
||||
NodeGuards.isFunctionDeclarationNode(targetNode) || // can break code on strict mode
|
||||
@@ -110,7 +111,9 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
NodeGuards.isYieldExpressionNode(targetNode) ||
|
||||
NodeGuards.isSuperNode(targetNode) ||
|
||||
(NodeGuards.isForOfStatementNode(targetNode) && targetNode.await) ||
|
||||
NodeGuards.isPrivateIdentifierNode(targetNode)
|
||||
NodeGuards.isPrivateIdentifierNode(targetNode) ||
|
||||
// `arguments` is not allowed in class field initializers or static initialization blocks
|
||||
(NodeGuards.isIdentifierNode(targetNode) && targetNode.name === 'arguments')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Function that uses `arguments` - this block can be collected for dead code injection
|
||||
function logArgs() {
|
||||
console.log(arguments);
|
||||
console.log(arguments.length);
|
||||
}
|
||||
|
||||
function foo() {
|
||||
console.log(arguments[0]);
|
||||
}
|
||||
|
||||
function bar() {
|
||||
var args = arguments;
|
||||
return args;
|
||||
}
|
||||
|
||||
// Class with static initialization block - dead code should NOT be injected here with `arguments`
|
||||
class MyClass {
|
||||
static value;
|
||||
|
||||
static {
|
||||
console.log('static block');
|
||||
MyClass.value = 42;
|
||||
}
|
||||
|
||||
method() {
|
||||
console.log('method');
|
||||
}
|
||||
}
|
||||
|
||||
console.log(MyClass.value);
|
||||
logArgs(1, 2, 3);
|
||||
foo('test');
|
||||
bar('a', 'b');
|
||||
@@ -0,0 +1,33 @@
|
||||
// Function that uses `arguments` - this block can be collected for dead code injection
|
||||
function logArgs() {
|
||||
console.log(arguments);
|
||||
console.log(arguments.length);
|
||||
}
|
||||
|
||||
function foo() {
|
||||
console.log(arguments[0]);
|
||||
}
|
||||
|
||||
function bar() {
|
||||
var args = arguments;
|
||||
return args;
|
||||
}
|
||||
|
||||
// Class with field initializers - dead code should NOT be injected here with `arguments`
|
||||
class MyClass {
|
||||
field1 = (() => {
|
||||
console.log('initializer');
|
||||
return 1;
|
||||
})();
|
||||
|
||||
field2 = 2;
|
||||
|
||||
method() {
|
||||
console.log('method');
|
||||
}
|
||||
}
|
||||
|
||||
new MyClass();
|
||||
logArgs(1, 2, 3);
|
||||
foo('test');
|
||||
bar('a', 'b');
|
||||
@@ -0,0 +1,53 @@
|
||||
import { assert } from 'chai';
|
||||
import { NO_ADDITIONAL_NODES_PRESET } from '../../../src/options/presets/NoCustomNodes';
|
||||
import { readFileAsString } from '../../helpers/readFileAsString';
|
||||
import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';
|
||||
|
||||
//
|
||||
// https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1166
|
||||
//
|
||||
describe('Issue #1166', () => {
|
||||
describe('`arguments` in collected block statement should not be injected into class field initializer', () => {
|
||||
let testFunc: () => string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/issue1166.js');
|
||||
|
||||
testFunc = () =>
|
||||
JavaScriptObfuscator.obfuscate(code, {
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 1
|
||||
}).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('does not crash on obfuscating', () => {
|
||||
// Run multiple times to increase chance of triggering the bug
|
||||
for (let i = 0; i < 50; i++) {
|
||||
assert.doesNotThrow(testFunc);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('`arguments` in collected block statement should not be injected into static block', () => {
|
||||
let testFunc: () => string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/issue1166-static-block.js');
|
||||
|
||||
testFunc = () =>
|
||||
JavaScriptObfuscator.obfuscate(code, {
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 1
|
||||
}).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('does not crash on obfuscating', () => {
|
||||
// Run multiple times to increase chance of triggering the bug
|
||||
for (let i = 0; i < 50; i++) {
|
||||
assert.doesNotThrow(testFunc);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user