You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pubtraitVTab:Sized{/// The data type of the bind datatypeInitData:Sized + Free;/// The data type of the init datatypeBindData:Sized + Free;unsafefnbind(bind:&BindInfo,data:*mutSelf::BindData) -> Result<(),Box<dyn std::error::Error>>;// ....}
This interface is a bit easy to misuse in Rust. The user's implementation of bind is called with data pointing to an allocated block that is large enough to hold a Self::BindData but uninitialized.
So, at least, it would be nice to document this more.
But, since this is meant to be the higher-level interface, I think we could do better and just make the interface entirely safe?
I think there are a couple of potentially feasible approaches. Which one would actually work would take some experimentation:
The Rust vtab::bind could just create and return the binddata that it wants, which could then be put in a box and passed to the C API?
Or, if VTab::BindData: Default then it could be initialized to the default value and passed in as a &mut.
I think these would also probably get rid of the need for the Free trait there?
This would be an API break but IMHO moving towards a safe interface would be worth it. Although, I suppose, we could probably keep the existing unsafe interfaces present but deprecated.
I can try to send you a PR for this, but I would just like to ask first
Rather than passing a pointer to a block of uninitialized memory, which can easily lead to UB, these functions now just return Rust objects.
This improves duckdb#414 by reducing the amount of unsafe code needed from extensions.
The VTab trait
https://github.com/duckdb/duckdb-rs/blob/main/crates/duckdb/src/vtab/mod.rs
has
This interface is a bit easy to misuse in Rust. The user's implementation of
bind
is called withdata
pointing to an allocated block that is large enough to hold aSelf::BindData
but uninitialized.As a result, if you convert the pointer to a
&mut
ref you get undefined behavior. https://github.com/duckdb/duckdb-rs/blob/main/crates/duckdb/examples/hello-ext/main.rs suggests doing this: it may be safe in the specific case of that code, I haven't checked, but if a more realistic implementation has more complex data then it can cause memory corruption.So, at least, it would be nice to document this more.
But, since this is meant to be the higher-level interface, I think we could do better and just make the interface entirely safe?
I think there are a couple of potentially feasible approaches. Which one would actually work would take some experimentation:
vtab::bind
could just create and return the binddata that it wants, which could then be put in a box and passed to the C API?VTab::BindData: Default
then it could be initialized to the default value and passed in as a&mut
.I think these would also probably get rid of the need for the
Free
trait there?This would be an API break but IMHO moving towards a safe interface would be worth it. Although, I suppose, we could probably keep the existing unsafe interfaces present but deprecated.
I can try to send you a PR for this, but I would just like to ask first
cc @joewalnes
The text was updated successfully, but these errors were encountered: