Fixed behaviour of simplify options when node with a single-statement body is inside simplified IfStatement node

Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/860
This commit is contained in:
sanex
2021-01-17 19:53:16 +03:00
parent ee41f06b3c
commit 5289dcc834
18 changed files with 955 additions and 8 deletions
+97
View File
@@ -167,6 +167,20 @@ export class NodeFactory {
};
}
/**
* @param {Statement} body
* @param {Expression} test
* @returns {DoWhileStatement}
*/
public static doWhileStatementNode (body: ESTree.Statement, test: ESTree.Expression): ESTree.DoWhileStatement {
return {
type: NodeType.DoWhileStatement,
body,
test,
metadata: { ignoredNode: false }
};
}
/**
* @param {Literal} source
* @returns {ExportAllDeclaration}
@@ -210,6 +224,72 @@ export class NodeFactory {
};
}
/**
* @param {VariableDeclaration | Expression | null} init
* @param {Expression | null} test
* @param {Expression | null} update
* @param {Statement} body
* @returns {ForStatement}
*/
public static forStatementNode (
init: ESTree.VariableDeclaration | ESTree.Expression | null,
test: ESTree.Expression | null,
update: ESTree.Expression | null,
body: ESTree.Statement
): ESTree.ForStatement {
return {
type: NodeType.ForStatement,
init,
test,
update,
body,
metadata: { ignoredNode: false }
};
}
/**
* @param {VariableDeclaration | Pattern} left
* @param {Expression} right
* @param {Statement} body
* @returns {ForInStatement}
*/
public static forInStatementNode (
left: ESTree.VariableDeclaration | ESTree.Pattern,
right: ESTree.Expression,
body: ESTree.Statement
): ESTree.ForInStatement {
return {
type: NodeType.ForInStatement,
left,
right,
body,
metadata: { ignoredNode: false }
};
}
/**
* @param {boolean} await
* @param {VariableDeclaration | Pattern} left
* @param {Expression} right
* @param {Statement} body
* @returns {ForOfStatement}
*/
public static forOfStatementNode (
await: boolean,
left: ESTree.VariableDeclaration | ESTree.Pattern,
right: ESTree.Expression,
body: ESTree.Statement
): ESTree.ForOfStatement {
return {
type: NodeType.ForOfStatement,
await,
left,
right,
body,
metadata: { ignoredNode: false }
};
}
/**
* @param {string} functionName
* @param {Identifier[]} params
@@ -298,6 +378,23 @@ export class NodeFactory {
};
}
/**
* @param {Identifier} label
* @param {Statement} body
* @returns {LabeledStatement}
*/
public static labeledStatementNode (
label: ESTree.Identifier,
body: ESTree.Statement
): ESTree.LabeledStatement {
return {
type: NodeType.LabeledStatement,
label,
body,
metadata: { ignoredNode: false }
};
}
/**
* @param {boolean | number | string} value
* @param {string} raw
+76
View File
@@ -1,3 +1,4 @@
/* eslint-disable max-lines */
import * as ESTree from 'estree';
import { TNodeWithLexicalScope } from '../types/node/TNodeWithLexicalScope';
@@ -5,6 +6,7 @@ import { TNodeWithLexicalScopeStatements } from '../types/node/TNodeWithLexicalS
import { TNodeWithStatements } from '../types/node/TNodeWithStatements';
import { NodeType } from '../enums/node/NodeType';
import { TNodeWithSingleStatementBody } from '../types/node/TNodeWithSingleStatementBody';
export class NodeGuards {
/**
@@ -116,6 +118,14 @@ export class NodeGuards {
&& 'directive' in node;
}
/**
* @param {Node} node
* @returns {boolean}
*/
public static isDoWhileStatementNode (node: ESTree.Node): node is ESTree.DoWhileStatement {
return node.type === NodeType.DoWhileStatement;
}
/**
* @param {Node} node
* @returns {boolean}
@@ -149,6 +159,22 @@ export class NodeGuards {
&& !('directive' in node);
}
/**
* @param {Node} node
* @returns {boolean}
*/
public static isForStatementNode (node: ESTree.Node): node is ESTree.ForStatement {
return node.type === NodeType.ForStatement;
}
/**
* @param {Node} node
* @returns {boolean}
*/
public static isForInStatementNode (node: ESTree.Node): node is ESTree.ForInStatement {
return node.type === NodeType.ForInStatement;
}
/**
* @param {Node} node
* @returns {boolean}
@@ -201,6 +227,19 @@ export class NodeGuards {
return node.type === NodeType.IfStatement;
}
/**
* @param {Node} node
* @returns {boolean}
*/
public static isIfStatementNodeWithSingleStatementBody (node: ESTree.Node): node is ESTree.IfStatement {
if (!NodeGuards.isIfStatementNode(node)) {
return false;
}
return !NodeGuards.isBlockStatementNode(node.consequent)
|| (!!node.alternate && !NodeGuards.isBlockStatementNode(node.alternate));
}
/**
* @param {Node} node
* @returns {boolean}
@@ -287,6 +326,35 @@ export class NodeGuards {
return NodeGuards.isNodeWithLexicalScope(node) || NodeGuards.isBlockStatementNode(node);
}
/**
* Checks if a node is the node with single statement body, like:
* while (true)
* console.log(1);
*
* or:
*
*
* @param {Node} node
* @returns {boolean}
*/
public static isNodeWithSingleStatementBody (node: ESTree.Node): node is TNodeWithSingleStatementBody {
// Different approach for `IfStatement` node because this node hasn't `body` property
if (NodeGuards.isIfStatementNode(node)) {
return NodeGuards.isIfStatementNodeWithSingleStatementBody(node);
}
// All other nodes with `Statement` node as `body` property
return (
NodeGuards.isForStatementNode(node)
|| NodeGuards.isForOfStatementNode(node)
|| NodeGuards.isForInStatementNode(node)
|| NodeGuards.isWhileStatementNode(node)
|| NodeGuards.isDoWhileStatementNode(node)
|| NodeGuards.isWithStatementNode(node)
|| NodeGuards.isLabeledStatementNode(node)
) && !NodeGuards.isBlockStatementNode(node.body);
}
/**
* @param {Node} node
* @param {Node} parentNode
@@ -438,6 +506,14 @@ export class NodeGuards {
return node.type === NodeType.VariableDeclarator;
}
/**
* @param {Node} node
* @returns {boolean}
*/
public static isWithStatementNode (node: ESTree.Node): node is ESTree.WithStatement {
return node.type === NodeType.WithStatement;
}
/**
* @param {Node} node
* @returns {boolean}