From 701389605d726e58156e9080c08d1a34de636790 Mon Sep 17 00:00:00 2001 From: gwenn Date: Wed, 24 Jul 2019 20:46:53 +0200 Subject: [PATCH] Do not assume `sqlite3_column_text` is valid UTF-8 Fix impact on features --- src/pragma.rs | 2 +- src/types/serde_json.rs | 2 +- src/types/url.rs | 8 +++++--- src/types/value_ref.rs | 12 ++++-------- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/pragma.rs b/src/pragma.rs index a28c8d7..52d334a 100644 --- a/src/pragma.rs +++ b/src/pragma.rs @@ -86,7 +86,7 @@ impl Sql { self.push_real(r); } ValueRef::Text(s) => { - let s = std::str::from_utf8(s).expect("invalid UTF-8"); + let s = std::str::from_utf8(s)?; self.push_string_literal(s); } _ => { diff --git a/src/types/serde_json.rs b/src/types/serde_json.rs index 54275dd..7460b31 100644 --- a/src/types/serde_json.rs +++ b/src/types/serde_json.rs @@ -17,7 +17,7 @@ impl ToSql for Value { impl FromSql for Value { fn column_result(value: ValueRef<'_>) -> FromSqlResult { match value { - ValueRef::Text(s) => serde_json::from_str(s), + ValueRef::Text(s) => serde_json::from_slice(s), ValueRef::Blob(b) => serde_json::from_slice(b), _ => return Err(FromSqlError::InvalidType), } diff --git a/src/types/url.rs b/src/types/url.rs index 6d96028..1c9c63a 100644 --- a/src/types/url.rs +++ b/src/types/url.rs @@ -14,10 +14,12 @@ impl ToSql for Url { impl FromSql for Url { fn column_result(value: ValueRef<'_>) -> FromSqlResult { match value { - ValueRef::Text(s) => Url::parse(s), - _ => return Err(FromSqlError::InvalidType), + ValueRef::Text(s) => { + let s = std::str::from_utf8(s).map_err(|e| FromSqlError::Other(Box::new(e)))?; + Url::parse(s).map_err(|e| FromSqlError::Other(Box::new(e))) + } + _ => Err(FromSqlError::InvalidType), } - .map_err(|err| FromSqlError::Other(Box::new(err))) } } diff --git a/src/types/value_ref.rs b/src/types/value_ref.rs index 01542d4..9a48bcf 100644 --- a/src/types/value_ref.rs +++ b/src/types/value_ref.rs @@ -54,10 +54,9 @@ impl<'a> ValueRef<'a> { /// `Err(Error::InvalidColumnType)`. pub fn as_str(&self) -> FromSqlResult<&'a str> { match *self { - ValueRef::Text(t) => match std::str::from_utf8(t) { - Err(e) => Err(FromSqlError::Other(Box::new(e))), - Ok(r) => Ok(r), - }, + ValueRef::Text(t) => { + std::str::from_utf8(t).map_err(|e| FromSqlError::Other(Box::new(e))) + } _ => Err(FromSqlError::InvalidType), } } @@ -131,10 +130,7 @@ impl<'a> ValueRef<'a> { ); let s = CStr::from_ptr(text as *const c_char); - // sqlite3_value_text returns UTF8 data, so our unwrap here should be fine. - let s = s - .to_str() - .expect("sqlite3_value_text returned invalid UTF-8"); + let s = s.to_bytes(); ValueRef::Text(s) } ffi::SQLITE_BLOB => {