[librsvg: 93/95] PropertyBag: Don't do redundant UTF-8 validation when generating Rust strings
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 93/95] PropertyBag: Don't do redundant UTF-8 validation when generating Rust strings
- Date: Thu, 22 Feb 2018 03:20:57 +0000 (UTC)
commit af5396832078460c04ba438aa7ea29dce8eb3438
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Feb 21 19:59:02 2018 -0600
PropertyBag: Don't do redundant UTF-8 validation when generating Rust strings
The CStr we store come from C strings from libxml2, so they have
already been validated as UTF-8.
rust/src/property_bag.rs | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
---
diff --git a/rust/src/property_bag.rs b/rust/src/property_bag.rs
index ac558758..680b0c88 100644
--- a/rust/src/property_bag.rs
+++ b/rust/src/property_bag.rs
@@ -8,7 +8,7 @@ use std::collections::hash_map;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::ptr;
-use std::str::FromStr;
+use std::str::{self, FromStr};
use attributes::Attribute;
@@ -20,6 +20,19 @@ pub struct PropertyBagIter<'a>(PropertyBagCStrIter<'a>);
pub struct PropertyBagCStrIter<'a>(hash_map::Iter<'a, &'a CStr, (Attribute, &'a CStr)>);
+trait Utf8CStrToStr {
+ fn to_str_utf8(&self) -> &str;
+}
+
+impl Utf8CStrToStr for CStr {
+ fn to_str_utf8(&self) -> &str {
+ // We can *only* do this when the CStr comes from a C string that was validated
+ // as UTF-8 on the C side of things. In our case, the C strings from libxml2 and
+ // are valid UTF-8.
+ unsafe { str::from_utf8_unchecked(self.to_bytes()) }
+ }
+}
+
impl<'a> PropertyBag<'a> {
pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
let mut map = HashMap::new();
@@ -37,7 +50,7 @@ impl<'a> PropertyBag<'a> {
// We silently drop unknown attributes. New attributes should be added in
// build.rs.
- if let Ok(attr) = Attribute::from_str(key_str.to_str().unwrap()) {
+ if let Ok(attr) = Attribute::from_str(key_str.to_str_utf8()) {
map.insert(key_str, (attr, val_str));
}
} else {
@@ -92,7 +105,7 @@ impl<'a> Iterator for PropertyBagIter<'a> {
type Item = (&'a str, Attribute, &'a str);
fn next(&mut self) -> Option<Self::Item> {
- self.0.next().map(|(k, a, v)| (k.to_str().unwrap(), a, v.to_str().unwrap()))
+ self.0.next().map(|(k, a, v)| (k.to_str_utf8(), a, v.to_str_utf8()))
}
}
@@ -242,8 +255,8 @@ mod tests {
&mut key as *mut _,
&mut att as *mut _,
&mut val as *mut _)) {
- let k = unsafe { CStr::from_ptr(key).to_str().unwrap() };
- let v = unsafe { CStr::from_ptr(val).to_str().unwrap() };
+ let k = unsafe { CStr::from_ptr(key).to_str_utf8() };
+ let v = unsafe { CStr::from_ptr(val).to_str_utf8() };
if k == "rx" {
assert!(att == Attribute::Rx);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]