-
Notifications
You must be signed in to change notification settings - Fork 63
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
Key struct is fragile, possibly unsound #196
Comments
Miri doesn't like it either
|
brunocodutra
added a commit
to brunocodutra/tree-edit-distance
that referenced
this issue
Sep 11, 2022
brunocodutra
added a commit
to brunocodutra/tree-edit-distance
that referenced
this issue
Sep 11, 2022
This was referenced Jan 18, 2023
This was referenced Jan 19, 2023
This was referenced Oct 13, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The
Key
struct is currently initialized in two phases. First it is created, like this:json-rust/src/object.rs
Lines 71 to 78 in 0775592
And only later it is attached to its actual contents.
Before the key is attached, calling
as_bytes
results in undefined behavior:json-rust/src/object.rs
Lines 81 to 85 in 0775592
because a null pointer is passed to
slice::from_raw_parts
, violating its safety invariant. Replacing a null pointer withNonNull::dangling()
will not solve the problem because then the slice will non-zero length would to unclaimed memory, which is also UB.If the two-phase initialization is truly necessary, a less fragile way to approach it is to explicitly encode the initialization state in the type system: have
UnattachedKey
struct without any accessor methods for the partly initialized state, and provide a method to turn it into a properKey
by callingattach()
.Key
also seems to contain a hand-rolled implementation of the small string optimization that, in addition to the usual dangers of custom unsafe code, leaves performance on the table. The current implementation always zero-initializes the underlying buffer. Usingsmallstr
crate or something along those lines will (even though I'm not really a fan of the underlyingsmallvec
crate).Using
slotmap
to store the strings in a single allocation instead of using the small string optimization would probably work even better, since it would avoid inflating the struct, and also remove the need for pointer fixups on cloning and reallocation altogether. It would also remove the need for two-phase initialization, andKey
would no longer have to be self-referential.The text was updated successfully, but these errors were encountered: