diff options
| -rw-r--r-- | idatui/app.py | 12 | ||||
| -rw-r--r-- | tests/test_scenarios.py | 9 |
2 files changed, 18 insertions, 3 deletions
diff --git a/idatui/app.py b/idatui/app.py index 4bba7df..eacdbe8 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -2048,9 +2048,15 @@ def _fuzzy(name: str, q: str): if not name: # defensive: never assume a symbol has a name return None nl = name.lower() + # Case-insensitive means BOTH sides: the name was lowered but the query + # wasn't, so a single capital could never match and any query containing one + # returned nothing at all. Invisible on lowercase C symbols (main, strlen), + # fatal on libraries that capitalise — "PEM_read_bio" found 0 of 10093 + # functions in libcrypto while the backend resolved it fine. + ql = q.lower() pos: list[int] = [] i = 0 - for ch in q: + for ch in ql: j = nl.find(ch, i) if j < 0: return None @@ -2058,9 +2064,9 @@ def _fuzzy(name: str, q: str): i = j + 1 span = pos[-1] - pos[0] score = -(span * 2.0) - pos[0] - len(name) * 0.01 - if q in nl: + if ql in nl: score += 50.0 - if nl.startswith(q): + if nl.startswith(ql): score += 100.0 return (score, tuple(pos)) diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py index 091ddc8..4024c07 100644 --- a/tests/test_scenarios.py +++ b/tests/test_scenarios.py @@ -309,6 +309,15 @@ async def s_palette(c: Ctx): c.check("palette matches a fuzzy subsequence", any(n == "error" for _, _, n in pal._results), f"results={[n for _, _, n in pal._results[:4]]}") + # Every other query here is lowercase, which is how a case bug hid for so + # long: the name was lowered but the query wasn't, so ONE capital matched + # nothing. Invisible on lowercase C symbols, fatal on a library that + # capitalises (PEM_read_bio found 0 of 10093 functions in libcrypto). + pinp.value = "MAIN" + await c.wait(lambda: any(n == "main" for _, _, n in pal._results), 10) + c.check("palette matching is case-insensitive in BOTH directions", + any(n == "main" for _, _, n in pal._results), + f"results={[n for _, _, n in pal._results[:4]]}") pinp.value = "main" await c.wait(lambda: pal._results and pal._results[0][2] == "main", 10) want = pal._results[0][1] |
