Redesign `utils.upgradeability.is_function_modified`

Due to the non-deterministic order of `Function.all_nodes()`
pull/1757/head
webthethird 2 years ago
parent a6d49d52f3
commit 3655708367
  1. 15
      slither/utils/upgradeability.py

@ -11,6 +11,7 @@ from slither.core.expressions.assignment_operation import AssignmentOperation
from slither.core.cfg.node import Node, NodeType from slither.core.cfg.node import Node, NodeType
from slither.slithir.operations import LowLevelCall from slither.slithir.operations import LowLevelCall
from slither.tools.read_storage.read_storage import SlotInfo, SlitherReadStorage from slither.tools.read_storage.read_storage import SlotInfo, SlitherReadStorage
from slither.tools.similarity.encode import encode_ir
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
@ -126,9 +127,17 @@ def is_function_modified(f1: Function, f2: Function) -> bool:
return False return False
# If the hashes differ, it is possible a change in a name or in a comment could be the only difference # If the hashes differ, it is possible a change in a name or in a comment could be the only difference
# So we need to resort to walking through the CFG and comparing the IR operations # So we need to resort to walking through the CFG and comparing the IR operations
for i, node in enumerate(f2.nodes): queue_f1 = [f1.entry_point]
for j, ir in enumerate(node.irs): queue_f2 = [f2.entry_point]
if ir != f1.nodes[i].irs[j]: visited = []
while len(queue_f1) > 0 and len(queue_f2) > 0:
node_f1 = queue_f1.pop(0)
node_f2 = queue_f2.pop(0)
visited.extend([node_f1, node_f2])
queue_f1.extend(son for son in node_f1.sons if son not in visited)
queue_f2.extend(son for son in node_f2.sons if son not in visited)
for i, ir in enumerate(node_f1.irs):
if encode_ir(ir) != encode_ir(node_f2.irs[i]):
return True return True
return False return False

Loading…
Cancel
Save