draugr.git


draugr

~ single ELF file analysis tool
git clone https://github.com/djnnvx/draugr.git
log | files | refs | archive | README

call_test.odin (2923B)

      1 package analysis
      2 
      3 import "core:fmt"
      4 import "core:testing"
      5 
      6 @(test)
      7 test_call_args_default_to_zero :: proc(t: ^testing.T) {
      8 	args, err := parse_call_args("")
      9 	defer delete(args)
     10 
     11 	testing.expect_value(t, err, "")
     12 	testing.expect_value(t, len(args), 6)
     13 	for a in args {
     14 		testing.expect_value(t, a, 0)
     15 	}
     16 }
     17 
     18 @(test)
     19 test_call_args_parse_decimal_and_hex :: proc(t: ^testing.T) {
     20 	args, err := parse_call_args("42, 0x2a, -1")
     21 	defer delete(args)
     22 
     23 	testing.expect_value(t, err, "")
     24 	testing.expect_value(t, args[0], 42)
     25 	testing.expect_value(t, args[1], 42)
     26 	testing.expect_value(t, i64(args[2]), -1)
     27 	testing.expect_value(t, args[3], 0)
     28 }
     29 
     30 @(test)
     31 test_call_args_string_becomes_a_pointer :: proc(t: ^testing.T) {
     32 	args, err := parse_call_args("s:hello")
     33 	defer delete(args)
     34 
     35 	testing.expect_value(t, err, "")
     36 	testing.expect(t, args[0] != 0, "s: argument must produce a non-null pointer")
     37 
     38 	str := cstring(rawptr(uintptr(args[0])))
     39 	testing.expect_value(t, string(str), "hello")
     40 }
     41 
     42 @(test)
     43 test_call_args_reject_junk_and_overflow :: proc(t: ^testing.T) {
     44 	junk, err := parse_call_args("notanumber")
     45 	defer delete(junk)
     46 	testing.expect(t, err != "", "non-numeric argument must be rejected")
     47 
     48 	too_many, err2 := parse_call_args("1,2,3,4,5,6,7")
     49 	defer delete(too_many)
     50 	testing.expect(t, err2 != "", "more than 6 arguments must be rejected")
     51 }
     52 
     53 @(test)
     54 test_parse_patches :: proc(t: ^testing.T) {
     55 	patches, err := parse_patches("got:puts=my_puts; secret=ret:1; hook=jmp:repl")
     56 	defer delete(patches)
     57 
     58 	testing.expect_value(t, err, "")
     59 	testing.expect_value(t, len(patches), 3)
     60 
     61 	testing.expect_value(t, patches[0].kind, Patch_Kind.Got)
     62 	testing.expect_value(t, patches[0].target, "puts")
     63 	testing.expect_value(t, patches[0].repl, "my_puts")
     64 
     65 	testing.expect_value(t, patches[1].kind, Patch_Kind.Ret)
     66 	testing.expect_value(t, patches[1].target, "secret")
     67 	testing.expect_value(t, patches[1].value, 1)
     68 
     69 	testing.expect_value(t, patches[2].kind, Patch_Kind.Jmp)
     70 	testing.expect_value(t, patches[2].target, "hook")
     71 	testing.expect_value(t, patches[2].repl, "repl")
     72 
     73 	empty, eerr := parse_patches("")
     74 	defer delete(empty)
     75 	testing.expect_value(t, eerr, "")
     76 	testing.expect_value(t, len(empty), 0)
     77 }
     78 
     79 @(test)
     80 test_parse_patches_rejects_junk :: proc(t: ^testing.T) {
     81 	cases := []string{"noequalssign", "f=ret:", "f=ret:xyz", "got:=target", "f=bogus:1"}
     82 	for c in cases {
     83 		p, err := parse_patches(c)
     84 		defer delete(p)
     85 		testing.expect(t, err != "", fmt.tprintf("spec %q must be rejected", c))
     86 	}
     87 }
     88 
     89 @(test)
     90 test_report_status_maps_exit_and_signal :: proc(t: ^testing.T) {
     91 	testing.expect_value(t, report_status(0), "")
     92 	testing.expect_value(t, report_status(101 << 8), "dlopen failed, see above")
     93 	testing.expect_value(t, report_status(102 << 8), "symbol not found, see above")
     94 	testing.expect(t, report_status(3 << 8) != "", "a non-zero exit must be an error")
     95 	testing.expect_value(t, report_status(11), "callee died on signal 11")
     96 }