-
Notifications
You must be signed in to change notification settings - Fork 19
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
Unsafe enum usage #12
Comments
Currently I am leaning towards adding missing |
That's good, but I'm afraid it's insufficient. There is always a chance that we'll miss some enum variants, or we'll have not so standard compliant odbc implementation or buggy driver which return non standard enum values, or even spec will change adding new enum values. We also need to remember that in C world some enums are used as bitflags actually, so ffi call can return mixed bit combination of enum values. Silently triggering UB in those cases is very user unfriendly and unsafe. It's better to perform fair conversion from ffi returned int to enum and if it was unsuccessful we should return error or at least trigger panic. |
I'm with @Koka on this issue. Since this is a low level crate interfacing C code we can never be too certain rust invariants are kept when crossing FFI boundary. If we can agree on this I would like to implement the change. Proposition:
This means that it would be up to the user to convert returned Are there any other suggestions? |
I've found a way for the best of both worlds by using The proposition now looks like this:
This approach is superior because it provides additional type safety. Users can never construct instances of I've updated the PR related to this |
I am still not sure we have a problem here. The ODBC specification allows us to list all enums. Human error aside, we should be able to provide complete enums. I am not aware of an ODBC function whose returnvalues are specified as bitflags. If there is one, I agree, its return type should not be modled as enum. The only remaining problem I see is if a driver or driver manager would not stick to the specification. If not seen a specific instance of this happening. If this is something which appears in practice I would suggest switching the return types to Integers and working with plain constants. |
Reading the links to the orginal issue again. Let's switch to integer return types. I do not think we need strict newtypes though. |
what do you mean? to dismantle the |
I have just run into SIGSEGV with INTERVAL data type in a query.
The value I got for a query was 106 (ColumnDescriptor::data_type). Personally I think that missing enum variant is a bug (in odbc-ffi or in the driver if value is not part of ODBC spec). Bugs are best handled with panic. So if you could verify a value is represented by an enum before casting to it or otherwise panic with the missing value in the message that would be the most useful. |
I'll convert all |
Since this would be a breaking change I'll combine it with another breaking change I had in mind: Using idiomatic Rust naming schemes (Aka Camel Case). |
Yes, exactly |
Hi @pacman82 , looks like we have an issue in FFI binding which causes UB. Passing mut enum ref across FFI boundaries causes UB in cases when ODBC driver returns value absent in enum.
Details: https://users.rust-lang.org/t/undefined-behaviour-after-unsafe-enum-usage/15572
Related odbc-rs issue: Koka/odbc-rs#66
Related discussion in rust-bindgen: rust-lang/rust-bindgen#667
Looks like it needs to be fixed at lowest level available i.e. in this crate, I'm unsure ho to fix this without harming usability though.
Looks like we could use manual conversion crates like https://crates.io/crates/enum_primitive or declare enums as
#[non_exhaustive]
rust-lang/rust#44109 when it will be ready. Or just declare everything as constants and don't use enums at allThe text was updated successfully, but these errors were encountered: