Przeglądaj źródła

Remove some `unsafe` blocks.

Turns out `String` has a `drain` method too.
Simon Sapin 10 lat temu
rodzic
commit
ca6a4aeaa3
3 zmienionych plików z 16 dodań i 27 usunięć
  1. 7 8
      idna/src/punycode.rs
  2. 6 17
      src/lib.rs
  3. 3 2
      src/parser.rs

+ 7 - 8
idna/src/punycode.rs

@@ -185,11 +185,11 @@ pub fn encode(input: &[char]) -> Option<String> {
                         break
                     }
                     let value = t + ((q - t) % (BASE - t));
-                    value_to_digit(value, &mut output);
+                    output.push(value_to_digit(value));
                     q = (q - t) / (BASE - t);
                     k += BASE;
                 }
-                value_to_digit(q, &mut output);
+                output.push(value_to_digit(q));
                 bias = adapt(delta, processed + 1, processed == basic_length);
                 delta = 0;
                 processed += 1;
@@ -203,11 +203,10 @@ pub fn encode(input: &[char]) -> Option<String> {
 
 
 #[inline]
-fn value_to_digit(value: u32, output: &mut String) {
-    let code_point = match value {
-        0 ... 25 => value + 0x61,  // a..z
-        26 ... 35 => value - 26 + 0x30,  // 0..9
+fn value_to_digit(value: u32) -> char {
+    match value {
+        0 ... 25 => (value as u8 + 'a' as u8) as char,  // a..z
+        26 ... 35 => (value as u8 - 26 + '0' as u8) as char,  // 0..9
         _ => panic!()
-    };
-    unsafe { output.as_mut_vec().push(code_point as u8) }
+    }
 }

+ 6 - 17
src/lib.rs

@@ -537,9 +537,7 @@ impl Url {
             // Found a slash other than the initial one
             let last_slash = last_slash + self.path_start as usize;
             let path_end = path_len + self.path_start as usize;
-            unsafe {
-                self.serialization.as_mut_vec().drain(last_slash..path_end);
-            }
+            self.serialization.drain(last_slash..path_end);
             let offset = (path_end - last_slash) as u32;
             if let Some(ref mut index) = self.query_start { *index -= offset }
             if let Some(ref mut index) = self.fragment_start { *index -= offset }
@@ -596,10 +594,7 @@ impl Url {
         match (self.port, port) {
             (None, None) => {}
             (Some(_), None) => {
-                unsafe {
-                    self.serialization.as_mut_vec().drain(
-                        self.host_end as usize .. self.path_start as usize);
-                }
+                self.serialization.drain(self.host_end as usize .. self.path_start as usize);
                 let offset = self.path_start - self.host_end;
                 self.path_start = self.host_end;
                 if let Some(ref mut index) = self.query_start { *index -= offset }
@@ -639,14 +634,10 @@ impl Url {
         if let Some(host) = host {
             self.set_host_internal(try!(Host::parse(host).map_err(|_| ())), None)
         } else if self.has_host() {
-            // Not debug_assert! since this proves that `unsafe` below is OK:
-            assert!(self.byte_at(self.scheme_end) == b':');
-            assert!(self.byte_at(self.path_start) == b'/');
+            debug_assert!(self.byte_at(self.scheme_end) == b':');
+            debug_assert!(self.byte_at(self.path_start) == b'/');
             let new_path_start = self.scheme_end + 1;
-            unsafe {
-                self.serialization.as_mut_vec()
-                    .drain(self.path_start as usize..new_path_start as usize);
-            }
+            self.serialization.drain(self.path_start as usize..new_path_start as usize);
             let offset = self.path_start - new_path_start;
             self.path_start = new_path_start;
             self.username_end = new_path_start;
@@ -750,9 +741,7 @@ impl Url {
             } else {
                 self.host_start - 1  // Keep the '@' to separate the username from the host
             };
-            unsafe {
-                self.serialization.as_mut_vec().drain(start as usize .. end as usize);
-            }
+            self.serialization.drain(start as usize .. end as usize);
             let offset = end - start;
             self.host_start -= offset;
             self.host_end -= offset;

+ 3 - 2
src/parser.rs

@@ -820,8 +820,9 @@ impl<'a> Parser<'a> {
                     if scheme_type.is_file() && is_windows_drive_letter(
                         &self.serialization[path_start + 1..]
                     ) {
-                        unsafe {
-                            *self.serialization.as_mut_vec().last_mut().unwrap() = b':'
+                        if self.serialization.ends_with('|') {
+                            self.serialization.pop();
+                            self.serialization.push(':');
                         }
                         if *has_host {
                             self.syntax_violation("file: with host and Windows drive letter");