std and rustc: explicitly pass c strings to c functions

When strings lose their trailing null, this pattern will become dangerous:

let foo = "bar";
let foo_ptr: *u8 = &foo[0];

Instead we should use c_strs to handle this correctly.
This commit is contained in:
Erick Tryzelaar
2013-07-07 13:30:48 -07:00
parent 3102b1797e
commit bd908d4c0e
4 changed files with 112 additions and 96 deletions

View File

@@ -442,6 +442,7 @@ pub mod ptr_tests {
use super::*;
use prelude::*;
use c_str::ToCStr;
use cast;
use libc;
use str;
@@ -486,7 +487,6 @@ pub mod ptr_tests {
#[test]
fn test_position() {
use c_str::ToCStr;
use libc::c_char;
do "hello".to_c_str().with_ref |p| {
@@ -500,8 +500,6 @@ pub mod ptr_tests {
#[test]
fn test_buf_len() {
use c_str::ToCStr;
do "hello".to_c_str().with_ref |p0| {
do "there".to_c_str().with_ref |p1| {
do "thing".to_c_str().with_ref |p2| {
@@ -608,66 +606,75 @@ pub mod ptr_tests {
#[test]
fn test_ptr_array_each_with_len() {
unsafe {
let one = ~"oneOne";
let two = ~"twoTwo";
let three = ~"threeThree";
let arr: ~[*i8] = ~[
::cast::transmute(&one[0]),
::cast::transmute(&two[0]),
::cast::transmute(&three[0]),
let one = "oneOne".to_c_str();
let two = "twoTwo".to_c_str();
let three = "threeThree".to_c_str();
let arr = ~[
one.with_ref(|buf| buf),
two.with_ref(|buf| buf),
three.with_ref(|buf| buf),
];
let expected_arr = [
one, two, three
];
let arr_ptr = &arr[0];
let mut ctr = 0;
let mut iteration_count = 0;
array_each_with_len(arr_ptr, arr.len(),
|e| {
let actual = str::raw::from_c_str(e);
let expected = expected_arr[ctr].clone();
debug!(
"test_ptr_array_each e: %s, a: %s",
expected, actual);
assert_eq!(actual, expected);
ctr += 1;
iteration_count += 1;
});
assert_eq!(iteration_count, 3u);
do arr.as_imm_buf |arr_ptr, arr_len| {
let mut ctr = 0;
let mut iteration_count = 0;
do array_each_with_len(arr_ptr, arr_len) |e| {
let actual = str::raw::from_c_str(e);
let expected = do expected_arr[ctr].with_ref |buf| {
str::raw::from_c_str(buf)
};
debug!(
"test_ptr_array_each_with_len e: %s, a: %s",
expected, actual);
assert_eq!(actual, expected);
ctr += 1;
iteration_count += 1;
}
assert_eq!(iteration_count, 3u);
}
}
}
#[test]
fn test_ptr_array_each() {
unsafe {
let one = ~"oneOne";
let two = ~"twoTwo";
let three = ~"threeThree";
let arr: ~[*i8] = ~[
::cast::transmute(&one[0]),
::cast::transmute(&two[0]),
::cast::transmute(&three[0]),
let one = "oneOne".to_c_str();
let two = "twoTwo".to_c_str();
let three = "threeThree".to_c_str();
let arr = ~[
one.with_ref(|buf| buf),
two.with_ref(|buf| buf),
three.with_ref(|buf| buf),
// fake a null terminator
0 as *i8
null(),
];
let expected_arr = [
one, two, three
];
let arr_ptr = &arr[0];
let mut ctr = 0;
let mut iteration_count = 0;
array_each(arr_ptr, |e| {
let actual = str::raw::from_c_str(e);
let expected = expected_arr[ctr].clone();
debug!(
"test_ptr_array_each e: %s, a: %s",
expected, actual);
assert_eq!(actual, expected);
ctr += 1;
iteration_count += 1;
});
assert_eq!(iteration_count, 3);
do arr.as_imm_buf |arr_ptr, arr_len| {
let mut ctr = 0;
let mut iteration_count = 0;
do array_each(arr_ptr) |e| {
let actual = str::raw::from_c_str(e);
let expected = do expected_arr[ctr].with_ref |buf| {
str::raw::from_c_str(buf)
};
debug!(
"test_ptr_array_each e: %s, a: %s",
expected, actual);
assert_eq!(actual, expected);
ctr += 1;
iteration_count += 1;
}
assert_eq!(iteration_count, 3);
}
}
}
#[test]
#[should_fail]
#[ignore(cfg(windows))]