Skip to content

Commit

Permalink
Reject callback with :string return type
Browse files Browse the repository at this point in the history
Callbacks returning a :string type were not supported so far.
It was possible to define such a callback, but the value returned was NULL in any case.
This implementation rejects :string return type of callbacks.

The reason for the reject is the following:
In contrast to :string parameters to called functions there is no well defined ownership of the memory of the string returned by callbacks.
Instead an explicit FFI::MemoryPointer or similar should be used, which allows to track the validity of underlying memory instead of relying on some Ruby implementation details.

Fixes #751
  • Loading branch information
larskanis committed May 23, 2020
1 parent 6a14427 commit 5a1111c
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
5 changes: 4 additions & 1 deletion ext/ffi_c/FunctionInfo.c
Expand Up @@ -172,14 +172,17 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
}

if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) {
fnInfo->hasStruct = true;
}

Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType);
fnInfo->ffiReturnType = fnInfo->returnType->ffiType;

if (fnInfo->returnType->nativeType == NATIVE_STRING) {
rb_raise(rb_eTypeError, "return type :string is not allowed as return type of callbacks");
}

#if defined(X86_WIN32)
rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil;
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" 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

0 comments on commit 5a1111c

Please sign in to comment.