Skip to content

Commit

Permalink
Reject FFI callback with :string return type
Browse files Browse the repository at this point in the history
* Applies ffi/ffi#782
* So the semantics of a callback returning :string is well defined.
  • Loading branch information
eregon committed Jun 5, 2020
1 parent 19a952b commit 284e295
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 2 deletions.
6 changes: 5 additions & 1 deletion lib/truffle/ffi/library.rb
Expand Up @@ -394,7 +394,11 @@ def callback(*args)
options = Hash.new
options[:convention] = ffi_convention
options[:enums] = @ffi_enums if defined?(@ffi_enums)
cb = FFI::CallbackInfo.new(find_type(ret), native_params, options)
ret_type = find_type(ret)
if ret_type == Type::STRING
raise TypeError, ":string is not allowed as return type of callbacks"
end
cb = FFI::CallbackInfo.new(ret_type, native_params, options)

# Add to the symbol -> type map (unless there was no name)
unless name.nil?
Expand Down
6 changes: 5 additions & 1 deletion lib/truffle/ffi/struct.rb
Expand Up @@ -228,7 +228,11 @@ def layout(*spec)

def callback(params, ret)
mod = enclosing_module
FFI::CallbackInfo.new(find_type(ret, mod), params.map { |e| find_type(e, mod) })
ret_type = find_type(ret, mod)
if ret_type == Type::STRING
raise TypeError, ":string is not allowed as return type of callbacks"
end
FFI::CallbackInfo.new(ret_type, params.map { |e| find_type(e, mod) })
end

def packed(packed = 1)
Expand Down
9 changes: 9 additions & 0 deletions spec/ffi/callback_spec.rb
Expand Up @@ -309,6 +309,15 @@ class S8F32S32 < FFI::Struct
expect(s2[:f32]).to be_within(0.0000001).of 1.234567
end

it "returning :string is rejected as typedef" do
expect {
Module.new do
extend FFI::Library
ffi_lib TestLibrary::PATH
callback :cbVrA, [], :string
end
}.to raise_error(TypeError)
end

it "global variable" do
proc = Proc.new { 0x1e }
Expand Down
8 changes: 8 additions & 0 deletions spec/ffi/struct_callback_spec.rb
Expand Up @@ -66,4 +66,12 @@ class TestStruct < FFI::Struct
expect(fn.respond_to?(:call)).to be true
expect(fn.call(1, 2)).to eq(3)
end

it "callback returning :string is rejected in struct" do
expect {
Class.new(FFI::Struct) do
layout :function1, callback([:int, :int], :string)
end
}.to raise_error(TypeError)
end
end

0 comments on commit 284e295

Please sign in to comment.