From 02d02417800184fb76cd0245cdaa94c437aa4081 Mon Sep 17 00:00:00 2001 From: blasty Date: Fri, 21 Aug 2026 12:14:46 +0200 Subject: reformat: ruff format + import sort, mechanically (see ruff.toml) No behavior. Listed in .git-blame-ignore-revs (next commit). --- tests/test_rawimage_rpc.py | 198 +++++++++++++++++++++++++++++++-------------- 1 file changed, 139 insertions(+), 59 deletions(-) (limited to 'tests/test_rawimage_rpc.py') diff --git a/tests/test_rawimage_rpc.py b/tests/test_rawimage_rpc.py index d39ad35..a6e7661 100644 --- a/tests/test_rawimage_rpc.py +++ b/tests/test_rawimage_rpc.py @@ -36,7 +36,7 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from idatui.rpcclient import RpcClient, RpcError # noqa: E402 REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -BLOB = os.path.join(REPO, "experiments", "fibonacci.bin") # real Thumb code +BLOB = os.path.join(REPO, "experiments", "fibonacci.bin") # real Thumb code PASS = FAIL = 0 @@ -52,11 +52,24 @@ def check(name, ok, detail=""): def spawn_pane(target, processor, timeout=420): - cmd = [sys.executable, "-m", "idatui.pane", "spawn", "--open", target, - "--processor", processor, "--detached", "--size", "60%", - "--timeout", str(timeout)] - r = subprocess.run(cmd, capture_output=True, text=True, - timeout=timeout + 60, cwd=REPO) + cmd = [ + sys.executable, + "-m", + "idatui.pane", + "spawn", + "--open", + target, + "--processor", + processor, + "--detached", + "--size", + "60%", + "--timeout", + str(timeout), + ] + r = subprocess.run( + cmd, capture_output=True, text=True, timeout=timeout + 60, cwd=REPO + ) if not r.stdout.strip(): print(f" spawn produced no JSON: {r.stderr.strip()}", file=sys.stderr) return None @@ -64,9 +77,22 @@ def spawn_pane(target, processor, timeout=420): def stop_pane(sock, timeout=60): - subprocess.run([sys.executable, "-m", "idatui.pane", "stop", "--sock", sock, - "--timeout", str(timeout)], - capture_output=True, text=True, timeout=timeout + 10, cwd=REPO) + subprocess.run( + [ + sys.executable, + "-m", + "idatui.pane", + "stop", + "--sock", + sock, + "--timeout", + str(timeout), + ], + capture_output=True, + text=True, + timeout=timeout + 10, + cwd=REPO, + ) def main() -> int: @@ -94,34 +120,44 @@ def main() -> int: # -- load options actually reached IDA --------------------------- # # Wrong processor => the disassembly is nonsense or absent; ARMv7-A # also means a 32-bit database, without which Hex-Rays refuses. - check("spawn forwarded --processor", info.get("ok"), - json.dumps(info)) + check("spawn forwarded --processor", info.get("ok"), json.dumps(info)) with RpcClient(sock) as c: st = c.call("state") - check("pane is drivable", st.get("active") in - ("listing", "decomp", "hex"), json.dumps(st)[:200]) + check( + "pane is drivable", + st.get("active") in ("listing", "decomp", "hex"), + json.dumps(st)[:200], + ) # -- define ------------------------------------------------- # # fibonacci.bin is Thumb at 0x0; as ARM it does not decode. r = c.call("define", kind="thumb", target="0x0") d = r.get("define", {}) check("define thumb ran", "define" in r, json.dumps(r)[:200]) - check("define thumb decoded instructions", - "instruction" in d.get("status", ""), d.get("status", "")) + check( + "define thumb decoded instructions", + "instruction" in d.get("status", ""), + d.get("status", ""), + ) r = c.call("define", kind="func", target="0x0") - check("define func created a function", - "function" in r["define"]["status"] - or "already" in r["define"]["status"], - r["define"]["status"]) + check( + "define func created a function", + "function" in r["define"]["status"] + or "already" in r["define"]["status"], + r["define"]["status"], + ) bad = None try: c.call("define", kind="nonsense") except RpcError as e: bad = str(e) - check("define rejects an unknown kind", bad is not None - and "unknown define kind" in bad, str(bad)) + check( + "define rejects an unknown kind", + bad is not None and "unknown define kind" in bad, + str(bad), + ) # -- opfmt (how a literal is displayed) --------------------- # # Thumb code is full of small immediates -- the thing 'o' exists @@ -134,21 +170,31 @@ def main() -> int: lit = None for ln in seen: m = re.match(r"([0-9A-F]{8})\s+(.*)", ln.get("text", "")) - if not (m and re.search(r"#(0x[0-9A-Fa-f]{2,}|[1-9]\d+)\b", - m.group(2))): + if not ( + m and re.search(r"#(0x[0-9A-Fa-f]{2,}|[1-9]\d+)\b", m.group(2)) + ): continue ea_s = "0x" + m.group(1) - st = c.call("opfmt", mode="show", target=ea_s, delay_ms=0 - ).get("opfmt", {}).get("status", "") + st = ( + c.call("opfmt", mode="show", target=ea_s, delay_ms=0) + .get("opfmt", {}) + .get("status", "") + ) if "no literal" not in st: lit = (ea_s, st) break - check("the blob has an immediate to reformat", lit is not None, - json.dumps([ln.get("text") for ln in seen[:8]])) + check( + "the blob has an immediate to reformat", + lit is not None, + json.dumps([ln.get("text") for ln in seen[:8]]), + ) if lit is not None: tgt, st0 = lit - check("opfmt show reports the stops without editing", - "[" in st0 and "dec" in st0, st0) + check( + "opfmt show reports the stops without editing", + "[" in st0 and "dec" in st0, + st0, + ) r = c.call("opfmt", mode="dec", target=tgt, delay_ms=0) st1 = r.get("opfmt", {}).get("status", "") check("opfmt sets a named format", "dec" in st1, st1) @@ -156,16 +202,21 @@ def main() -> int: st2 = r.get("opfmt", {}).get("status", "") check("opfmt cycles on from there", "\u2192" in st2, st2) r = c.call("opfmt", mode="default") - check("opfmt hands the operand back to IDA", - "default" in r.get("opfmt", {}).get("status", ""), - r.get("opfmt", {}).get("status", "")) + check( + "opfmt hands the operand back to IDA", + "default" in r.get("opfmt", {}).get("status", ""), + r.get("opfmt", {}).get("status", ""), + ) badfmt = None try: c.call("opfmt", mode="roman") except RpcError as e: badfmt = str(e) - check("opfmt rejects an unknown mode", badfmt is not None - and "unknown opfmt mode" in badfmt, str(badfmt)) + check( + "opfmt rejects an unknown mode", + badfmt is not None and "unknown opfmt mode" in badfmt, + str(badfmt), + ) # -- rename_many -------------------------------------------- # fns = c.call("functions", limit=200) @@ -177,28 +228,48 @@ def main() -> int: # 'start' (not 'addr') on purpose: symbol files in the wild # use it, and accepting only one spelling is how a bulk # import silently renames nothing. - json.dump([{"start": hex(ea), "name": "bulk_named_fn"}, - {"start": "0xdeadbe", "name": "nowhere"}], f) + json.dump( + [ + {"start": hex(ea), "name": "bulk_named_fn"}, + {"start": "0xdeadbe", "name": "nowhere"}, + ], + f, + ) r = c.call("rename_many", file=symfile) m = r.get("rename_many", {}) - check("rename_many applied the good entry", m.get("ok") == 1, - json.dumps(m)) - check("rename_many reports the bad entry", - m.get("failed") == 1 and m.get("errors"), json.dumps(m)) + check( + "rename_many applied the good entry", + m.get("ok") == 1, + json.dumps(m), + ) + check( + "rename_many reports the bad entry", + m.get("failed") == 1 and m.get("errors"), + json.dumps(m), + ) # The readback matters more than the return value: a driver # trusts resolve/functions to decide what work is left. - check("renamed symbol resolves", - c.call("resolve", name="bulk_named_fn").get("ea") == ea, - json.dumps(c.call("resolve", name="bulk_named_fn"))) + check( + "renamed symbol resolves", + c.call("resolve", name="bulk_named_fn").get("ea") == ea, + json.dumps(c.call("resolve", name="bulk_named_fn")), + ) names = {f["name"] for f in c.call("functions", limit=200)} - check("function table shows the new name", - "bulk_named_fn" in names, str(sorted(names)[:10])) - - r = c.call("rename_many", items=[{"addr": hex(ea), - "name": "inline_named_fn"}]) - check("rename_many takes inline items", - r["rename_many"]["ok"] == 1, json.dumps(r["rename_many"])) + check( + "function table shows the new name", + "bulk_named_fn" in names, + str(sorted(names)[:10]), + ) + + r = c.call( + "rename_many", items=[{"addr": hex(ea), "name": "inline_named_fn"}] + ) + check( + "rename_many takes inline items", + r["rename_many"]["ok"] == 1, + json.dumps(r["rename_many"]), + ) # -- the stale-pseudocode trap ------------------------------ # # Hex-Rays caches per function and does not notice that a @@ -208,22 +279,31 @@ def main() -> int: # the function's own body cites it.) before = c.call("pseudocode", target=hex(ea)) pc_before = json.dumps(before) - r = c.call("rename_many", items=[{"addr": hex(ea), - "name": "after_cache_fn"}]) + r = c.call( + "rename_many", items=[{"addr": hex(ea), "name": "after_cache_fn"}] + ) pc_after = json.dumps(c.call("pseudocode", target=hex(ea))) - check("pseudocode was cached before the rename", - "inline_named_fn" in pc_before, pc_before[:200]) - check("rename_many invalidates the decompile cache", - "after_cache_fn" in pc_after - and "inline_named_fn" not in pc_after, pc_after[:300]) + check( + "pseudocode was cached before the rename", + "inline_named_fn" in pc_before, + pc_before[:200], + ) + check( + "rename_many invalidates the decompile cache", + "after_cache_fn" in pc_after and "inline_named_fn" not in pc_after, + pc_after[:300], + ) empty = None try: c.call("rename_many") except RpcError as e: empty = str(e) - check("rename_many without items errors", empty is not None - and "items" in empty, str(empty)) + check( + "rename_many without items errors", + empty is not None and "items" in empty, + str(empty), + ) finally: stop_pane(sock) -- cgit v1.3.1-sl0p