Do not assume sqlite3_column_text is valid UTF-8.

Fix Statement::value_ref
This commit is contained in:
gwenn 2019-07-22 21:07:53 +02:00
parent b7882380b2
commit f78ac1f2cf
2 changed files with 6 additions and 7 deletions

View File

@ -221,7 +221,7 @@ impl<'stmt> Row<'stmt> {
/// 16 bytes, `Error::InvalidColumnType` will also be returned. /// 16 bytes, `Error::InvalidColumnType` will also be returned.
pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> { pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> {
let idx = idx.idx(self.stmt)?; let idx = idx.idx(self.stmt)?;
let value = self.stmt.value_ref(idx); let value = self.stmt.value_ref(idx)?;
FromSql::column_result(value).map_err(|err| match err { FromSql::column_result(value).map_err(|err| match err {
FromSqlError::InvalidType => { FromSqlError::InvalidType => {
Error::InvalidColumnType(idx, self.stmt.column_name(idx).into(), value.data_type()) Error::InvalidColumnType(idx, self.stmt.column_name(idx).into(), value.data_type())
@ -262,7 +262,7 @@ impl<'stmt> Row<'stmt> {
// returns) to `ValueRef<'a>` is needed because it's only valid until // returns) to `ValueRef<'a>` is needed because it's only valid until
// the next call to sqlite3_step. // the next call to sqlite3_step.
let val_ref = self.stmt.value_ref(idx); let val_ref = self.stmt.value_ref(idx);
Ok(val_ref) val_ref
} }
/// Get the value of a particular column of the result row as a `ValueRef`, /// Get the value of a particular column of the result row as a `ValueRef`,

View File

@ -601,10 +601,10 @@ impl Statement<'_> {
Statement { conn, stmt } Statement { conn, stmt }
} }
pub(crate) fn value_ref(&self, col: usize) -> ValueRef<'_> { pub(crate) fn value_ref(&self, col: usize) -> Result<ValueRef<'_>> {
let raw = unsafe { self.stmt.ptr() }; let raw = unsafe { self.stmt.ptr() };
match self.stmt.column_type(col) { Ok(match self.stmt.column_type(col) {
ffi::SQLITE_NULL => ValueRef::Null, ffi::SQLITE_NULL => ValueRef::Null,
ffi::SQLITE_INTEGER => { ffi::SQLITE_INTEGER => {
ValueRef::Integer(unsafe { ffi::sqlite3_column_int64(raw, col as c_int) }) ValueRef::Integer(unsafe { ffi::sqlite3_column_int64(raw, col as c_int) })
@ -624,8 +624,7 @@ impl Statement<'_> {
// sqlite3_column_text returns UTF8 data, so our unwrap here should be fine. // sqlite3_column_text returns UTF8 data, so our unwrap here should be fine.
let s = s let s = s
.to_str() .to_str()?;
.expect("sqlite3_column_text returned invalid UTF-8");
ValueRef::Text(s) ValueRef::Text(s)
} }
ffi::SQLITE_BLOB => { ffi::SQLITE_BLOB => {
@ -653,7 +652,7 @@ impl Statement<'_> {
} }
} }
_ => unreachable!("sqlite3_column_type returned invalid value"), _ => unreachable!("sqlite3_column_type returned invalid value"),
} })
} }
pub(crate) fn step(&self) -> Result<bool> { pub(crate) fn step(&self) -> Result<bool> {