Handle text with internal nuls

Fix insertion and selection (#657).
This commit is contained in:
gwenn
2020-03-25 19:20:05 +01:00
parent 8c574be1e3
commit f71ea05603
2 changed files with 41 additions and 17 deletions

View File

@@ -237,25 +237,19 @@ fn str_to_cstring(s: &str) -> Result<CString> {
/// Returns `Ok((string ptr, len as c_int, SQLITE_STATIC | SQLITE_TRANSIENT))`
/// normally.
/// Returns errors if the string has embedded nuls or is too large for sqlite.
/// Returns error if the string is too large for sqlite.
/// The `sqlite3_destructor_type` item is always `SQLITE_TRANSIENT` unless
/// the string was empty (in which case it's `SQLITE_STATIC`, and the ptr is
/// static).
fn str_for_sqlite(s: &[u8]) -> Result<(*const c_char, c_int, ffi::sqlite3_destructor_type)> {
let len = len_as_c_int(s.len())?;
if memchr::memchr(0, s).is_none() {
let (ptr, dtor_info) = if len != 0 {
(s.as_ptr() as *const c_char, ffi::SQLITE_TRANSIENT())
} else {
// Return a pointer guaranteed to live forever
("".as_ptr() as *const c_char, ffi::SQLITE_STATIC())
};
Ok((ptr, len, dtor_info))
let (ptr, dtor_info) = if len != 0 {
(s.as_ptr() as *const c_char, ffi::SQLITE_TRANSIENT())
} else {
// There's an embedded nul, so we fabricate a NulError.
let e = CString::new(s);
Err(Error::NulError(e.unwrap_err()))
}
// Return a pointer guaranteed to live forever
("".as_ptr() as *const c_char, ffi::SQLITE_STATIC())
};
Ok((ptr, len, dtor_info))
}
// Helper to cast to c_int safely, returning the correct error type if the cast