summaryrefslogtreecommitdiffstats
path: root/idatui
diff options
context:
space:
mode:
authorblasty <peter@haxx.in>2026-07-23 00:49:06 +0200
committerblasty <peter@haxx.in>2026-07-23 00:49:06 +0200
commit80311f5f7fa57cb8f7487a1fb1fdd59735adc7de (patch)
treeece48f4bb119c00c77a31a26707dc6368e87978b /idatui
parentperf: read_raw tool — bulk byte reads for the hex view (5–8x) (diff)
downloadida-tui-80311f5f7fa57cb8f7487a1fb1fdd59735adc7de.tar.gz
ida-tui-80311f5f7fa57cb8f7487a1fb1fdd59735adc7de.tar.xz
ida-tui-80311f5f7fa57cb8f7487a1fb1fdd59735adc7de.zip
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_<ADDR>` 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.
Diffstat (limited to 'idatui')
-rw-r--r--idatui/app.py2
-rw-r--r--idatui/domain.py9
2 files changed, 10 insertions, 1 deletions
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)