-
Notifications
You must be signed in to change notification settings - Fork 331
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
Fix FFI::Pointer#write_string to always terminate with a \0 byte #806
Conversation
@larskanis Could you review? The CI fails on TruffleRuby as expected (If we are OK with this change I'll apply it in TruffleRuby before merging) but it's otherwise passing. |
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.
I'm in a struggle with mixing null termination and no null termination. IMHO write_string
should always add a null termination. The mixed behaviour reminds me of strncpy()
which is often considered insecure therefore. So what do you think about adding a null after len
bytes, if len
is given?
I kind of agree, and I'll update the PR to always add a |
When len is given the null character is appended after the truncated string. Due to discussion in ffi#806 (review) Also add some Unicode characters to point out we're counting bytes, not characters.
@eregon I changed code and specs to add a null character in any case in |
…tring * And try to improve the clarity of the docs.
I did the change in TruffleRuby, will ping here when it's merged and there is a new truffleruby-head build. |
@larskanis I'm not sure if we can do this change regarding compatibility. In TruffleRuby's own usages of I also noticed a problematic usage in OptCarrot: When running on CRuby there is at least a nice error:
So this should help migration, but I'm not sure if the Pointer's size is always known. On TruffleRuby there are currently no such checks, and so it results in malloc() assertions & errors. |
@larskanis I'm OK to merge the change in TruffleRuby-head to experiment. |
* Since #write_string might append a final \0 byte in future FFI releases: ffi/ffi#806
* Since #write_string might append a final \0 byte in future FFI releases: ffi/ffi#806
@larskanis Could you reply here, do you think we should try this change and see what happens? |
Thank you Benoit for your investigation above! I'm sorry that I've got very little time for OSS development over the past months. Regarding this change I'm unsure how to solve it best. Obviously we break compatibility in some cases, but we shouldn't in a minor version. We could use
I'm somewhat in favor with option 1, but still unsure. If we reach an agreement on this PR, I can release a new ffi version 1.14.0 within some days. |
If the string fits into the memory but the final 0-byte doesn't, print a deprecation warning. This should mitigate the comptibility issue that @eregon noticed in ffi#806 (comment) . Also extend the specs for ffi-2.x behavior and the behavior for too large strings.
dfd8bda
to
e0e687d
Compare
@larskanis That sounds good to me. In the case the pointer is unbounded (size=LONG_MAX), then an extra Given there is a deprecation warning, maybe we could actually use the new behavior after a few FFI 1.x releases? |
What should we do about Because of the name ( Currently the documentation is a mix: # @param [String] str string to write
# @param [Numeric] len length of string to return
# @return [self]
# Write +len+ first bytes of +str+ in pointer's contents.
#
# Same as:
# ptr.write_string(str, len) # with len not nil
def write_string_length(str, len)
write_bytes(str, 0, len)
end |
I think it's good to merge now. There are some errors on Truffleruby, since it's not implemented there. Can I merge the PR now or is there anything else to consider? |
Fine to merge for me, I should be able to fix TruffleRuby soon after. |
Revert "Merge pull request #806 from eregon/fix-write_string"
There was no specs for
write_string
yet, so actually changing as proposed in #805 caused no spec failures.