From dda12752c2b2e5717982beeccbebb5aab8865ff1 Mon Sep 17 00:00:00 2001 From: Gary Feng <104392015+gfeng-certik@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:41:17 -0500 Subject: [PATCH] fix: finish connecting true-statement node to end-if node before connecting condition node to false-statement node (#23) - fixes the issue with wrong if-statement CFG when the then-clause is empty. https://github.com/CertiKProject/slither-task/issues/241 --- slither/solc_parsing/declarations/function.py | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/slither/solc_parsing/declarations/function.py b/slither/solc_parsing/declarations/function.py index d1465bb0f9..070b5fcdb2 100644 --- a/slither/solc_parsing/declarations/function.py +++ b/slither/solc_parsing/declarations/function.py @@ -362,7 +362,7 @@ def _new_yul_block( def _parse_if(self, if_statement: Dict, node: NodeSolc) -> NodeSolc: # IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )? - falseStatement = None + false_body = None if self.is_compact_ast: condition = if_statement["condition"] @@ -379,13 +379,9 @@ def _parse_if(self, if_statement: Dict, node: NodeSolc) -> NodeSolc: trueStatement = self._parse_statement( if_statement["trueBody"], condition_node, true_scope ) + if "falseBody" in if_statement and if_statement["falseBody"]: - false_scope = Scope( - node.underlying_node.scope.is_checked, False, node.underlying_node.scope - ) - falseStatement = self._parse_statement( - if_statement["falseBody"], condition_node, false_scope - ) + false_body = if_statement["falseBody"] else: children = if_statement[self.get_children("children")] condition = children[0] @@ -400,19 +396,22 @@ def _parse_if(self, if_statement: Dict, node: NodeSolc) -> NodeSolc: node.underlying_node.scope.is_checked, False, node.underlying_node.scope ) trueStatement = self._parse_statement(children[1], condition_node, true_scope) + if len(children) == 3: - false_scope = Scope( - node.underlying_node.scope.is_checked, False, node.underlying_node.scope - ) - falseStatement = self._parse_statement(children[2], condition_node, false_scope) + false_body = children[2] endIf_node = self._new_node(NodeType.ENDIF, if_statement["src"], node.underlying_node.scope) link_underlying_nodes(trueStatement, endIf_node) - if falseStatement: + if false_body: + false_scope = Scope( + node.underlying_node.scope.is_checked, False, node.underlying_node.scope + ) + falseStatement = self._parse_statement(false_body, condition_node, false_scope) link_underlying_nodes(falseStatement, endIf_node) else: link_underlying_nodes(condition_node, endIf_node) + return endIf_node def _parse_while(self, whilte_statement: Dict, node: NodeSolc) -> NodeSolc: