1require_relative 'test_base'
2require 'dl/func'
3
4module DL
5  class TestCFunc < TestBase
6    def setup
7      super
8      @name = 'strcpy'
9      @cf = CFunc.new(@libc[@name], TYPE_VOIDP, @name)
10    end
11
12    def test_ptr=
13      @cf.ptr = @libc['malloc']
14      assert_equal @cf.ptr, @libc['malloc']
15    end
16
17    def test_ptr
18      assert_equal @cf.ptr, @libc[@name]
19    end
20
21    def test_set_calltype
22      @cf.calltype = :foo
23      assert_equal :foo, @cf.calltype
24    end
25
26    def test_new_ptr_type_name
27      assert_equal @name, @cf.name
28      assert @cf.name.tainted?, 'name should be tainted'
29      assert_equal :cdecl, @cf.calltype
30      assert_equal TYPE_VOIDP, @cf.ctype
31    end
32
33    def test_new_ptr
34      cf = CFunc.new(@libc['strcpy'])
35      assert_nil cf.name
36      assert_equal :cdecl, cf.calltype
37      assert_equal TYPE_VOID, cf.ctype
38    end
39
40    def test_name_should_be_duped
41      assert_equal @name, @cf.name
42      assert @cf.name.tainted?, 'name should be tainted'
43
44      name = @name.dup
45      @name << 'foo'
46
47      assert_equal name, @cf.name
48    end
49
50    def test_to_s
51      s = @cf.to_s
52      assert s.tainted?, 'to_s should be tainted'
53      assert_match(/ptr=#{sprintf("0x0*%x", @cf.ptr)}/, s)
54      assert_match(/name='#{@cf.name}'/, s)
55      assert_match(/type=#{@cf.ctype}/, s)
56    end
57
58    def test_inspect
59      assert_equal @cf.inspect, @cf.to_s
60    end
61
62    def test_inspect_is_tainted
63      assert @cf.inspect.tainted?, 'inspect is tainted'
64    end
65
66    def test_to_i
67      assert_equal @cf.to_i, @cf.ptr
68      assert_equal @libc[@name], @cf.to_i
69    end
70
71    def test_last_error
72      Thread.new do
73        f = Function.new(@cf, [TYPE_VOIDP, TYPE_VOIDP])
74        assert_nil CFunc.last_error
75        f.call("000", "123")
76        assert_not_nil CFunc.last_error
77      end.join
78    end
79  end
80end
81