-
Notifications
You must be signed in to change notification settings - Fork 244
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
secp-sys: Use NonNull in API instead of *mut T #551
secp-sys: Use NonNull in API instead of *mut T #551
Conversation
Currently we expect non-null pointers when we take `*mut T` parameters, however we do not check that the pointers are non-null because we never set VERIFY in our C build. We can use the `NonNull` type to enforce no-null-ness as long as we use `NonNull::new`. In a couple of instances we manually check that a buffer is not empty and therefore that the pointer to it is non-null so we can safely use `NonNull::new_unchecked`. Replace mutable pointer parameters `*mut T` (e.g. `*mut c_void`) and return types with `NonNull<T>`. Fix rust-bitcoin#546
6752f04
to
9b07e8e
Compare
Thanks! We could actually go a bit further and
I meant, on all the specific |
Are we sure we want this? My understanding is that FFI sys deliberately should not do anything clever and just translate the C interface. The wrappers can do the clever stuff. For linker reasons, there should only ever by one sys crate in project build dependency. Anyone building their own high-level wrappers around the sys crate is not bound by our choice. The general design rationale here is to not do anything and deal with raw pointers. As an example open-ssl-sys: https://github.com/sfackler/rust-openssl/blob/master/openssl-sys/src/handwritten/aes.rs Even the bindgen autogenerated bindgens follow this principle. |
The C interface is "takes a non-null pointer at penalty of UB". Arguably using
That's because bindgen does not (and cannot) understand the contracts required by C code. |
|
Ok, I'm happy to take this PR as-is then. Is that what you're suggesting @Kixunil ? |
Went to double-check and after reading https://internals.rust-lang.org/t/seperating-nonnull-into-nonnullmut-and-nonnullconst/11083 and https://internals.rust-lang.org/t/what-is-the-real-difference-between-const-t-and-mut-t-raw-pointers/6127 I came to the conclusion that neither |
@Kixunil nice, thanks for the links -- but this PR only replaces Edit sorry, I'm on the run, I will read the links in a bit and apologize if they answer my question |
Yes, I think it's OK. |
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.
ACK 9b07e8e
9b07e8e secp-sys: Use NonNull in API instead of *mut T (Tobin C. Harding) Pull request description: Currently we expect non-null pointers when we take `*mut T` parameters, however we do not check that the pointers are non-null because we never set VERIFY in our C build. We can use the `NonNull` type to enforce no-null-ness as long as we use `NonNull::new`. In a couple of instances we manually check that a buffer is not empty and therefore that the pointer to it is non-null so we can safely use `NonNull::new_unchecked`. Replace mutable pointer parameters `*mut T` (e.g. `*mut c_void`) and return types with `NonNull<T>`. Fix rust-bitcoin#546 ### Note The description above fully explains the issue to the best of my knowledge, if the description is not spot on then I'm not fully understanding the issue. Please correct me if this is the case. > One unfortunate thing is that this means that we wouldn't be able to implement CPtr for secp256k1::Context, which is our designated "expose types from secp256k1-sys which is not stable" semver escape hatch. You've lost me here? `secp256k1::Context` is a trait did you mean `secp256k1::Secp256k1` or `secp256k1_sys::Context`? ACKs for top commit: apoelstra: ACK 9b07e8e Tree-SHA512: 37aceebfa62e590ce8cc282c35b014ad018e5cfbea99402ed3aa1fcbaa69e01a01c1c1f32351f5f15a7d270e31da5b239ee5bc11d2343cf866082ad85df6a622
Currently we expect non-null pointers when we take
*mut T
parameters, however we do not check that the pointers are non-null because we never set VERIFY in our C build. We can use theNonNull
type to enforce no-null-ness as long as we useNonNull::new
. In a couple of instances we manually check that a buffer is not empty and therefore that the pointer to it is non-null so we can safely useNonNull::new_unchecked
.Replace mutable pointer parameters
*mut T
(e.g.*mut c_void
) and return types withNonNull<T>
.Fix #546
Note
The description above fully explains the issue to the best of my knowledge, if the description is not spot on then I'm not fully understanding the issue. Please correct me if this is the case.
You've lost me here?
secp256k1::Context
is a trait did you meansecp256k1::Secp256k1
orsecp256k1_sys::Context
?