Bug 1344209: Handle empty strings gracefully in rust nsString bindings. r=mystor
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 03 Mar 2017 15:20:39 +0100
changeset 345907 ec25e01a8ff15b728175f52cdc841129a7e1e8d6
parent 345906 86e1748ab478e23f7a73e2c4af11a310d26fbda9
child 345908 6dfad3d738fed02f68223568f8ceb43df5a4e575
push id38337
push userkwierso@gmail.com
push dateSat, 04 Mar 2017 01:30:14 +0000
treeherderautoland@b691557cb7a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmystor
bugs1344209
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1344209: Handle empty strings gracefully in rust nsString bindings. r=mystor MozReview-Commit-ID: 5lI8LXwZIML Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
xpcom/rust/nsstring/gtest/Test.cpp
xpcom/rust/nsstring/gtest/test.rs
xpcom/rust/nsstring/src/lib.rs
--- a/xpcom/rust/nsstring/gtest/Test.cpp
+++ b/xpcom/rust/nsstring/gtest/Test.cpp
@@ -124,8 +124,13 @@ extern "C" void Rust_AutoAssignFromCpp()
 TEST(RustNsString, AutoAssignFromCpp) {
   Rust_AutoAssignFromCpp();
 }
 
 extern "C" void Rust_StringWrite();
 TEST(RustNsString, StringWrite) {
   Rust_StringWrite();
 }
+
+extern "C" void Rust_FromEmptyRustString();
+TEST(RustNsString, FromEmptyRustString) {
+  Rust_FromEmptyRustString();
+}
--- a/xpcom/rust/nsstring/gtest/test.rs
+++ b/xpcom/rust/nsstring/gtest/test.rs
@@ -105,8 +105,14 @@ pub extern fn Rust_StringWrite() {
     expect_eq!(s, "abc");
     expect_eq!(cs, "abc");
     write!(s, "{}", 123).unwrap();
     write!(cs, "{}", 123).unwrap();
     expect_eq!(s, "abc123");
     expect_eq!(cs, "abc123");
 }
 
+#[no_mangle]
+pub extern fn Rust_FromEmptyRustString() {
+    let mut test = nsString::from("Blah");
+    test.assign_utf8(&nsCString::from(String::new()));
+    assert!(test.is_empty());
+}
--- a/xpcom/rust/nsstring/src/lib.rs
+++ b/xpcom/rust/nsstring/src/lib.rs
@@ -308,28 +308,32 @@ macro_rules! define_string_types {
             }
         }
 
         impl<'a> From<&'a [$char_t]> for $String<'a> {
             fn from(s: &'a [$char_t]) -> $String<'a> {
                 assert!(s.len() < (u32::MAX as usize));
                 $String {
                     hdr: $StringRepr {
-                        data: s.as_ptr(),
+                        data: if s.is_empty() { ptr::null() } else { s.as_ptr() },
                         length: s.len() as u32,
                         flags: F_NONE,
                     },
                     _marker: PhantomData,
                 }
             }
         }
 
         impl From<Box<[$char_t]>> for $String<'static> {
             fn from(s: Box<[$char_t]>) -> $String<'static> {
                 assert!(s.len() < (u32::MAX as usize));
+                if s.is_empty() {
+                    return $String::new();
+                }
+
                 // SAFETY NOTE: This method produces an F_OWNED ns[C]String from
                 // a Box<[$char_t]>. this is only safe because in the Gecko
                 // tree, we use the same allocator for Rust code as for C++
                 // code, meaning that our box can be legally freed with
                 // libc::free().
                 let length = s.len() as u32;
                 let ptr = s.as_ptr();
                 mem::forget(s);