Skip to content

Commit

Permalink
Implemented tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fnhartmann committed Nov 16, 2023
1 parent 67f325a commit 0c2d455
Showing 1 changed file with 254 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
ImportedFunctionSymbol,
ListOperation,
OperationType,
UnaryOperation,
Variable,
)
from decompiler.structures.pseudo.operations import OperationType
Expand Down Expand Up @@ -962,6 +963,208 @@ def test_for_loop_recovery_if_continue_in_while_2(self):
]
assert last_definition == Assignment(Variable("a"), BinaryOperation(OperationType.minus, [Constant(4), Constant(1)]))

def test_for_loop_recovery_if_continue_in_while_3(self):
"""
Test for loop recovery if a continue occurs in a while loop and the continuation-statement and the last definition
are simple binary operations that use the same variable but another than the iteration variable.
a = 1
while(a < 10){
if(num2 > num1){
a = num1 + 3
continue
}
a = num1 + 2
}
"""
true_value = LogicCondition.initialize_true(context := LogicCondition.generate_new_context())
ast = AbstractSyntaxTree(
root := SeqNode(true_value),
condition_map={
logic_cond("x1", context): Condition(OperationType.less, [Variable("a"), Constant(10)]),
logic_cond("x2", context): Condition(OperationType.greater, [Variable("num2"), Variable("num1")]),
},
)

true_branch = ast._add_code_node(
[Assignment(Variable("a"), BinaryOperation(OperationType.plus, [Variable("num1"), Constant(3)])), Continue()]
)
if_condition = ast._add_condition_node_with(logic_cond("x2", context), true_branch)

init_code_node = ast._add_code_node([Assignment(Variable("a"), Constant(0))])

while_loop = ast.factory.create_while_loop_node(logic_cond("x1", context))
while_loop_body = ast.factory.create_seq_node()
while_loop_iteration = ast._add_code_node(
[Assignment(Variable("a"), BinaryOperation(OperationType.plus, [Variable("num1"), Constant(2)]))]
)
ast._add_node(while_loop)
ast._add_node(while_loop_body)

ast._add_edges_from(
[
(root, init_code_node),
(root, while_loop),
(while_loop, while_loop_body),
(while_loop_body, if_condition),
(while_loop_body, while_loop_iteration),
]
)

WhileLoopReplacer(ast, _generate_options()).run()
assert all(isinstance(loop_node, ForLoopNode) for loop_node in list(ast.get_loop_nodes_post_order()))

condition_nodes = list(ast.get_condition_nodes_post_order())
last_definition = condition_nodes[0].true_branch_child.instructions[
_get_last_definition_index_of(condition_nodes[0].true_branch_child, Variable("a"))
]
assert last_definition == Assignment(
Variable("a"),
BinaryOperation(OperationType.minus, [BinaryOperation(OperationType.plus, [Variable("num1"), Constant(3)]), Constant(2)]),
)

def test_for_loop_recovery_if_continue_in_while_4(self):
"""
Test for loop recovery if a continue occurs in a while loop, the last definition is a simple binary operation and
the continuation-instruction has a negated used variable.
a = 0
while(a < 10) {
if(a == 2) {
a = a + 1
continue
}
a = -a + 10
}
"""
true_value = LogicCondition.initialize_true(context := LogicCondition.generate_new_context())
ast = AbstractSyntaxTree(
root := SeqNode(true_value),
condition_map={
logic_cond("x1", context): Condition(OperationType.less, [Variable("a"), Constant(10)]),
logic_cond("x2", context): Condition(OperationType.equal, [Variable("a"), Constant(2)]),
},
)

true_branch = ast._add_code_node(
[Assignment(Variable("a"), BinaryOperation(OperationType.plus, [Variable("a"), Constant(1)])), Continue()]
)
if_condition = ast._add_condition_node_with(logic_cond("x2", context), true_branch)

init_code_node = ast._add_code_node([Assignment(Variable("a"), Constant(0))])

while_loop = ast.factory.create_while_loop_node(logic_cond("x1", context))
while_loop_body = ast.factory.create_seq_node()
while_loop_iteration = ast._add_code_node(
[
Assignment(
Variable("a"),
BinaryOperation(OperationType.plus, [UnaryOperation(OperationType.negate, [Variable("a")]), Constant(10)]),
)
]
)
ast._add_node(while_loop)
ast._add_node(while_loop_body)

ast._add_edges_from(
[
(root, init_code_node),
(root, while_loop),
(while_loop, while_loop_body),
(while_loop_body, if_condition),
(while_loop_body, while_loop_iteration),
]
)

WhileLoopReplacer(ast, _generate_options()).run()
assert all(isinstance(loop_node, ForLoopNode) for loop_node in list(ast.get_loop_nodes_post_order()))

condition_nodes = list(ast.get_condition_nodes_post_order())
last_definition = condition_nodes[0].true_branch_child.instructions[
_get_last_definition_index_of(condition_nodes[0].true_branch_child, Variable("a"))
]
assert last_definition == Assignment(
Variable("a"),
UnaryOperation(
OperationType.negate,
[BinaryOperation(OperationType.minus, [BinaryOperation(OperationType.plus, [Variable("a"), Constant(1)]), Constant(10)])],
),
)

def test_for_loop_recovery_if_continue_in_while_5(self):
"""
Test for loop recovery if a continue occurs in a while loop, the last definition is a simple binary operation,
the continuation-instruction has a negated constant and a not unified form like 'var = var + const'.
a = 0;
while(a < 10) {
if(a == 2) {
a = a + 1
continue
}
a = -10 - -a
}
"""
true_value = LogicCondition.initialize_true(context := LogicCondition.generate_new_context())
ast = AbstractSyntaxTree(
root := SeqNode(true_value),
condition_map={
logic_cond("x1", context): Condition(OperationType.less, [Variable("a"), Constant(10)]),
logic_cond("x2", context): Condition(OperationType.equal, [Variable("a"), Constant(2)]),
},
)

true_branch = ast._add_code_node(
[Assignment(Variable("a"), BinaryOperation(OperationType.plus, [Variable("a"), Constant(1)])), Continue()]
)
if_condition = ast._add_condition_node_with(logic_cond("x2", context), true_branch)

init_code_node = ast._add_code_node([Assignment(Variable("a"), Constant(0))])

while_loop = ast.factory.create_while_loop_node(logic_cond("x1", context))
while_loop_body = ast.factory.create_seq_node()
while_loop_iteration = ast._add_code_node(
[
Assignment(
Variable("a"),
BinaryOperation(OperationType.minus, [Constant(-10), UnaryOperation(OperationType.negate, [Variable("a")])]),
)
]
)
ast._add_node(while_loop)
ast._add_node(while_loop_body)

ast._add_edges_from(
[
(root, init_code_node),
(root, while_loop),
(while_loop, while_loop_body),
(while_loop_body, if_condition),
(while_loop_body, while_loop_iteration),
]
)

WhileLoopReplacer(ast, _generate_options()).run()

for loop_node in list(ast.get_loop_nodes_post_order()):
assert isinstance(loop_node, ForLoopNode)
assert loop_node.modification == Assignment(
Variable("a"),
BinaryOperation(
OperationType.plus,
[UnaryOperation(OperationType.negate, [UnaryOperation(OperationType.negate, [Variable("a")])]), Constant(-10)],
),
)

condition_nodes = list(ast.get_condition_nodes_post_order())
last_definition = condition_nodes[0].true_branch_child.instructions[
_get_last_definition_index_of(condition_nodes[0].true_branch_child, Variable("a"))
]
assert last_definition == Assignment(
Variable("a"),
BinaryOperation(OperationType.minus, [BinaryOperation(OperationType.plus, [Variable("a"), Constant(1)]), Constant(-10)]),
)

def test_for_loop_recovery_if_continue_in_nested_while(self):
"""
while(a < 5) {
Expand Down Expand Up @@ -1181,3 +1384,54 @@ def test_skip_for_loop_recovery_if_continue_in_while_3(self):

WhileLoopReplacer(ast, _generate_options()).run()
assert not any(isinstance(loop_node, ForLoopNode) for loop_node in list(ast.get_loop_nodes_post_order()))

def test_skip_for_loop_recovery_if_continue_in_while_4(self):
"""
Test skip of for loop recovery if a continue occurs in a while loop, the continuation-statement and the last definition
uses different variables.
a = 0
while(a < 10){
if(num2 > num1){
a = num2 + 3
continue
}
a = num1 + 2
}
"""
true_value = LogicCondition.initialize_true(context := LogicCondition.generate_new_context())
ast = AbstractSyntaxTree(
root := SeqNode(true_value),
condition_map={
logic_cond("x1", context): Condition(OperationType.less, [Variable("a"), Constant(10)]),
logic_cond("x2", context): Condition(OperationType.greater, [Variable("num2"), Variable("num1")]),
},
)

true_branch = ast._add_code_node(
[Assignment(Variable("a"), BinaryOperation(OperationType.plus, [Variable("num2"), Constant(3)])), Continue()]
)
if_condition = ast._add_condition_node_with(logic_cond("x2", context), true_branch)

init_code_node = ast._add_code_node([Assignment(Variable("a"), Constant(0))])

while_loop = ast.factory.create_while_loop_node(logic_cond("x1", context))
while_loop_body = ast.factory.create_seq_node()
while_loop_iteration = ast._add_code_node(
[Assignment(Variable("a"), BinaryOperation(OperationType.plus, [Variable("num1"), Constant(2)]))]
)
ast._add_node(while_loop)
ast._add_node(while_loop_body)

ast._add_edges_from(
[
(root, init_code_node),
(root, while_loop),
(while_loop, while_loop_body),
(while_loop_body, if_condition),
(while_loop_body, while_loop_iteration),
]
)

WhileLoopReplacer(ast, _generate_options()).run()
assert not any(isinstance(loop_node, ForLoopNode) for loop_node in list(ast.get_loop_nodes_post_order()))

0 comments on commit 0c2d455

Please sign in to comment.