From 934ad153352cc584d83348436ccdc00f86e18cbf Mon Sep 17 00:00:00 2001 From: Charlie Savage Date: Thu, 28 Mar 2024 01:16:10 -0700 Subject: [PATCH] If you call FFI::Pointer#== with an instance of an object that is not FFI::Pointer or descendants an exception is thrown - "INTERNAL ERROR!!! TypeError: wrong argument type Module (expected FFI::Pointer). In my case, this then causes the RubyMine debugger (debase) to blow up, making debugging harder. This PR updates FFI::Pointer#== to return false if a pointer is compared to a non-pointer object, which is the expected behavior. --- ext/ffi_c/Pointer.c | 7 ++++++- spec/ffi/pointer_spec.rb | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ext/ffi_c/Pointer.c b/ext/ffi_c/Pointer.c index 31b9f8036..affa35901 100644 --- a/ext/ffi_c/Pointer.c +++ b/ext/ffi_c/Pointer.c @@ -314,7 +314,12 @@ ptr_equals(VALUE self, VALUE other) return ptr->memory.address == NULL ? Qtrue : Qfalse; } - return ptr->memory.address == POINTER(other)->address ? Qtrue : Qfalse; + if (!rb_obj_is_kind_of(other, rbffi_PointerClass)) { + return Qfalse; + } + else { + return ptr->memory.address == POINTER(other)->address ? Qtrue : Qfalse; + } } /* diff --git a/spec/ffi/pointer_spec.rb b/spec/ffi/pointer_spec.rb index a7114966b..bda270189 100644 --- a/spec/ffi/pointer_spec.rb +++ b/spec/ffi/pointer_spec.rb @@ -76,6 +76,16 @@ def to_ptr expect(FFI::Pointer::NULL.to_ptr).to eq(FFI::Pointer::NULL) end + it "equals itself" do + memory = FFI::MemoryPointer.new :pointer + expect(memory == memory).to be true + end + + it "does not equal non pointers" do + memory = FFI::MemoryPointer.new :pointer + expect(memory == Hash.new).to be false + end + describe "pointer type methods" do it "#read_pointer" do @@ -150,6 +160,9 @@ def to_ptr it 'returns true when compared with nil' do expect((FFI::Pointer::NULL == nil)).to be true end + it 'returns false when compared with a non-pointer object' do + expect((FFI::Pointer::NULL == Array.new)).to be false + end it 'should not raise an error when attempting read/write zero length array' do null_ptr = FFI::Pointer::NULL expect( null_ptr.read_array_of_uint(0) ).to eq([])