You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When passing the canonical name of a FFI::Pointer subclass as a type, FFI::Library fails to introspect the correct type and return FFI::Type::POINTER. Insofar it has been confirmed to impact FFI::Struct, but theoretically affects all parts of the gem.
Example code
A trivial example can be performed with the following:
require'ffi'# A subclass of MemoryPointer, itself a subclass of Pointer.classSpecialReference < FFI::MemoryPointer# additional features would be put here ...end# A struct which uses a SpecialReferenceclassExampleData < FFI::Structlayout:value,:uint32_t,:ref,SpecialReference# this will fail with TypeErrorend
Expectation
When passing a subclass of Pointer, the expected output should be one of :pointer or Type::POINTER.
Reality
A TypeError is raised, declaring the type as invalid.
Example output
/var/lib/gems/3.1.0/gems/ffi-1.15.5/lib/ffi/types.rb:69:in `find_type': unable to resolve type 'SpecialReference' (TypeError)
from /var/lib/gems/3.1.0/gems/ffi-1.15.5/lib/ffi/struct.rb:278:in `find_type'
from /var/lib/gems/3.1.0/gems/ffi-1.15.5/lib/ffi/struct.rb:271:in `find_field_type'
from /var/lib/gems/3.1.0/gems/ffi-1.15.5/lib/ffi/struct.rb:311:in `array_layout'
from /var/lib/gems/3.1.0/gems/ffi-1.15.5/lib/ffi/struct.rb:217:in `layout'
from (irb):11:in `<class:ExampleData>'
from (irb):10:in `<main>'
...
Proposed solution
It appears that the current check used is inadequate, as it fails to occur as expected (see Relevant source code below). Replacing the line with the following appears to resolve the issue.
elsift.ancestors.include?(Pointer)and not t.kind_of?(Struct)Type::POINTER
# @param [DataConverter, Type, Struct, Symbol] t type to find# @return [Type]# Find a type definition.deffind_type(t)ift.kind_of?(Type)telsifdefined?(@ffi_typedefs) && @ffi_typedefs.has_key?(t)@ffi_typedefs[t]elsift.is_a?(Class) && t < StructType::POINTERelsift.is_a?(DataConverter)# Add a typedef so next time the converter is used, it hits the cachetypedefType::Mapped.new(t),tend || FFI.find_type(t)end
The text was updated successfully, but these errors were encountered:
Brief
When passing the canonical name of a
FFI::Pointer
subclass as a type,FFI::Library
fails to introspect the correct type and returnFFI::Type::POINTER
. Insofar it has been confirmed to impactFFI::Struct
, but theoretically affects all parts of the gem.Example code
A trivial example can be performed with the following:
Expectation
When passing a subclass of
Pointer
, the expected output should be one of:pointer
orType::POINTER
.Reality
A
TypeError
is raised, declaring the type as invalid.Example output
Proposed solution
It appears that the current check used is inadequate, as it fails to occur as expected (see Relevant source code below). Replacing the line with the following appears to resolve the issue.
Relevant source code
See: library.rb:575, reproduced in full below.
The text was updated successfully, but these errors were encountered: