glib: properly handle passing NULL to GString
GString can hold a pointer that might be null and calling slice::from_raw_part
on it causes an UB. Instead, we now return an empty string in such case
@@ -45,7 +45,6 @@ impl GString {
/// The underlying string must not be mutated, in particular in terms of
/// length, underneath the `GString` instance.
unsafe fn new(ptr: *mut c_char) -> Self {
- assert!(!ptr.is_null());
GString(Inner::Foreign(ptr, libc::strlen(ptr)))
}
@@ -62,13 +61,15 @@ impl GString {
/// The underlying string must not be mutated, in particular in terms of
/// length, underneath the `GString` instance for the duration of the borrow.
unsafe fn new_borrowed(ptr: *const c_char) -> Borrowed<Self> {
- assert!(!ptr.is_null());
Borrowed::new(GString(Inner::Foreign(ptr as *mut _, libc::strlen(ptr))))
}
pub fn as_str(&self) -> &str {
let cstr = match self {
GString(Inner::Foreign(ptr, length)) => unsafe {
+ if ptr.is_null() || length == &0 {
+ return "";
+ }
let bytes = slice::from_raw_parts(*ptr as *const u8, length + 1);
CStr::from_bytes_with_nul_unchecked(bytes)
},
@@ -109,7 +110,11 @@ impl hash::Hash for GString {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
let bytes = match self {
GString(Inner::Foreign(ptr, length)) => unsafe {
+ if ptr.is_null() || length == &0 {
+ b""
+ } else {
slice::from_raw_parts(*ptr as *const u8, length + 1)
+ }
},
GString(Inner::Native(cstring)) => cstring
.as_ref()
@@ -411,7 +416,7 @@ impl<'a> FromGlibContainer<*const c_char, *const i8> for GString {
return Self::from("");
}
let mut bytes = Vec::with_capacity(num + 1);
- let slice = std::slice::from_raw_parts(ptr as *const u8, num);
+ let slice = slice::from_raw_parts(ptr as *const u8, num);
bytes.extend_from_slice(slice);
bytes.push(0);
@@ -419,16 +424,10 @@ impl<'a> FromGlibContainer<*const c_char, *const i8> for GString {
}
unsafe fn from_glib_container_num(ptr: *const i8, num: usize) -> Self {
- if num == 0 || ptr.is_null() {
- return GString::from("");
- }
GString(Inner::Foreign(ptr as *mut _, num))
}
unsafe fn from_glib_full_num(ptr: *const i8, num: usize) -> Self {
- if num == 0 || ptr.is_null() {
- return GString::from("");
- }
GString(Inner::Foreign(ptr as *mut _, num))
}
}
