diff options
| author | blasty <blasty@local> | 2026-07-23 21:47:40 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-23 21:47:40 +0200 |
| commit | a0c90c11f2e73ea2f01b4b8c22efde596f5d3553 (patch) | |
| tree | 209924cd09b89659291eb1b50a14a0d499dbc83f /tests | |
| parent | listing: restore full-segment search load (find every match) (diff) | |
| download | ida-tui-a0c90c11f2e73ea2f01b4b8c22efde596f5d3553.tar.gz ida-tui-a0c90c11f2e73ea2f01b4b8c22efde596f5d3553.tar.xz ida-tui-a0c90c11f2e73ea2f01b4b8c22efde596f5d3553.zip | |
fix: don't let a late navigation steal focus from an open prompt
Real, data-loss-capable bug: opening a function that is already the current one
(e.g. after scrolling away from it) schedules an async re-navigation. If the user
opens the search prompt ('/') before that navigation lands, the navigation's
_show_active() called lst.focus() and yanked focus OUT of the search box. The
next typed characters then routed to the listing as verbs -- and 'u' = undefine,
silently deleting a function. (This is what produced the flaky
"search finds nothing" + "no function for <ea>" cascade in the pilot.)
Fix: _show_active() no longer grabs focus for the code view while any prompt
overlay (search/rename/comment/retype/goto/func-filter) is visible -- those own
the keyboard until dismissed. View visibility is unchanged; only the focus grab
is suppressed.
Also harden the pilot's open(): wait for the listing cursor to actually LAND on
the target address, not merely for _cur.ea to match (which is stale-true when
re-opening the same function), so tests can't proceed on a not-yet-moved cursor.
Verified: the exact failing order disasm_nav->search->follow_xrefs is green;
broad focus-sensitive sweep (startup/disasm_nav/view_toggle/hex/search/rename/
comment_func/retype/follow_xrefs/decomp_nav/mouse/listing*/continuous_view/
func_banners/region_define) 89/0.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_scenarios.py | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py index f72e340..7372c02 100644 --- a/tests/test_scenarios.py +++ b/tests/test_scenarios.py @@ -164,8 +164,12 @@ class Ctx: raise RuntimeError(f"no function for {target!r}") self.app._open_function(fn.addr, fn.name) await self.wait(lambda: self.app._cur and self.app._cur.ea == fn.addr, t) + # Wait for the cursor to actually LAND on the target, not merely for + # _cur.ea to match: re-opening a function we already navigated to (its + # _cur.ea is stale-true) schedules an async re-navigation, and proceeding + # before it lands would leave the cursor parked wherever we last were. await self.wait(lambda: self.lst.total > 0 - and self.lst._cursor_ea() is not None, t) + and self.lst._cursor_ea() == fn.addr, t) if view == "decomp": self.lst.focus() await self.press("tab") # F5/Tab -> decompile the function at cursor |
