mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Fixed invalid code generation for rest arguments when controlFlowFlattening option is enabled
Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/887
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
Change Log
|
||||
|
||||
v2.10.5
|
||||
---
|
||||
* Fixed invalid code generation for rest arguments when `controlFlowFlattening` option is enabled. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/887
|
||||
|
||||
v2.10.4
|
||||
---
|
||||
* Fixed invalid behaviour of `numbersToExpressions` option for float numbers. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/882
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "javascript-obfuscator",
|
||||
"version": "2.10.4",
|
||||
"version": "2.10.5",
|
||||
"description": "JavaScript obfuscator",
|
||||
"keywords": [
|
||||
"obfuscator",
|
||||
|
||||
@@ -15,6 +15,7 @@ import { initializable } from '../../decorators/Initializable';
|
||||
import { AbstractCustomNode } from '../AbstractCustomNode';
|
||||
import { NodeFactory } from '../../node/NodeFactory';
|
||||
import { NodeUtils } from '../../node/NodeUtils';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
|
||||
@injectable()
|
||||
export class CallExpressionFunctionNode extends AbstractCustomNode {
|
||||
@@ -57,11 +58,26 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const calleeIdentifier: ESTree.Identifier = NodeFactory.identifierNode('callee');
|
||||
const params: ESTree.Identifier[] = [];
|
||||
const params: (ESTree.Identifier | ESTree.RestElement)[] = [];
|
||||
const callArguments: (ESTree.Identifier | ESTree.SpreadElement)[] = [];
|
||||
const argumentsLength: number = this.expressionArguments.length;
|
||||
|
||||
for (let i: number = 0; i < argumentsLength; i++) {
|
||||
params.push(NodeFactory.identifierNode(`param${i + 1}`));
|
||||
const argument: ESTree.Expression | ESTree.SpreadElement = this.expressionArguments[i];
|
||||
const isSpreadCallArgument: boolean = NodeGuards.isSpreadElementNode(argument);
|
||||
|
||||
const baseIdentifierNode: ESTree.Identifier = NodeFactory.identifierNode(`param${i + 1}`);
|
||||
|
||||
params.push(
|
||||
isSpreadCallArgument
|
||||
? NodeFactory.restElementNode(baseIdentifierNode)
|
||||
: baseIdentifierNode
|
||||
);
|
||||
callArguments.push(
|
||||
isSpreadCallArgument
|
||||
? NodeFactory.spreadElementNode(baseIdentifierNode)
|
||||
: baseIdentifierNode
|
||||
);
|
||||
}
|
||||
|
||||
const structure: TStatement = NodeFactory.expressionStatementNode(
|
||||
@@ -74,7 +90,7 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
|
||||
NodeFactory.returnStatementNode(
|
||||
NodeFactory.callExpressionNode(
|
||||
calleeIdentifier,
|
||||
params
|
||||
callArguments
|
||||
)
|
||||
)
|
||||
])
|
||||
|
||||
+25
-1
@@ -317,7 +317,7 @@ export class NodeFactory {
|
||||
* @returns {FunctionExpression}
|
||||
*/
|
||||
public static functionExpressionNode (
|
||||
params: ESTree.Identifier[],
|
||||
params: ESTree.Pattern[],
|
||||
body: ESTree.BlockStatement
|
||||
): ESTree.FunctionExpression {
|
||||
return {
|
||||
@@ -493,6 +493,18 @@ export class NodeFactory {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Pattern} argument
|
||||
* @returns {SpreadElement}
|
||||
*/
|
||||
public static restElementNode (argument: ESTree.Pattern): ESTree.RestElement {
|
||||
return {
|
||||
type: NodeType.RestElement,
|
||||
argument,
|
||||
metadata: { ignoredNode: false }
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression} argument
|
||||
* @returns {ReturnStatement}
|
||||
@@ -517,6 +529,18 @@ export class NodeFactory {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression} argument
|
||||
* @returns {SpreadElement}
|
||||
*/
|
||||
public static spreadElementNode (argument: ESTree.Expression): ESTree.SpreadElement {
|
||||
return {
|
||||
type: NodeType.SpreadElement,
|
||||
argument,
|
||||
metadata: { ignoredNode: false }
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Expression} discriminant
|
||||
* @param {SwitchCase[]} cases
|
||||
|
||||
+9
-7
@@ -7,17 +7,19 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
|
||||
|
||||
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
||||
`
|
||||
const epsilon = 500;
|
||||
const number = 500000.0000001;
|
||||
|
||||
if(epsilon > 0 && number > 500000.0000000 && number < 500000.0000002) {
|
||||
console.log("math works!");
|
||||
};
|
||||
(function () {
|
||||
const log = console.log;
|
||||
const first = 'foo';
|
||||
const rest = ['bar', 'baz', 'bark'];
|
||||
log(first, ...rest);
|
||||
})();
|
||||
|
||||
`,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
numbersToExpressions: true
|
||||
compact: false,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
|
||||
|
||||
+32
@@ -117,5 +117,37 @@ describe('CallExpressionControlFlowReplacer', function () {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Variant #4 - rest call argument', () => {
|
||||
const controlFlowStorageCallRegExp: RegExp = /_0x([a-f0-9]){4,6}\['\w{5}']\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}, *\.\.\._0x([a-f0-9]){4,6}\);/;
|
||||
const controlFlowStorageNodeRegExp: RegExp = new RegExp(`` +
|
||||
`'\\w{5}' *: *function *\\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}, *\.\.\._0x([a-f0-9]){4,6}\\) *\\{` +
|
||||
`return *_0x([a-f0-9]){4,6}\\(_0x([a-f0-9]){4,6}, *\.\.\._0x([a-f0-9]){4,6}\\);` +
|
||||
`\\}` +
|
||||
``);
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/rest-call-argument.js');
|
||||
|
||||
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_ADDITIONAL_NODES_PRESET,
|
||||
controlFlowFlattening: true,
|
||||
controlFlowFlatteningThreshold: 1
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should replace call expression node with call to control flow storage node', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageCallRegExp);
|
||||
});
|
||||
|
||||
it('should keep spread parameter and rest call argument inside control flow storage node function', () => {
|
||||
assert.match(obfuscatedCode, controlFlowStorageNodeRegExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
(function () {
|
||||
const log = console.log;
|
||||
const first = 'foo';
|
||||
const rest = ['bar', 'baz', 'bark'];
|
||||
log(first, ...rest);
|
||||
})();
|
||||
+2
-2
@@ -221,7 +221,7 @@ describe('FunctionControlFlowTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('arrow function expression', () => {
|
||||
describe('Variant #7 - arrow function expression', () => {
|
||||
describe('Variant #1 - arrow function expression with body', () => {
|
||||
const regexp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
|
||||
|
||||
@@ -269,7 +269,7 @@ describe('FunctionControlFlowTransformer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('prevailing kind of variables', () => {
|
||||
describe('Variant #8 - prevailing kind of variables', () => {
|
||||
describe('Variant #1 - `var` kind', () => {
|
||||
const regexp: RegExp = new RegExp(`var ${variableMatch} *= *\\{`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user