From 5096292cadb939d7b0813eb0bed91cdce3a28dcf Mon Sep 17 00:00:00 2001 From: Kevin Phoenix Date: Mon, 1 Jun 2026 12:29:33 -0700 Subject: [PATCH] Fix IR field types: statement labels/targets are ints, not statements The following IR fields were annotated as SootStmt or str but the actual runtime values are int (sequential statement indices used as labels): - SootBlock.label: str -> int - GotoStmt.target: SootStmt -> int - IfStmt.target: SootStmt -> int - LookupSwitchStmt.lookup_values_and_targets values: SootStmt -> int - LookupSwitchStmt.default_target: SootStmt -> int - TableSwitchStmt.targets: tuple[SootStmt, ...] -> tuple[int, ...] - TableSwitchStmt.lookup_values_and_targets values: SootStmt -> int - TableSwitchStmt.default_target: SootStmt -> int Cross-referenced angr's usage to confirm these are always treated as ints: e.g. cfg_fast_soot.py does `method.block_by_label[stmt.target]` (dict lookup keyed by label) and `block.label + len(block.statements)` (arithmetic). Co-Authored-By: Claude Opus 4.7 (1M context) --- pysoot/sootir/soot_block.py | 2 +- pysoot/sootir/soot_statement.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pysoot/sootir/soot_block.py b/pysoot/sootir/soot_block.py index 50e7b66..664324e 100644 --- a/pysoot/sootir/soot_block.py +++ b/pysoot/sootir/soot_block.py @@ -7,7 +7,7 @@ @dataclass(slots=True, unsafe_hash=True) class SootBlock: - label: str + label: int statements: tuple[SootStmt, ...] idx: int | None diff --git a/pysoot/sootir/soot_statement.py b/pysoot/sootir/soot_statement.py index 74c214e..d570bbf 100644 --- a/pysoot/sootir/soot_statement.py +++ b/pysoot/sootir/soot_statement.py @@ -104,7 +104,7 @@ def from_ir(label, offset, ir_stmt, stmt_map=None): @dataclass(slots=True, unsafe_hash=True) class GotoStmt(SootStmt): - target: SootStmt + target: int def __str__(self): return f"goto {self.target}" @@ -117,7 +117,7 @@ def from_ir(label, offset, ir_stmt, stmt_map=None): @dataclass(slots=True, unsafe_hash=True) class IfStmt(SootStmt): condition: SootValue - target: SootStmt + target: int def __str__(self): return f"if({str(self.condition)}) goto {str(self.target)}" @@ -169,8 +169,8 @@ def from_ir(label, offset, ir_stmt, stmt_map=None): @dataclass(slots=True, unsafe_hash=True) class LookupSwitchStmt(SootStmt): key: SootValue - lookup_values_and_targets: frozendict[int, SootStmt] - default_target: SootStmt + lookup_values_and_targets: frozendict[int, int] + default_target: int def __str__(self): targets = repr(self.lookup_values_and_targets) @@ -197,9 +197,9 @@ class TableSwitchStmt(SootStmt): key: SootValue low_index: int high_index: int - targets: tuple[SootStmt, ...] - lookup_values_and_targets: frozendict[int, SootStmt] - default_target: SootStmt + targets: tuple[int, ...] + lookup_values_and_targets: frozendict[int, int] + default_target: int def __str__(self): targets = repr(self.lookup_values_and_targets)