-
Notifications
You must be signed in to change notification settings - Fork 43
Fix memory corruption with FFI backend #180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
2b8e414
to
07a606f
Compare
lib/fiddle/ffi_backend.rb
Outdated
cptr = Pointer.malloc(value.bytesize + 1) | ||
cptr.ffi_ptr.put_string(0, value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to use put_bytes
instead...
cptr = Pointer.malloc(value.bytesize + 1) | |
cptr.ffi_ptr.put_string(0, value) | |
cptr = Pointer.malloc(value.bytesize) | |
cptr.ffi_ptr.put_bytes(0, value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried that initially with write_bytes
, but looks like some of the tests expect an additional null byte.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, looks like the failing tests are due to an issue with the to_s
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kou Is it expected though that Fiddle::Pointer.to_ptr("abc")
doesn't guarantee to return a \0-terminated native string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what the C extension does:
Lines 784 to 787 in 7a4c6da
else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){ | |
char *str = StringValuePtr(val); | |
wrap = val; | |
ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL); |
StringValuePtr AFAIK always returns a \0 terminated char* in CRuby (same as RSTRING_PTR).
So then
cptr = Pointer.malloc(value.bytesize + 1)
cptr.ffi_ptr.put_string(0, value)
is I believe the correct way.
i.e. it was correct as of 07a606f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made the behavior consistent with CRuby in #187.
07a606f
to
ae9b0bb
Compare
Thanks. |
Thank you |
To reproduce with JRuby or TruffleRuby:
put_string
adds a null byte at the end vswrite_bytes
. This is not caught by the bounds check since the underlyingFFI::Pointer
size is not set.