Skip to content

Commit 228febc

Browse files
committed
tests: Improve pretty printer testing
1 parent 87cf359 commit 228febc

File tree

1 file changed

+123
-1
lines changed

1 file changed

+123
-1
lines changed

tests/test_pypcode.py

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
import gc
55
import logging
66
from unittest import main, TestCase
7-
from typing import List
7+
from unittest.mock import create_autospec
8+
from typing import cast, List
89

910
from pypcode import (
11+
AddrSpace,
1012
Arch,
1113
ArchLanguage,
1214
BadDataError,
@@ -17,7 +19,9 @@
1719
TranslateFlags,
1820
Translation,
1921
UnimplError,
22+
Varnode,
2023
)
24+
from pypcode.printing import OpFormat, PcodePrettyPrinter
2125

2226
# logging.basicConfig(level=logging.DEBUG)
2327
log = logging.getLogger(__name__)
@@ -315,5 +319,123 @@ def test_pretty_printing(self):
315319
assert "RAX = RAX ^ RAX" in str(tx)
316320

317321

322+
class PrintingTests(TestCase):
323+
"""
324+
Pretty printing tests.
325+
"""
326+
327+
def test_branches(self):
328+
for opc, output in [
329+
(OpCode.BRANCH, "goto ram[123:4]"),
330+
(OpCode.BRANCHIND, "goto [ram[123:4]]"),
331+
(OpCode.CALL, "call ram[123:4]"),
332+
(OpCode.CALLIND, "call [ram[123:4]]"),
333+
(OpCode.RETURN, "return ram[123:4]"),
334+
]:
335+
vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
336+
vn.space.name = "ram"
337+
vn.offset = 0x123
338+
vn.size = 4
339+
340+
op = cast(PcodeOp, create_autospec(PcodeOp, instance=True, spec_set=True))
341+
op.opcode = opc
342+
op.output = None
343+
op.inputs = [vn]
344+
345+
assert PcodePrettyPrinter.fmt_op(op) == output
346+
347+
def test_cbranch(self):
348+
target_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
349+
target_vn.space.name = "ram"
350+
target_vn.offset = 0x456
351+
target_vn.size = 4
352+
353+
cond_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
354+
cond_vn.space.name = "ram"
355+
cond_vn.offset = 0x123
356+
cond_vn.size = 1
357+
358+
op = cast(PcodeOp, create_autospec(PcodeOp, instance=True, spec_set=True))
359+
op.opcode = OpCode.CBRANCH
360+
op.output = None
361+
op.inputs = [target_vn, cond_vn]
362+
363+
assert PcodePrettyPrinter.fmt_op(op) == "if (ram[123:1]) goto ram[456:4]"
364+
365+
def test_load(self):
366+
dest_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
367+
dest_vn.space.name = "ram"
368+
dest_vn.offset = 0x123
369+
dest_vn.size = 1
370+
371+
space = cast(AddrSpace, create_autospec(AddrSpace, instance=True, spec_set=True))
372+
space.name = "ram"
373+
374+
space_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
375+
space_vn.space.name = "const"
376+
space_vn.getSpaceFromConst.return_value = space
377+
378+
offset_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
379+
offset_vn.space.name = "const"
380+
offset_vn.offset = 0x456
381+
offset_vn.size = 1
382+
383+
op = cast(PcodeOp, create_autospec(PcodeOp, instance=True, spec_set=True))
384+
op.opcode = OpCode.LOAD
385+
op.output = dest_vn
386+
op.inputs = [space_vn, offset_vn]
387+
388+
assert PcodePrettyPrinter.fmt_op(op) == "ram[123:1] = *[ram]0x456"
389+
390+
def test_store(self):
391+
space = cast(AddrSpace, create_autospec(AddrSpace, instance=True, spec_set=True))
392+
space.name = "ram"
393+
394+
space_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
395+
space_vn.space.name = "const"
396+
space_vn.getSpaceFromConst.return_value = space
397+
398+
offset_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
399+
offset_vn.space.name = "const"
400+
offset_vn.offset = 0x123
401+
offset_vn.size = 1
402+
403+
value_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
404+
value_vn.space.name = "const"
405+
value_vn.offset = 0x456
406+
value_vn.size = 1
407+
408+
op = cast(PcodeOp, create_autospec(PcodeOp, instance=True, spec_set=True))
409+
op.opcode = OpCode.STORE
410+
op.output = None
411+
op.inputs = [space_vn, offset_vn, value_vn]
412+
413+
assert PcodePrettyPrinter.fmt_op(op) == "*[ram]0x123 = 0x456"
414+
415+
def test_callother(self):
416+
target_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
417+
target_vn.getUserDefinedOpName.return_value = "udop"
418+
419+
arg_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
420+
arg_vn.space.name = "const"
421+
arg_vn.offset = 0x456
422+
arg_vn.size = 1
423+
424+
op = cast(PcodeOp, create_autospec(PcodeOp, instance=True, spec_set=True))
425+
op.opcode = OpCode.CALLOTHER
426+
op.output = None
427+
op.inputs = [target_vn, arg_vn]
428+
429+
assert PcodePrettyPrinter.fmt_op(op) == "udop(0x456)"
430+
431+
def test_no_regname(self):
432+
arg_vn = cast(Varnode, create_autospec(Varnode, instance=True, spec_set=True))
433+
arg_vn.space.name = "register"
434+
arg_vn.offset = 0x123
435+
arg_vn.size = 4
436+
arg_vn.getRegisterName.return_value = None
437+
assert OpFormat.fmt_vn(arg_vn) == "register[123:4]"
438+
439+
318440
if __name__ == "__main__":
319441
main()

0 commit comments

Comments
 (0)