ffi 1.9.14 → 1.9.15
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/ext/ffi_c/AbstractMemory.c +70 -1
- data/lib/ffi/platform/x86_64-openbsd/types.conf +27 -21
- data/lib/ffi/pointer.rb +26 -0
- data/lib/ffi/version.rb +1 -1
- data/spec/ffi/pointer_spec.rb +7 -0
- data/spec/ffi/rbx/memory_pointer_spec.rb +65 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f97cb3645f562b21855a49b07add50953a9c00bd
|
4
|
+
data.tar.gz: 719a550754eb99c86addf70e85992fbc14c86ee8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3df802e3c31b7597c3fb45192be4a8e3972c71c7e9aaf2cbdbb945e9c3958f4c9a83b3022c5cb399d69a9cfbf7ad031763150777b9c76e9d7745c3ddd2242212
|
7
|
+
data.tar.gz: df2b9eb032aa9ab92ae7e6fe18c66378518e8fea5f409b23ce3f17d603063d7895a9a072ed96bbac08b3a7d9355f5ce1d0b870d19b2d9e1fb3f5f58be91bf226
|
data/README.md
CHANGED
@@ -43,6 +43,8 @@ At a minimum, you will need:
|
|
43
43
|
* A C compiler (e.g. Xcode on OSX, gcc on everything else)
|
44
44
|
* libffi development library - this is commonly in the libffi-dev or libffi-devel
|
45
45
|
|
46
|
+
On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.) FFI may trigger `mprotrect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
|
47
|
+
|
46
48
|
## Installation
|
47
49
|
|
48
50
|
From rubygems:
|
data/ext/ffi_c/AbstractMemory.c
CHANGED
@@ -310,7 +310,7 @@ memory_clear(VALUE self)
|
|
310
310
|
* @return [Numeric]
|
311
311
|
*/
|
312
312
|
static VALUE
|
313
|
-
memory_size(VALUE self)
|
313
|
+
memory_size(VALUE self)
|
314
314
|
{
|
315
315
|
AbstractMemory* ptr;
|
316
316
|
|
@@ -319,6 +319,72 @@ memory_size(VALUE self)
|
|
319
319
|
return LONG2NUM(ptr->size);
|
320
320
|
}
|
321
321
|
|
322
|
+
/*
|
323
|
+
* call-seq: memory.get(type, offset)
|
324
|
+
* Return data of given type contained in memory.
|
325
|
+
* @param [Symbol, Type] type_name type of data to get
|
326
|
+
* @param [Numeric] offset point in buffer to start from
|
327
|
+
* @return [Object]
|
328
|
+
* @raise {ArgumentError} if type is not supported
|
329
|
+
*/
|
330
|
+
static VALUE
|
331
|
+
memory_get(VALUE self, VALUE type_name, VALUE offset)
|
332
|
+
{
|
333
|
+
AbstractMemory* ptr;
|
334
|
+
VALUE nType;
|
335
|
+
Type *type;
|
336
|
+
|
337
|
+
nType = rbffi_Type_Lookup(type_name);
|
338
|
+
if(NIL_P(nType)) goto undefined_type;
|
339
|
+
|
340
|
+
Data_Get_Struct(self, AbstractMemory, ptr);
|
341
|
+
Data_Get_Struct(nType, Type, type);
|
342
|
+
|
343
|
+
MemoryOp *op = get_memory_op(type);
|
344
|
+
if(op == NULL) goto undefined_type;
|
345
|
+
|
346
|
+
return op->get(ptr, NUM2LONG(offset));
|
347
|
+
|
348
|
+
undefined_type: {
|
349
|
+
VALUE msg = rb_sprintf("undefined type '%" PRIsVALUE "'", type_name);
|
350
|
+
rb_exc_raise(rb_exc_new3(rb_eArgError, msg));
|
351
|
+
return Qnil;
|
352
|
+
}
|
353
|
+
}
|
354
|
+
|
355
|
+
/*
|
356
|
+
* call-seq: memory.put(type, offset, value)
|
357
|
+
* @param [Symbol, Type] type_name type of data to put
|
358
|
+
* @param [Numeric] offset point in buffer to start from
|
359
|
+
* @return [nil]
|
360
|
+
* @raise {ArgumentError} if type is not supported
|
361
|
+
*/
|
362
|
+
static VALUE
|
363
|
+
memory_put(VALUE self, VALUE type_name, VALUE offset, VALUE value)
|
364
|
+
{
|
365
|
+
AbstractMemory* ptr;
|
366
|
+
VALUE nType;
|
367
|
+
Type *type;
|
368
|
+
|
369
|
+
nType = rbffi_Type_Lookup(type_name);
|
370
|
+
if(NIL_P(nType)) goto undefined_type;
|
371
|
+
|
372
|
+
Data_Get_Struct(self, AbstractMemory, ptr);
|
373
|
+
Data_Get_Struct(nType, Type, type);
|
374
|
+
|
375
|
+
MemoryOp *op = get_memory_op(type);
|
376
|
+
if(op == NULL) goto undefined_type;
|
377
|
+
|
378
|
+
op->put(ptr, NUM2LONG(offset), value);
|
379
|
+
return Qnil;
|
380
|
+
|
381
|
+
undefined_type: {
|
382
|
+
VALUE msg = rb_sprintf("unsupported type '%" PRIsVALUE "'", type_name);
|
383
|
+
rb_exc_raise(rb_exc_new3(rb_eArgError, msg));
|
384
|
+
return Qnil;
|
385
|
+
}
|
386
|
+
}
|
387
|
+
|
322
388
|
/*
|
323
389
|
* call-seq: memory.get_string(offset, length=nil)
|
324
390
|
* Return string contained in memory.
|
@@ -1018,6 +1084,9 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
|
|
1018
1084
|
rb_define_method(classMemory, "write_bytes", memory_write_bytes, -1);
|
1019
1085
|
rb_define_method(classMemory, "get_array_of_string", memory_get_array_of_string, -1);
|
1020
1086
|
|
1087
|
+
rb_define_method(classMemory, "get", memory_get, 2);
|
1088
|
+
rb_define_method(classMemory, "put", memory_put, 3);
|
1089
|
+
|
1021
1090
|
rb_define_method(classMemory, "clear", memory_clear, 0);
|
1022
1091
|
rb_define_method(classMemory, "total", memory_size, 0);
|
1023
1092
|
rb_define_alias(classMemory, "size", "total");
|
@@ -26,44 +26,48 @@ rbx.platform.typedef.__intptr_t = long
|
|
26
26
|
rbx.platform.typedef.__uintptr_t = ulong
|
27
27
|
rbx.platform.typedef.__intmax_t = long_long
|
28
28
|
rbx.platform.typedef.__uintmax_t = ulong_long
|
29
|
-
rbx.platform.typedef.__register_t =
|
29
|
+
rbx.platform.typedef.__register_t = long
|
30
30
|
rbx.platform.typedef.__vaddr_t = ulong
|
31
31
|
rbx.platform.typedef.__paddr_t = ulong
|
32
32
|
rbx.platform.typedef.__vsize_t = ulong
|
33
33
|
rbx.platform.typedef.__psize_t = ulong
|
34
|
-
rbx.platform.typedef.__clock_t = int
|
35
|
-
rbx.platform.typedef.__clockid_t = int
|
36
|
-
rbx.platform.typedef.__off_t = long_long
|
37
34
|
rbx.platform.typedef.__ptrdiff_t = long
|
38
35
|
rbx.platform.typedef.__size_t = ulong
|
39
36
|
rbx.platform.typedef.__ssize_t = long
|
40
|
-
rbx.platform.typedef.__time_t = int
|
41
|
-
rbx.platform.typedef.__timer_t = int
|
42
37
|
rbx.platform.typedef.__wchar_t = int
|
43
38
|
rbx.platform.typedef.__wint_t = int
|
44
39
|
rbx.platform.typedef.__rune_t = int
|
45
40
|
rbx.platform.typedef.__wctrans_t = pointer
|
46
41
|
rbx.platform.typedef.__wctype_t = pointer
|
42
|
+
rbx.platform.typedef.__blkcnt_t = long_long
|
43
|
+
rbx.platform.typedef.__blksize_t = int
|
44
|
+
rbx.platform.typedef.__clock_t = long_long
|
45
|
+
rbx.platform.typedef.__clockid_t = int
|
47
46
|
rbx.platform.typedef.__cpuid_t = ulong
|
48
47
|
rbx.platform.typedef.__dev_t = int
|
49
48
|
rbx.platform.typedef.__fixpt_t = uint
|
49
|
+
rbx.platform.typedef.__fsblkcnt_t = ulong_long
|
50
|
+
rbx.platform.typedef.__fsfilcnt_t = ulong_long
|
50
51
|
rbx.platform.typedef.__gid_t = uint
|
51
52
|
rbx.platform.typedef.__id_t = uint
|
52
53
|
rbx.platform.typedef.__in_addr_t = uint
|
53
54
|
rbx.platform.typedef.__in_port_t = ushort
|
54
|
-
rbx.platform.typedef.__ino_t =
|
55
|
+
rbx.platform.typedef.__ino_t = ulong_long
|
55
56
|
rbx.platform.typedef.__key_t = long
|
56
57
|
rbx.platform.typedef.__mode_t = uint
|
57
58
|
rbx.platform.typedef.__nlink_t = uint
|
59
|
+
rbx.platform.typedef.__off_t = long_long
|
58
60
|
rbx.platform.typedef.__pid_t = int
|
59
61
|
rbx.platform.typedef.__rlim_t = ulong_long
|
60
62
|
rbx.platform.typedef.__sa_family_t = uchar
|
61
63
|
rbx.platform.typedef.__segsz_t = int
|
62
64
|
rbx.platform.typedef.__socklen_t = uint
|
65
|
+
rbx.platform.typedef.__suseconds_t = long
|
63
66
|
rbx.platform.typedef.__swblk_t = int
|
67
|
+
rbx.platform.typedef.__time_t = long_long
|
68
|
+
rbx.platform.typedef.__timer_t = int
|
64
69
|
rbx.platform.typedef.__uid_t = uint
|
65
70
|
rbx.platform.typedef.__useconds_t = uint
|
66
|
-
rbx.platform.typedef.__suseconds_t = int
|
67
71
|
rbx.platform.typedef.u_char = uchar
|
68
72
|
rbx.platform.typedef.u_short = ushort
|
69
73
|
rbx.platform.typedef.u_int = uint
|
@@ -73,7 +77,7 @@ rbx.platform.typedef.ushort = ushort
|
|
73
77
|
rbx.platform.typedef.uint = uint
|
74
78
|
rbx.platform.typedef.ulong = ulong
|
75
79
|
rbx.platform.typedef.cpuid_t = ulong
|
76
|
-
rbx.platform.typedef.register_t =
|
80
|
+
rbx.platform.typedef.register_t = long
|
77
81
|
rbx.platform.typedef.int8_t = char
|
78
82
|
rbx.platform.typedef.uint8_t = uchar
|
79
83
|
rbx.platform.typedef.int16_t = short
|
@@ -82,8 +86,6 @@ rbx.platform.typedef.int32_t = int
|
|
82
86
|
rbx.platform.typedef.uint32_t = uint
|
83
87
|
rbx.platform.typedef.int64_t = long_long
|
84
88
|
rbx.platform.typedef.uint64_t = ulong_long
|
85
|
-
rbx.platform.typedef.intptr_t = long
|
86
|
-
rbx.platform.typedef.uintptr_t = ulong
|
87
89
|
rbx.platform.typedef.u_int8_t = uchar
|
88
90
|
rbx.platform.typedef.u_int16_t = ushort
|
89
91
|
rbx.platform.typedef.u_int32_t = uint
|
@@ -95,34 +97,38 @@ rbx.platform.typedef.vaddr_t = ulong
|
|
95
97
|
rbx.platform.typedef.paddr_t = ulong
|
96
98
|
rbx.platform.typedef.vsize_t = ulong
|
97
99
|
rbx.platform.typedef.psize_t = ulong
|
100
|
+
rbx.platform.typedef.blkcnt_t = long_long
|
101
|
+
rbx.platform.typedef.blksize_t = int
|
98
102
|
rbx.platform.typedef.caddr_t = string
|
99
|
-
rbx.platform.typedef.daddr_t = int
|
100
103
|
rbx.platform.typedef.daddr32_t = int
|
101
|
-
rbx.platform.typedef.
|
104
|
+
rbx.platform.typedef.daddr_t = long_long
|
102
105
|
rbx.platform.typedef.dev_t = int
|
103
106
|
rbx.platform.typedef.fixpt_t = uint
|
104
107
|
rbx.platform.typedef.gid_t = uint
|
105
108
|
rbx.platform.typedef.id_t = uint
|
106
|
-
rbx.platform.typedef.ino_t =
|
109
|
+
rbx.platform.typedef.ino_t = ulong_long
|
107
110
|
rbx.platform.typedef.key_t = long
|
108
111
|
rbx.platform.typedef.mode_t = uint
|
109
112
|
rbx.platform.typedef.nlink_t = uint
|
110
|
-
rbx.platform.typedef.pid_t = int
|
111
113
|
rbx.platform.typedef.rlim_t = ulong_long
|
112
114
|
rbx.platform.typedef.segsz_t = int
|
113
115
|
rbx.platform.typedef.swblk_t = int
|
114
116
|
rbx.platform.typedef.uid_t = uint
|
115
117
|
rbx.platform.typedef.useconds_t = uint
|
116
|
-
rbx.platform.typedef.suseconds_t =
|
118
|
+
rbx.platform.typedef.suseconds_t = long
|
119
|
+
rbx.platform.typedef.fsblkcnt_t = ulong_long
|
120
|
+
rbx.platform.typedef.fsfilcnt_t = ulong_long
|
117
121
|
rbx.platform.typedef.in_addr_t = uint
|
118
122
|
rbx.platform.typedef.in_port_t = ushort
|
119
|
-
rbx.platform.typedef.
|
120
|
-
rbx.platform.typedef.socklen_t = uint
|
121
|
-
rbx.platform.typedef.clock_t = int
|
123
|
+
rbx.platform.typedef.clock_t = long_long
|
122
124
|
rbx.platform.typedef.clockid_t = int
|
125
|
+
rbx.platform.typedef.pid_t = int
|
123
126
|
rbx.platform.typedef.size_t = ulong
|
124
127
|
rbx.platform.typedef.ssize_t = long
|
125
|
-
rbx.platform.typedef.time_t =
|
128
|
+
rbx.platform.typedef.time_t = long_long
|
126
129
|
rbx.platform.typedef.timer_t = int
|
127
130
|
rbx.platform.typedef.off_t = long_long
|
128
|
-
rbx.platform.typedef.__fd_mask =
|
131
|
+
rbx.platform.typedef.__fd_mask = uint
|
132
|
+
rbx.platform.typedef.sigset_t = uint
|
133
|
+
rbx.platform.typedef.socklen_t = uint
|
134
|
+
rbx.platform.typedef.sa_family_t = uchar
|
data/lib/ffi/pointer.rb
CHANGED
@@ -130,5 +130,31 @@ module FFI
|
|
130
130
|
}
|
131
131
|
self
|
132
132
|
end
|
133
|
+
|
134
|
+
# @return [self]
|
135
|
+
def to_ptr
|
136
|
+
self
|
137
|
+
end
|
138
|
+
|
139
|
+
# @param [Symbol,Type] type of data to read
|
140
|
+
# @return [Object]
|
141
|
+
# Read pointer's contents as +type+
|
142
|
+
#
|
143
|
+
# Same as:
|
144
|
+
# ptr.get(type, 0)
|
145
|
+
def read(type)
|
146
|
+
get(type, 0)
|
147
|
+
end
|
148
|
+
|
149
|
+
# @param [Symbol,Type] type of data to read
|
150
|
+
# @param [Object] value to write
|
151
|
+
# @return [nil]
|
152
|
+
# Write +value+ of type +type+ to pointer's content
|
153
|
+
#
|
154
|
+
# Same as:
|
155
|
+
# ptr.put(type, 0)
|
156
|
+
def write(type, value)
|
157
|
+
put(type, 0, value)
|
158
|
+
end
|
133
159
|
end
|
134
160
|
end
|
data/lib/ffi/version.rb
CHANGED
data/spec/ffi/pointer_spec.rb
CHANGED
@@ -62,6 +62,13 @@ describe "Pointer" do
|
|
62
62
|
expect { PointerTestLib.ptr_ret_int32(0xfee1deadbeefcafebabe, 0) }.to raise_error
|
63
63
|
end
|
64
64
|
|
65
|
+
it "#to_ptr" do
|
66
|
+
memory = FFI::MemoryPointer.new :pointer
|
67
|
+
expect(memory.to_ptr).to eq(memory)
|
68
|
+
|
69
|
+
expect(FFI::Pointer::NULL.to_ptr).to eq(FFI::Pointer::NULL)
|
70
|
+
end
|
71
|
+
|
65
72
|
describe "pointer type methods" do
|
66
73
|
|
67
74
|
it "#read_pointer" do
|
@@ -52,12 +52,76 @@ describe "MemoryPointer" do
|
|
52
52
|
m = FFI::MemoryPointer.new(:int)
|
53
53
|
m.write_int(1)
|
54
54
|
expect(m.read_int).to eq(1)
|
55
|
+
expect(m.read :int).to eq(1)
|
56
|
+
expect(m.read FFI::Type::INT).to eq(1)
|
55
57
|
end
|
56
|
-
|
58
|
+
|
59
|
+
it "allows writing as a sized int" do
|
60
|
+
m = FFI::MemoryPointer.new(:uint32)
|
61
|
+
m.write_uint32(1)
|
62
|
+
expect(m.read_uint32).to eq(1)
|
63
|
+
expect(m.read :uint32).to eq(1)
|
64
|
+
expect(m.read FFI::Type::UINT32).to eq(1)
|
65
|
+
|
66
|
+
m = FFI::MemoryPointer.new(:uint32)
|
67
|
+
m.write :uint32, 1
|
68
|
+
expect(m.read :uint32).to eq(1)
|
69
|
+
|
70
|
+
m = FFI::MemoryPointer.new(:int64)
|
71
|
+
m.write_int64(1)
|
72
|
+
expect(m.read_int64).to eq(1)
|
73
|
+
expect(m.read :int64).to eq(1)
|
74
|
+
expect(m.read FFI::Type::INT64).to eq(1)
|
75
|
+
|
76
|
+
m = FFI::MemoryPointer.new(:int64)
|
77
|
+
m.write :int64, 1
|
78
|
+
expect(m.read :int64).to eq(1)
|
79
|
+
end
|
80
|
+
|
57
81
|
it "allows writing as a long" do
|
58
82
|
m = FFI::MemoryPointer.new(:long)
|
59
83
|
m.write_long(10)
|
60
84
|
expect(m.read_long).to eq(10)
|
85
|
+
expect(m.read :long).to eq(10)
|
86
|
+
expect(m.read FFI::Type::LONG).to eq(10)
|
87
|
+
|
88
|
+
m.write :long, 10
|
89
|
+
expect(m.read :long).to eq(10)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "allows writing as a size_t" do
|
93
|
+
m = FFI::MemoryPointer.new(:size_t)
|
94
|
+
m.write(:size_t, 10)
|
95
|
+
expect(m.read :size_t).to eq(10)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "allows writing as a bool" do
|
99
|
+
m = FFI::MemoryPointer.new(:bool)
|
100
|
+
m.write(:bool, true)
|
101
|
+
expect(m.read :bool).to eq(true)
|
102
|
+
expect(m.read FFI::Type::BOOL).to eq(true)
|
103
|
+
|
104
|
+
m.write(:bool, false)
|
105
|
+
expect(m.read :bool).to eq(false)
|
106
|
+
expect(m.read FFI::Type::BOOL).to eq(false)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "allows writing a custom typedef" do
|
110
|
+
FFI.typedef :uint, :fubar_t
|
111
|
+
FFI.typedef :size_t, :fubar2_t
|
112
|
+
|
113
|
+
m = FFI::MemoryPointer.new(:fubar_t)
|
114
|
+
m.write(:fubar_t, 10)
|
115
|
+
expect(m.read :fubar_t).to eq(10)
|
116
|
+
|
117
|
+
m = FFI::MemoryPointer.new(:fubar2_t)
|
118
|
+
m.write(:fubar2_t, 10)
|
119
|
+
expect(m.read :fubar2_t).to eq(10)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "raises an error if you try to read an undefined type" do
|
123
|
+
m = FFI::MemoryPointer.new(:long)
|
124
|
+
expect { m.read(:undefined_type) }.to raise_error(ArgumentError)
|
61
125
|
end
|
62
126
|
|
63
127
|
it "raises an error if you try putting a long into a pointer of size 1" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
4
|
+
version: 1.9.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wayne Meissner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -570,7 +570,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
570
570
|
version: '0'
|
571
571
|
requirements: []
|
572
572
|
rubyforge_project:
|
573
|
-
rubygems_version: 2.
|
573
|
+
rubygems_version: 2.6.8
|
574
574
|
signing_key:
|
575
575
|
specification_version: 4
|
576
576
|
summary: Ruby FFI
|