1require_relative 'test_base.rb' 2require 'dl/callback' 3require 'dl/func' 4require 'dl/pack' 5 6module DL 7class TestDL < TestBase 8 def ptr2num(*list) 9 list.pack("p*").unpack(PackInfo::PACK_MAP[TYPE_VOIDP] + "*") 10 end 11 12 # TODO: refactor test repetition 13 14 def test_free_secure 15 assert_raises(SecurityError) do 16 Thread.new do 17 $SAFE = 4 18 DL.free(0) 19 end.join 20 end 21 end 22 23 def test_realloc 24 str = "abc" 25 ptr_id = DL.realloc(0, 4) 26 ptr = CPtr.new(ptr_id, 4) 27 28 assert_equal ptr_id, ptr.to_i 29 30 cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy') 31 cfunc.call([ptr_id,str].pack("l!p").unpack("l!*")) 32 assert_equal("abc\0", ptr[0,4]) 33 DL.free ptr_id 34 end 35 36 def test_realloc_secure 37 assert_raises(SecurityError) do 38 Thread.new do 39 $SAFE = 4 40 DL.realloc(0, 4) 41 end.join 42 end 43 end 44 45 def test_malloc 46 str = "abc" 47 48 ptr_id = DL.malloc(4) 49 ptr = CPtr.new(ptr_id, 4) 50 51 assert_equal ptr_id, ptr.to_i 52 53 cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy') 54 cfunc.call([ptr_id,str].pack("l!p").unpack("l!*")) 55 assert_equal("abc\0", ptr[0,4]) 56 DL.free ptr_id 57 end 58 59 def test_malloc_security 60 assert_raises(SecurityError) do 61 Thread.new do 62 $SAFE = 4 63 DL.malloc(4) 64 end.join 65 end 66 end 67 68 def test_call_int() 69 cfunc = CFunc.new(@libc['atoi'], TYPE_INT, 'atoi') 70 x = cfunc.call(["100"].pack("p").unpack("l!*")) 71 assert_equal(100, x) 72 73 cfunc = CFunc.new(@libc['atoi'], TYPE_INT, 'atoi') 74 x = cfunc.call(["-100"].pack("p").unpack("l!*")) 75 assert_equal(-100, x) 76 end 77 78 def test_call_long() 79 cfunc = CFunc.new(@libc['atol'], TYPE_LONG, 'atol') 80 x = cfunc.call(["100"].pack("p").unpack("l!*")) 81 assert_equal(100, x) 82 cfunc = CFunc.new(@libc['atol'], TYPE_LONG, 'atol') 83 x = cfunc.call(["-100"].pack("p").unpack("l!*")) 84 assert_equal(-100, x) 85 end 86 87 def test_call_double() 88 cfunc = CFunc.new(@libc['atof'], TYPE_DOUBLE, 'atof') 89 x = cfunc.call(["0.1"].pack("p").unpack("l!*")) 90 assert_in_delta(0.1, x) 91 92 cfunc = CFunc.new(@libc['atof'], TYPE_DOUBLE, 'atof') 93 x = cfunc.call(["-0.1"].pack("p").unpack("l!*")) 94 assert_in_delta(-0.1, x) 95 end 96 97 def test_sin 98 return if /x86_64/ =~ RUBY_PLATFORM 99 pi_2 = Math::PI/2 100 cfunc = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'), 101 [TYPE_DOUBLE]) 102 x = cfunc.call(pi_2) 103 assert_equal(Math.sin(pi_2), x) 104 105 cfunc = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'), 106 [TYPE_DOUBLE]) 107 x = cfunc.call(-pi_2) 108 assert_equal(Math.sin(-pi_2), x) 109 end 110 111 def test_strlen() 112 cfunc = CFunc.new(@libc['strlen'], TYPE_INT, 'strlen') 113 x = cfunc.call(["abc"].pack("p").unpack("l!*")) 114 assert_equal("abc".size, x) 115 end 116 117 def test_strcpy() 118 buff = "xxxx" 119 str = "abc" 120 cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy') 121 x = cfunc.call(ptr2num(buff,str)) 122 assert_equal("abc\0", buff) 123 assert_equal("abc\0", CPtr.new(x).to_s(4)) 124 125 buff = "xxxx" 126 str = "abc" 127 cfunc = CFunc.new(@libc['strncpy'], TYPE_VOIDP, 'strncpy') 128 x = cfunc.call(ptr2num(buff,str) + [3]) 129 assert_equal("abcx", buff) 130 assert_equal("abcx", CPtr.new(x).to_s(4)) 131 132 ptr = CPtr.malloc(4) 133 str = "abc" 134 cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy') 135 x = cfunc.call([ptr.to_i, *ptr2num(str)]) 136 assert_equal("abc\0", ptr[0,4]) 137 assert_equal("abc\0", CPtr.new(x).to_s(4)) 138 end 139 140 def test_callback() 141 buff = "foobarbaz" 142 cb = set_callback(TYPE_INT,2){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]} 143 cfunc = CFunc.new(@libc['qsort'], TYPE_VOID, 'qsort') 144 cfunc.call(ptr2num(buff) + [buff.size, 1, cb]) 145 assert_equal('aabbfoorz', buff) 146 end 147 148 def test_dlwrap() 149 ary = [0,1,2,4,5] 150 addr = dlwrap(ary) 151 ary2 = dlunwrap(addr) 152 assert_equal(ary, ary2) 153 end 154 155 def test_type_size_t 156 assert_equal(DL::TYPE_SSIZE_T, DL::TYPE_SIZE_T.abs) 157 end 158 159 def test_type_uintptr_t 160 assert_equal(-DL::TYPE_INTPTR_T, DL::TYPE_UINTPTR_T) 161 end 162 163 def test_sizeof_uintptr_t 164 assert_equal(DL::SIZEOF_VOIDP, DL::SIZEOF_INTPTR_T) 165 end 166end 167end # module DL 168