From 433a4884b36d622b1f7f4ccdbdd336636140d007 Mon Sep 17 00:00:00 2001 From: Angelo D <43831545+AngeloD2022@users.noreply.github.com> Date: Wed, 31 Aug 2022 17:27:17 -0400 Subject: [PATCH 1/3] Fix boolean parenthesis problem. (Tested empirically) --- src/jsxer/nodes/LogicalExpression.cpp | 83 ++++++++++++++++++++++++++- src/jsxer/nodes/LogicalExpression.h | 6 ++ src/jsxer/nodes/TernaryExpression.cpp | 2 +- src/jsxer/nodes/TernaryExpression.h | 1 + 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/src/jsxer/nodes/LogicalExpression.cpp b/src/jsxer/nodes/LogicalExpression.cpp index 8151de4..f88dd31 100644 --- a/src/jsxer/nodes/LogicalExpression.cpp +++ b/src/jsxer/nodes/LogicalExpression.cpp @@ -1,9 +1,16 @@ #include "LogicalExpression.h" -string get_expr(AstNode *node, const string& literal){ - return '(' + (node == nullptr ? literal : node->to_string()) + ')'; +string LogicalExpression::parenthesis(AstNode *node){ + switch (node->type()) { + case NodeType::LocalAssignmentExpression: + case NodeType::AssignmentExpression: + return "(" + node->to_string() + ")"; + default: + return node->to_string(); + } } + void LogicalExpression::parse() { // opName is either "&&" or "||" opName = decoders::d_sid(reader); @@ -14,5 +21,75 @@ void LogicalExpression::parse() { } string LogicalExpression::to_string() { - return get_expr(leftExpr, leftLiteral) + ' ' + opName + ' ' + get_expr(rightExpr, rightLiteral); + +// fprintf(stdout, "L: %s R: %s \n", leftExpr->to_string().c_str(), rightExpr->to_string().c_str()); + +// return get_expr(leftExpr, leftLiteral) + ' ' + opName + ' ' + get_expr(rightExpr, rightLiteral); + +// if (opName == "&&") { +// if (rightExpr != nullptr && rightExpr->type() == NodeType::LogicalExpression){ +// LogicalExpression* right = (LogicalExpression *) rightExpr; +// if (right->opName == "||") +// return get_expr(leftExpr, leftLiteral) + " " + opName + " (" + right->to_string() + ")"; +// } else if (leftExpr != nullptr && leftExpr->type() == NodeType::LogicalExpression) { +// LogicalExpression* left = (LogicalExpression *) leftExpr; +// if (left->opName == "||") +// return "(" + left->to_string() + ") " + opName + " " + get_expr(rightExpr, rightLiteral); +// } +// } + string result = " " + opName + " "; + +// if (rightExpr != nullptr && rightExpr->type() == NodeType::LogicalExpression){ +// LogicalExpression* right = (LogicalExpression *) rightExpr; +// +// if (right->opName == "||") +// return get_expr(leftExpr, leftLiteral) + " " + opName + " (" + right->to_string() + ")"; +// +// } else if (leftExpr != nullptr && leftExpr->type() == NodeType::LogicalExpression && opName == "&&") { +// LogicalExpression* left = (LogicalExpression *) leftExpr; +// +// if (left->opName == "||") +// return "(" + left->to_string() + ") " + opName + " " + get_expr(rightExpr, rightLiteral); +// } else { +// result = get_expr(leftExpr, leftLiteral) + result + get_expr(rightExpr, rightLiteral); +// } + + if (leftExpr != nullptr) { + if (leftExpr->type() == NodeType::LogicalExpression) { + LogicalExpression* left = (LogicalExpression *) leftExpr; + if (left->opName == "||" && opName == "&&") { + result = "(" + left->to_string() + ")" + result; + if (rightExpr != nullptr && rightExpr->type() == NodeType::LogicalExpression) { + LogicalExpression* right = (LogicalExpression *) rightExpr; + if (right->opName == "||"){ + result += "(" + right->to_string() + ")"; + goto done; + } + } + } + else + result = left->to_string() + result; + } else { + result = parenthesis(leftExpr) + result; + } + } else { + result = leftLiteral + result; + } + + if (rightExpr != nullptr) { + if (rightExpr->type() == NodeType::LogicalExpression) { + LogicalExpression* right = (LogicalExpression *) rightExpr; + if (right->opName == "||") + result += "(" + right->to_string() + ")"; + else + result += right->to_string(); + } else { + result += parenthesis(rightExpr); + } + } else { + result += rightLiteral; + } + + done: + return result; } diff --git a/src/jsxer/nodes/LogicalExpression.h b/src/jsxer/nodes/LogicalExpression.h index 42d477b..16586b9 100644 --- a/src/jsxer/nodes/LogicalExpression.h +++ b/src/jsxer/nodes/LogicalExpression.h @@ -24,5 +24,11 @@ namespace jsxer { namespace nodes { AstNode *rightExpr; string leftLiteral; string rightLiteral; + + string get_expr(AstNode *node, const string &literal); + + bool contains_or(); + + string parenthesis(AstNode *node); }; } } diff --git a/src/jsxer/nodes/TernaryExpression.cpp b/src/jsxer/nodes/TernaryExpression.cpp index 5916fc2..f523027 100644 --- a/src/jsxer/nodes/TernaryExpression.cpp +++ b/src/jsxer/nodes/TernaryExpression.cpp @@ -1,6 +1,6 @@ #include "TernaryExpression.h" -bool parenthesis(AstNode* node) { +bool TernaryExpression::parenthesis(AstNode* node) { return (node->type() == NodeType::TernaryExpression) && (node->type() == NodeType::ListExpression); } diff --git a/src/jsxer/nodes/TernaryExpression.h b/src/jsxer/nodes/TernaryExpression.h index f18f69b..a6e47ef 100644 --- a/src/jsxer/nodes/TernaryExpression.h +++ b/src/jsxer/nodes/TernaryExpression.h @@ -23,5 +23,6 @@ namespace jsxer { namespace nodes { AstNode* node_true; AstNode* node_false; + bool parenthesis(AstNode *node); }; } } From 72469e7d4f26c304aeb820c0d285198213e1ff06 Mon Sep 17 00:00:00 2001 From: Angelo D <43831545+AngeloD2022@users.noreply.github.com> Date: Wed, 31 Aug 2022 20:36:04 -0400 Subject: [PATCH 2/3] Removed commented-out code. --- src/jsxer/nodes/LogicalExpression.cpp | 31 --------------------------- 1 file changed, 31 deletions(-) diff --git a/src/jsxer/nodes/LogicalExpression.cpp b/src/jsxer/nodes/LogicalExpression.cpp index f88dd31..2a1f594 100644 --- a/src/jsxer/nodes/LogicalExpression.cpp +++ b/src/jsxer/nodes/LogicalExpression.cpp @@ -21,39 +21,8 @@ void LogicalExpression::parse() { } string LogicalExpression::to_string() { - -// fprintf(stdout, "L: %s R: %s \n", leftExpr->to_string().c_str(), rightExpr->to_string().c_str()); - -// return get_expr(leftExpr, leftLiteral) + ' ' + opName + ' ' + get_expr(rightExpr, rightLiteral); - -// if (opName == "&&") { -// if (rightExpr != nullptr && rightExpr->type() == NodeType::LogicalExpression){ -// LogicalExpression* right = (LogicalExpression *) rightExpr; -// if (right->opName == "||") -// return get_expr(leftExpr, leftLiteral) + " " + opName + " (" + right->to_string() + ")"; -// } else if (leftExpr != nullptr && leftExpr->type() == NodeType::LogicalExpression) { -// LogicalExpression* left = (LogicalExpression *) leftExpr; -// if (left->opName == "||") -// return "(" + left->to_string() + ") " + opName + " " + get_expr(rightExpr, rightLiteral); -// } -// } string result = " " + opName + " "; -// if (rightExpr != nullptr && rightExpr->type() == NodeType::LogicalExpression){ -// LogicalExpression* right = (LogicalExpression *) rightExpr; -// -// if (right->opName == "||") -// return get_expr(leftExpr, leftLiteral) + " " + opName + " (" + right->to_string() + ")"; -// -// } else if (leftExpr != nullptr && leftExpr->type() == NodeType::LogicalExpression && opName == "&&") { -// LogicalExpression* left = (LogicalExpression *) leftExpr; -// -// if (left->opName == "||") -// return "(" + left->to_string() + ") " + opName + " " + get_expr(rightExpr, rightLiteral); -// } else { -// result = get_expr(leftExpr, leftLiteral) + result + get_expr(rightExpr, rightLiteral); -// } - if (leftExpr != nullptr) { if (leftExpr->type() == NodeType::LogicalExpression) { LogicalExpression* left = (LogicalExpression *) leftExpr; From 9322d0bb09dfe06def6ddb434fcd4391790b4e87 Mon Sep 17 00:00:00 2001 From: Angelo D <43831545+AngeloD2022@users.noreply.github.com> Date: Sun, 23 Oct 2022 16:08:08 -0400 Subject: [PATCH 3/3] Added comment to explain parenthesis logic. --- src/jsxer/nodes/LogicalExpression.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/jsxer/nodes/LogicalExpression.cpp b/src/jsxer/nodes/LogicalExpression.cpp index 2a1f594..dd41c9c 100644 --- a/src/jsxer/nodes/LogicalExpression.cpp +++ b/src/jsxer/nodes/LogicalExpression.cpp @@ -23,6 +23,12 @@ void LogicalExpression::parse() { string LogicalExpression::to_string() { string result = " " + opName + " "; + // Explanation of the below logic: + // ExtendScript does not honor traditional boolean order of operations with logical expressions. + // The decompiler now produces output that forces order of operations equivalent to ES with modern interpreters like V8, + // and it manages to do it such that it does not affect the order of operations if evaluated in the ES runtime. + // Awesome! :) + if (leftExpr != nullptr) { if (leftExpr->type() == NodeType::LogicalExpression) { LogicalExpression* left = (LogicalExpression *) leftExpr;