Skip to content

Commit 3fe4bc0

Browse files
committed
Fix an utf8 issue
It was possible to reach `last_error_message` before we set the client encoding to utf8. If there is some other default client encoding set, this could lead to an corrupted string violating rust gurantees about strings always being utf8. Additionally I've checked the codebase for other occurrences of `from_utf8_unchecked` and added comments there why they are fine. Having a second (or third) look at them would be helpful.
1 parent b493976 commit 3fe4bc0

4 files changed

Lines changed: 6 additions & 1 deletion

File tree

diesel/src/pg/connection/raw.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fn last_error_message(conn: *const PGconn) -> String {
106106
unsafe {
107107
let error_ptr = PQerrorMessage(conn);
108108
let bytes = CStr::from_ptr(error_ptr).to_bytes();
109-
str::from_utf8_unchecked(bytes).to_string()
109+
String::from_utf8_lossy(bytes).to_string()
110110
}
111111
}
112112

diesel/src/pg/connection/result.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ impl<'a> PgResult<'a> {
5959
unsafe {
6060
let count_char_ptr = PQcmdTuples(self.internal_result.as_ptr());
6161
let count_bytes = CStr::from_ptr(count_char_ptr).to_bytes();
62+
// Using from_utf8_unchecked is ok here because, we've set the
63+
// client encoding to utf8
6264
let count_str = str::from_utf8_unchecked(count_bytes);
6365
match count_str {
6466
"" => 0,

diesel/src/sqlite/connection/raw.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ impl Drop for RawConnection {
133133
fn convert_to_string_and_free(err_msg: *const libc::c_char) -> String {
134134
let msg = unsafe {
135135
let bytes = CStr::from_ptr(err_msg).to_bytes();
136+
// sqlite is documented to return utf8 strings here
136137
str::from_utf8_unchecked(bytes).into()
137138
};
138139
unsafe { ffi::sqlite3_free(err_msg as *mut libc::c_void) };

diesel/src/sqlite/connection/sqlite_value.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ impl SqliteValue {
3535
let ptr = ffi::sqlite3_value_text(self.value());
3636
let len = ffi::sqlite3_value_bytes(self.value());
3737
let bytes = slice::from_raw_parts(ptr as *const u8, len as usize);
38+
// The string is guaranteed to be utf8 according to
39+
// https://www.sqlite.org/c3ref/value_blob.html
3840
str::from_utf8_unchecked(bytes)
3941
}
4042
}

0 commit comments

Comments
 (0)