aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--idatui/app.py12
-rw-r--r--tests/test_scenarios.py32
2 files changed, 42 insertions, 2 deletions
diff --git a/idatui/app.py b/idatui/app.py
index 086785c..8fc259e 100644
--- a/idatui/app.py
+++ b/idatui/app.py
@@ -2380,14 +2380,22 @@ class IdaTui(App):
def on_comment_requested(self, msg: CommentRequested) -> None:
ea = self._line_ea_for(msg.view)
+ # Signature / local-declaration lines carry no address; fall back to the
+ # function's entry ea so commenting the header annotates the function.
+ func_level = ea is None
+ if func_level:
+ ea = self._cur.ea if self._cur else None
if ea is None:
self._status("no address on this line to comment")
return
- existing = self._existing_comment(msg.view)
+ existing = "" if func_level else self._existing_comment(msg.view)
self._comment_ctx = (msg.view, ea, existing)
self.query_one("#status", Static).display = False
inp = self.query_one("#comment", Input)
- inp.placeholder = f"comment @ {ea:#x} — Enter=apply (empty=clear) Esc=cancel"
+ inp.placeholder = (
+ f"function comment @ {ea:#x} — Enter=apply (empty=clear) Esc=cancel"
+ if func_level else
+ f"comment @ {ea:#x} — Enter=apply (empty=clear) Esc=cancel")
inp.can_focus = True
inp.display = True
inp.value = existing
diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py
index 0b22f90..0cad008 100644
--- a/tests/test_scenarios.py
+++ b/tests/test_scenarios.py
@@ -1046,6 +1046,38 @@ async def s_rename(c: Ctx):
c.check("found a pseudocode line to comment", False, "no marker line")
+@scenario("comment_func")
+async def s_comment_func(c: Ctx):
+ # Commenting the signature/declaration line (which carries no address) falls
+ # back to a function-level comment at the entry ea instead of being refused.
+ app, dec = c.app, c.dec
+ pick = c.pick_decomp_ref()
+ if pick is None:
+ c.check("found a function for the comment test", False)
+ return
+ fn = pick[0]
+ await c.open(fn.addr, "decomp")
+ dec.focus()
+ dec.cursor, dec.cursor_x = 0, 2 # the signature line
+ dec.refresh()
+ await c.pause(0.05)
+ c.check("signature line has no address of its own", dec._line_ea(0) is None,
+ f"ea={dec._line_ea(0)}")
+ await c.press("semicolon")
+ await c.pause(0.1)
+ ci = app.query_one("#comment", Input)
+ note = f"fn_note_{os.getpid()}"
+ c.check("';' on the signature line opens a function-comment prompt",
+ ci.display and "function comment" in str(ci.placeholder).lower(),
+ f"display={ci.display} ph={ci.placeholder!r}")
+ ci.value = note
+ await c.press("enter")
+ await c.wait(lambda: dec.loaded_ea == fn.addr and any(note in t for t in dec._texts), 25)
+ c.check("function comment appears in the pseudocode",
+ any(note in t for t in dec._texts), "not shown")
+ app.program.client.call("set_comments", items=[{"addr": hex(fn.addr), "comment": ""}])
+
+
@scenario("retype")
async def s_retype(c: Ctx):
app, dec = c.app, c.dec