mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 13:58:55 +08:00 
			
		
		
		
	Fix panic at 'SQLite API not initialized or SQLite feature omitted'
`to_sqlite_error` needs `sqlite3_malloc` ``` sqlite> .log on sqlite> .load target/debug/examples/libloadable_extension.so Error: error during initialization: SQLite version mismatch: 3014000 < 3042000 ```
This commit is contained in:
		| @@ -25,7 +25,9 @@ pub extern "C" fn sqlite3_extension_init( | ||||
|     pz_err_msg: *mut *mut c_char, | ||||
|     p_api: *mut ffi::sqlite3_api_routines, | ||||
| ) -> c_int { | ||||
|     if let Err(err) = extension_init(db, p_api) { | ||||
|     if p_api.is_null() { | ||||
|         return ffi::SQLITE_ERROR; | ||||
|     } else if let Err(err) = extension_init(db, p_api) { | ||||
|         return unsafe { to_sqlite_error(&err, pz_err_msg) }; | ||||
|     } | ||||
|     ffi::SQLITE_OK | ||||
|   | ||||
| @@ -6267,9 +6267,7 @@ pub unsafe fn sqlite3_expanded_sql( | ||||
| pub unsafe fn rusqlite_extension_init2( | ||||
|     p_api: *mut sqlite3_api_routines, | ||||
| ) -> ::std::result::Result<(), crate::InitError> { | ||||
|     if p_api.is_null() { | ||||
|         return Err(crate::InitError::NullApiPointer); | ||||
|     } | ||||
|     __SQLITE3_MALLOC.store((*p_api).malloc, ::atomic::Ordering::Release); | ||||
|     if let Some(fun) = (*p_api).libversion_number { | ||||
|         let version = fun(); | ||||
|         if SQLITE_VERSION_NUMBER > version { | ||||
| @@ -6371,7 +6369,6 @@ pub unsafe fn rusqlite_extension_init2( | ||||
|     __SQLITE3_LIBVERSION.store((*p_api).libversion, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_LIBVERSION_NUMBER | ||||
|         .store((*p_api).libversion_number, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_MALLOC.store((*p_api).malloc, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_OPEN.store((*p_api).open, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_OPEN16.store((*p_api).open16, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_PREPARE.store((*p_api).prepare, ::atomic::Ordering::Release); | ||||
|   | ||||
| @@ -702,6 +702,7 @@ mod loadable_extension { | ||||
|         let sqlite3_api_routines_ident = sqlite3_api_routines.ident; | ||||
|         let p_api = quote::format_ident!("p_api"); | ||||
|         let mut stores = Vec::new(); | ||||
|         let mut malloc = Vec::new(); | ||||
|         // (2) `#define sqlite3_xyz sqlite3_api->abc` => `pub unsafe fn | ||||
|         // sqlite3_xyz(args) -> ty {...}` for each `abc` field: | ||||
|         for field in sqlite3_api_routines.fields { | ||||
| @@ -764,7 +765,12 @@ mod loadable_extension { | ||||
|                 &syn::parse2(tokens).expect("could not parse quote output"), | ||||
|             )); | ||||
|             output.push('\n'); | ||||
|             stores.push(quote::quote! { | ||||
|             if name == "malloc" { | ||||
|                 &mut malloc | ||||
|             } else { | ||||
|                 &mut stores | ||||
|             } | ||||
|             .push(quote::quote! { | ||||
|                 #ptr_name.store( | ||||
|                     (*#p_api).#ident, | ||||
|                     ::atomic::Ordering::Release, | ||||
| @@ -775,9 +781,7 @@ mod loadable_extension { | ||||
|         let tokens = quote::quote! { | ||||
|             /// Like SQLITE_EXTENSION_INIT2 macro | ||||
|             pub unsafe fn rusqlite_extension_init2(#p_api: *mut #sqlite3_api_routines_ident) -> ::std::result::Result<(),crate::InitError> { | ||||
|                 if #p_api.is_null() { | ||||
|                     return Err(crate::InitError::NullApiPointer); | ||||
|                 } | ||||
|                 #(#malloc)* // sqlite3_malloc needed by to_sqlite_error | ||||
|                 if let Some(fun) = (*#p_api).libversion_number { | ||||
|                     let version = fun(); | ||||
|                     if SQLITE_VERSION_NUMBER > version { | ||||
|   | ||||
| @@ -7463,9 +7463,7 @@ pub unsafe fn sqlite3_is_interrupted(arg1: *mut sqlite3) -> ::std::os::raw::c_in | ||||
| pub unsafe fn rusqlite_extension_init2( | ||||
|     p_api: *mut sqlite3_api_routines, | ||||
| ) -> ::std::result::Result<(), crate::InitError> { | ||||
|     if p_api.is_null() { | ||||
|         return Err(crate::InitError::NullApiPointer); | ||||
|     } | ||||
|     __SQLITE3_MALLOC.store((*p_api).malloc, ::atomic::Ordering::Release); | ||||
|     if let Some(fun) = (*p_api).libversion_number { | ||||
|         let version = fun(); | ||||
|         if SQLITE_VERSION_NUMBER > version { | ||||
| @@ -7567,7 +7565,6 @@ pub unsafe fn rusqlite_extension_init2( | ||||
|     __SQLITE3_LIBVERSION.store((*p_api).libversion, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_LIBVERSION_NUMBER | ||||
|         .store((*p_api).libversion_number, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_MALLOC.store((*p_api).malloc, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_OPEN.store((*p_api).open, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_OPEN16.store((*p_api).open16, ::atomic::Ordering::Release); | ||||
|     __SQLITE3_PREPARE.store((*p_api).prepare, ::atomic::Ordering::Release); | ||||
|   | ||||
| @@ -275,8 +275,6 @@ pub fn code_to_str(code: c_int) -> &'static str { | ||||
| #[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||||
| #[non_exhaustive] | ||||
| pub enum InitError { | ||||
|     /// Invalid sqlite3_api_routines pointer | ||||
|     NullApiPointer, | ||||
|     /// Version mismatch between the extension and the SQLite3 library | ||||
|     VersionMismatch { compile_time: i32, runtime: i32 }, | ||||
|     /// Invalid function pointer in one of sqlite3_api_routines fields | ||||
| @@ -286,9 +284,6 @@ pub enum InitError { | ||||
| impl ::std::fmt::Display for InitError { | ||||
|     fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | ||||
|         match *self { | ||||
|             InitError::NullApiPointer => { | ||||
|                 write!(f, "Invalid sqlite3_api_routines pointer") | ||||
|             } | ||||
|             InitError::VersionMismatch { | ||||
|                 compile_time, | ||||
|                 runtime, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user