From 71b2f5187b0cbace3f8b6ff53432ff2ca0defcf0 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 12 Apr 2020 11:17:56 -0700 Subject: [PATCH] Ensure type use for auxdata is repr(C) --- src/functions.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/functions.rs b/src/functions.rs index dbf9b6a..df40b18 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -67,6 +67,7 @@ //! Ok(()) //! } //! ``` +use std::any::TypeId; use std::os::raw::{c_int, c_void}; use std::panic::{catch_unwind, RefUnwindSafe, UnwindSafe}; use std::ptr; @@ -177,13 +178,16 @@ impl Context<'_> { /// https://www.sqlite.org/c3ref/get_auxdata.html for a discussion of /// this feature, or the unit tests of this module for an example. pub fn set_aux(&self, arg: c_int, value: T) { - let boxed = Box::into_raw(Box::new((std::any::TypeId::of::(), value))); + let boxed = Box::into_raw(Box::new(AuxData { + id: TypeId::of::(), + value, + })); unsafe { ffi::sqlite3_set_auxdata( self.ctx, arg, boxed as *mut c_void, - Some(free_boxed_value::<(std::any::TypeId, T)>), + Some(free_boxed_value::>), ) }; } @@ -192,20 +196,26 @@ impl Context<'_> { /// via `set_aux`. Returns `Ok(None)` if no data has been associated, /// and . pub fn get_aux(&self, arg: c_int) -> Result> { - let p = unsafe { ffi::sqlite3_get_auxdata(self.ctx, arg) as *mut (std::any::TypeId, T) }; + let p = unsafe { ffi::sqlite3_get_auxdata(self.ctx, arg) as *const AuxData }; if p.is_null() { Ok(None) } else { - let id_val = unsafe { &*p }; - if std::any::TypeId::of::() != id_val.0 { + let id = unsafe { (*p).id }; + if TypeId::of::() != id { Err(Error::GetAuxWrongType) } else { - Ok(Some(&id_val.1)) + Ok(Some(unsafe { &(*p).value })) } } } } +#[repr(C)] +struct AuxData { + id: TypeId, + value: T, +} + /// `feature = "functions"` Aggregate is the callback interface for user-defined /// aggregate function. ///