1begin
2  require_relative 'helper'
3rescue LoadError
4end
5
6module Fiddle
7  class TestFunc < TestCase
8    def test_random
9      f = Function.new(@libc['srand'], [-TYPE_LONG], TYPE_VOID)
10      assert_nil f.call(10)
11    end
12
13    def test_syscall_with_tainted_string
14      f = Function.new(@libc['system'], [TYPE_VOIDP], TYPE_INT)
15      assert_raises(SecurityError) do
16        Thread.new {
17          $SAFE = 1
18          f.call("uname -rs".taint)
19        }.join
20      end
21    end
22
23    def test_sinf
24      begin
25        f = Function.new(@libm['sinf'], [TYPE_FLOAT], TYPE_FLOAT)
26      rescue Fiddle::DLError
27        skip "libm may not have sinf()"
28      end
29      assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
30    end
31
32    def test_sin
33      f = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
34      assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
35    end
36
37    def test_string
38      stress, GC.stress = GC.stress, true
39      f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
40      buff = "000"
41      str = f.call(buff, "123")
42      assert_equal("123", buff)
43      assert_equal("123", str.to_s)
44    ensure
45      GC.stress = stress
46    end
47
48    def test_isdigit
49      f = Function.new(@libc['isdigit'], [TYPE_INT], TYPE_INT)
50      r1 = f.call(?1.ord)
51      r2 = f.call(?2.ord)
52      rr = f.call(?r.ord)
53      assert_operator r1, :>, 0
54      assert_operator r2, :>, 0
55      assert_equal 0, rr
56    end
57
58    def test_atof
59      f = Function.new(@libc['atof'], [TYPE_VOIDP], TYPE_DOUBLE)
60      r = f.call("12.34")
61      assert_includes(12.00..13.00, r)
62    end
63
64    def test_strtod
65      f = Function.new(@libc['strtod'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_DOUBLE)
66      buff1 = Pointer["12.34"]
67      buff2 = buff1 + 4
68      r = f.call(buff1, - buff2)
69      assert_in_delta(12.34, r, 0.001)
70    end
71
72    def test_qsort1
73      cb = Class.new(Closure) {
74        def call(x, y)
75          Pointer.new(x)[0] <=> Pointer.new(y)[0]
76        end
77      }.new(TYPE_INT, [TYPE_VOIDP, TYPE_VOIDP])
78
79      qsort = Function.new(@libc['qsort'],
80                           [TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
81                           TYPE_VOID)
82      buff = "9341"
83      qsort.call(buff, buff.size, 1, cb)
84      assert_equal("1349", buff)
85
86      bug4929 = '[ruby-core:37395]'
87      buff = "9341"
88      EnvUtil.under_gc_stress {qsort.call(buff, buff.size, 1, cb)}
89      assert_equal("1349", buff, bug4929)
90    end
91  end
92end if defined?(Fiddle)
93