From cf4007b3824ba170699efd6ffbc3c065ecb10669 Mon Sep 17 00:00:00 2001 From: blasty Date: Thu, 23 Jul 2026 00:49:06 +0200 Subject: fix: crash on an unnamed function (None name) in the symbol palette `Ctrl+N` then typing crashed with `AttributeError: 'NoneType' object has no attribute 'lower'` when a function had no name: Func.from_raw took `d["name"]` verbatim, so a server-returned null/missing name became None and blew up _fuzzy (and would break sort/rename-prefill too). Two-layer fix: * Func.from_raw synthesizes IDA's `sub_` for a null/empty/missing name (and tolerates a missing size) so `name` is always a str for every consumer; and * _fuzzy guards against a falsy name defensively. Verified: Func.from_raw({addr, name:null}) -> "sub_1000"; _fuzzy(None,'m') -> None (no raise). Pilot palette + startup 9/0. --- idatui/app.py | 2 ++ idatui/domain.py | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/idatui/app.py b/idatui/app.py index 7bca4e0..38d2411 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -1581,6 +1581,8 @@ def _fuzzy(name: str, q: str): matched character indices (for highlighting).""" if not q: return (0.0, ()) + if not name: # defensive: never assume a symbol has a name + return None nl = name.lower() pos: list[int] = [] i = 0 diff --git a/idatui/domain.py b/idatui/domain.py index 31cb82d..0d5d0aa 100644 --- a/idatui/domain.py +++ b/idatui/domain.py @@ -58,7 +58,14 @@ class Func: @classmethod def from_raw(cls, d: dict) -> "Func": - return cls(addr=_as_int(d["addr"]), name=d["name"], size=_as_int(d["size"])) + addr = _as_int(d["addr"]) + name = d.get("name") + # An unnamed function (server returns null/empty) must still have a + # usable string name — synthesize IDA's sub_ADDR so every consumer + # (palette, sort, rename prefill) can treat name as a str. + if not name: + name = f"sub_{addr:X}" + return cls(addr=addr, name=name, size=_as_int(d.get("size", 0))) @dataclass(frozen=True) -- cgit v1.3.1-sl0p