Browse Source

update tor_allocate and add tests

Chelsea Holland Komlo 6 years ago
parent
commit
7999d0bf6b
1 changed files with 14 additions and 8 deletions
  1. 14 8
      src/rust/tor_allocate/tor_allocate.rs

+ 14 - 8
src/rust/tor_allocate/tor_allocate.rs

@@ -1,5 +1,5 @@
 use libc::{c_char, c_void};
-use std::{ptr, slice};
+use std::{ptr, slice, mem};
 
 #[cfg(not(test))]
 extern "C" {
@@ -19,29 +19,35 @@ extern "C" fn tor_malloc_ ( size: usize) ->  *mut c_void {
 ///
 /// # Inputs
 ///
-/// * `src`, a reference to a String that will be copied.
+/// * `src`, a reference to a String.
 ///
 /// # Returns
 ///
-/// A `String` that should be freed by tor_free in C
+/// A `*mut c_char` that should be freed by tor_free in C
 ///
 pub fn allocate_and_copy_string(src: &String) -> *mut c_char {
-    let bytes = src.as_bytes();
+    let bytes: &[u8] = src.as_bytes();
 
-    let size = bytes.len();
-    let size_with_null_byte = size + 1;
+    let size =  mem::size_of_val::<[u8]>(bytes);
+    let size_one_byte = mem::size_of::<u8>();
+
+    // handle integer overflow when adding one to the calculated length
+    let size_with_null_byte = match size.checked_add(size_one_byte) {
+        Some(n) => n,
+        None => return ptr::null_mut(),
+    };
 
     let dest = unsafe { tor_malloc_(size_with_null_byte) as *mut u8 };
 
     if dest.is_null() {
-        return dest as *mut c_char;
+        return ptr::null_mut();
     }
 
     unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), dest, size) };
 
     // set the last byte as null, using the ability to index into a slice
     // rather than doing pointer arithmatic
-    let slice = unsafe { slice::from_raw_parts_mut(dest, size_with_null_byte) };
+    let slice = unsafe { slice::from_raw_parts_mut(dest, size_with_null_byte)};
     slice[size] = 0; // add a null terminator
 
     dest as *mut c_char