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:
@@ -2400,11 +2400,10 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
|
|||||||
(rust_main, args)
|
(rust_main, args)
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = llvm::LLVMBuildCall(bld,
|
let result = do args.as_imm_buf |buf, len| {
|
||||||
start_fn,
|
llvm::LLVMBuildCall(bld, start_fn, buf, len as c_uint, noname())
|
||||||
&args[0],
|
};
|
||||||
args.len() as c_uint,
|
|
||||||
noname());
|
|
||||||
llvm::LLVMBuildRet(bld, result);
|
llvm::LLVMBuildRet(bld, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2652,7 +2652,7 @@ pub mod funcs {
|
|||||||
pub fn execvpe(c: *c_char, argv: **c_char, envp: **c_char)
|
pub fn execvpe(c: *c_char, argv: **c_char, envp: **c_char)
|
||||||
-> c_int;
|
-> c_int;
|
||||||
#[link_name = "_getcwd"]
|
#[link_name = "_getcwd"]
|
||||||
pub fn getcwd(buf: *c_char, size: size_t) -> *c_char;
|
pub fn getcwd(buf: *mut c_char, size: size_t) -> *c_char;
|
||||||
#[link_name = "_getpid"]
|
#[link_name = "_getpid"]
|
||||||
pub fn getpid() -> c_int;
|
pub fn getpid() -> c_int;
|
||||||
#[link_name = "_isatty"]
|
#[link_name = "_isatty"]
|
||||||
@@ -2804,7 +2804,7 @@ pub mod funcs {
|
|||||||
pub fn execvp(c: *c_char, argv: **c_char) -> c_int;
|
pub fn execvp(c: *c_char, argv: **c_char) -> c_int;
|
||||||
pub fn fork() -> pid_t;
|
pub fn fork() -> pid_t;
|
||||||
pub fn fpathconf(filedes: c_int, name: c_int) -> c_long;
|
pub fn fpathconf(filedes: c_int, name: c_int) -> c_long;
|
||||||
pub fn getcwd(buf: *c_char, size: size_t) -> *c_char;
|
pub fn getcwd(buf: *mut c_char, size: size_t) -> *c_char;
|
||||||
pub fn getegid() -> gid_t;
|
pub fn getegid() -> gid_t;
|
||||||
pub fn geteuid() -> uid_t;
|
pub fn geteuid() -> uid_t;
|
||||||
pub fn getgid() -> gid_t ;
|
pub fn getgid() -> gid_t ;
|
||||||
|
|||||||
@@ -74,14 +74,15 @@ pub static TMPBUF_SZ : uint = 1000u;
|
|||||||
static BUF_BYTES : uint = 2048u;
|
static BUF_BYTES : uint = 2048u;
|
||||||
|
|
||||||
pub fn getcwd() -> Path {
|
pub fn getcwd() -> Path {
|
||||||
let buf = [0 as libc::c_char, ..BUF_BYTES];
|
let mut buf = [0 as libc::c_char, ..BUF_BYTES];
|
||||||
unsafe {
|
do buf.as_mut_buf |buf, len| {
|
||||||
if(0 as *libc::c_char == libc::getcwd(
|
unsafe {
|
||||||
&buf[0],
|
if libc::getcwd(buf, len as size_t).is_null() {
|
||||||
BUF_BYTES as libc::size_t)) {
|
fail!()
|
||||||
fail!();
|
}
|
||||||
|
|
||||||
|
Path(str::raw::from_c_str(buf as *c_char))
|
||||||
}
|
}
|
||||||
Path(str::raw::from_c_str(&buf[0]))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,18 +465,18 @@ pub fn self_exe_path() -> Option<Path> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
use libc::funcs::posix01::unistd::readlink;
|
use libc::funcs::posix01::unistd::readlink;
|
||||||
|
|
||||||
let mut path_str = str::with_capacity(TMPBUF_SZ);
|
let mut path = [0 as c_char, .. TMPBUF_SZ];
|
||||||
let len = do path_str.to_c_str().with_ref |buf| {
|
|
||||||
let buf = buf as *mut c_char;
|
do path.as_mut_buf |buf, len| {
|
||||||
do "/proc/self/exe".to_c_str().with_ref |proc_self_buf| {
|
let len = do "/proc/self/exe".to_c_str.with_ref |proc_self_buf| {
|
||||||
readlink(proc_self_buf, buf, TMPBUF_SZ as size_t)
|
readlink(proc_self_buf, buf, len as size_t) as uint
|
||||||
|
};
|
||||||
|
|
||||||
|
if len == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(str::raw::from_buf_len(buf as *u8, len))
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if len == -1 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
str::raw::set_len(&mut path_str, len as uint);
|
|
||||||
Some(path_str)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -699,13 +700,15 @@ pub fn list_dir(p: &Path) -> ~[~str] {
|
|||||||
extern {
|
extern {
|
||||||
fn rust_list_dir_val(ptr: *dirent_t) -> *libc::c_char;
|
fn rust_list_dir_val(ptr: *dirent_t) -> *libc::c_char;
|
||||||
}
|
}
|
||||||
let input = p.to_str();
|
|
||||||
let mut strings = ~[];
|
let mut strings = ~[];
|
||||||
let input_ptr = ::cast::transmute(&input[0]);
|
|
||||||
debug!("os::list_dir -- BEFORE OPENDIR");
|
debug!("os::list_dir -- BEFORE OPENDIR");
|
||||||
let dir_ptr = opendir(input_ptr);
|
|
||||||
|
let dir_ptr = do p.to_c_str().with_ref |buf| {
|
||||||
|
opendir(buf)
|
||||||
|
};
|
||||||
|
|
||||||
if (dir_ptr as uint != 0) {
|
if (dir_ptr as uint != 0) {
|
||||||
debug!("os::list_dir -- opendir() SUCCESS");
|
debug!("os::list_dir -- opendir() SUCCESS");
|
||||||
let mut entry_ptr = readdir(dir_ptr);
|
let mut entry_ptr = readdir(dir_ptr);
|
||||||
while (entry_ptr as uint != 0) {
|
while (entry_ptr as uint != 0) {
|
||||||
strings.push(str::raw::from_c_str(rust_list_dir_val(
|
strings.push(str::raw::from_c_str(rust_list_dir_val(
|
||||||
@@ -715,7 +718,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
|
|||||||
closedir(dir_ptr);
|
closedir(dir_ptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
debug!("os::list_dir -- opendir() FAILURE");
|
debug!("os::list_dir -- opendir() FAILURE");
|
||||||
}
|
}
|
||||||
debug!(
|
debug!(
|
||||||
"os::list_dir -- AFTER -- #: %?",
|
"os::list_dir -- AFTER -- #: %?",
|
||||||
@@ -1043,14 +1046,15 @@ pub fn last_os_error() -> ~str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut buf = [0 as c_char, ..TMPBUF_SZ];
|
let mut buf = [0 as c_char, ..TMPBUF_SZ];
|
||||||
unsafe {
|
|
||||||
let err = strerror_r(errno() as c_int, &mut buf[0],
|
|
||||||
TMPBUF_SZ as size_t);
|
|
||||||
if err < 0 {
|
|
||||||
fail!("strerror_r failure");
|
|
||||||
}
|
|
||||||
|
|
||||||
str::raw::from_c_str(&buf[0])
|
do buf.as_mut_buf |buf, len| {
|
||||||
|
unsafe {
|
||||||
|
if strerror_r(errno() as c_int, buf, len as size_t) < 0 {
|
||||||
|
fail!("strerror_r failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
str::raw::from_c_str(buf as *c_char)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1076,23 +1080,29 @@ pub fn last_os_error() -> ~str {
|
|||||||
static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
|
static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
|
||||||
static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
|
static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
|
||||||
|
|
||||||
let mut buf = [0 as c_char, ..TMPBUF_SZ];
|
|
||||||
|
|
||||||
// This value is calculated from the macro
|
// This value is calculated from the macro
|
||||||
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
|
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
|
||||||
let langId = 0x0800 as DWORD;
|
let langId = 0x0800 as DWORD;
|
||||||
let err = errno() as DWORD;
|
let err = errno() as DWORD;
|
||||||
unsafe {
|
|
||||||
let res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
ptr::mut_null(), err, langId,
|
|
||||||
&mut buf[0], TMPBUF_SZ as DWORD,
|
|
||||||
ptr::null());
|
|
||||||
if res == 0 {
|
|
||||||
fail!("[%?] FormatMessage failure", errno());
|
|
||||||
}
|
|
||||||
|
|
||||||
str::raw::from_c_str(&buf[0])
|
let mut buf = [0 as c_char, ..TMPBUF_SZ];
|
||||||
|
|
||||||
|
do buf.as_imm_buf |buf, len| {
|
||||||
|
unsafe {
|
||||||
|
let res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
ptr::mut_null(),
|
||||||
|
err,
|
||||||
|
langId,
|
||||||
|
buf,
|
||||||
|
len as DWORD,
|
||||||
|
ptr::null());
|
||||||
|
if res == 0 {
|
||||||
|
fail!("[%?] FormatMessage failure", errno());
|
||||||
|
}
|
||||||
|
|
||||||
|
str::raw::from_c_str(buf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -442,6 +442,7 @@ pub mod ptr_tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
|
use c_str::ToCStr;
|
||||||
use cast;
|
use cast;
|
||||||
use libc;
|
use libc;
|
||||||
use str;
|
use str;
|
||||||
@@ -486,7 +487,6 @@ pub mod ptr_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_position() {
|
fn test_position() {
|
||||||
use c_str::ToCStr;
|
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
|
|
||||||
do "hello".to_c_str().with_ref |p| {
|
do "hello".to_c_str().with_ref |p| {
|
||||||
@@ -500,8 +500,6 @@ pub mod ptr_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_buf_len() {
|
fn test_buf_len() {
|
||||||
use c_str::ToCStr;
|
|
||||||
|
|
||||||
do "hello".to_c_str().with_ref |p0| {
|
do "hello".to_c_str().with_ref |p0| {
|
||||||
do "there".to_c_str().with_ref |p1| {
|
do "there".to_c_str().with_ref |p1| {
|
||||||
do "thing".to_c_str().with_ref |p2| {
|
do "thing".to_c_str().with_ref |p2| {
|
||||||
@@ -608,66 +606,75 @@ pub mod ptr_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_ptr_array_each_with_len() {
|
fn test_ptr_array_each_with_len() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let one = ~"oneOne";
|
let one = "oneOne".to_c_str();
|
||||||
let two = ~"twoTwo";
|
let two = "twoTwo".to_c_str();
|
||||||
let three = ~"threeThree";
|
let three = "threeThree".to_c_str();
|
||||||
let arr: ~[*i8] = ~[
|
let arr = ~[
|
||||||
::cast::transmute(&one[0]),
|
one.with_ref(|buf| buf),
|
||||||
::cast::transmute(&two[0]),
|
two.with_ref(|buf| buf),
|
||||||
::cast::transmute(&three[0]),
|
three.with_ref(|buf| buf),
|
||||||
];
|
];
|
||||||
let expected_arr = [
|
let expected_arr = [
|
||||||
one, two, three
|
one, two, three
|
||||||
];
|
];
|
||||||
let arr_ptr = &arr[0];
|
|
||||||
let mut ctr = 0;
|
do arr.as_imm_buf |arr_ptr, arr_len| {
|
||||||
let mut iteration_count = 0;
|
let mut ctr = 0;
|
||||||
array_each_with_len(arr_ptr, arr.len(),
|
let mut iteration_count = 0;
|
||||||
|e| {
|
do array_each_with_len(arr_ptr, arr_len) |e| {
|
||||||
let actual = str::raw::from_c_str(e);
|
let actual = str::raw::from_c_str(e);
|
||||||
let expected = expected_arr[ctr].clone();
|
let expected = do expected_arr[ctr].with_ref |buf| {
|
||||||
debug!(
|
str::raw::from_c_str(buf)
|
||||||
"test_ptr_array_each e: %s, a: %s",
|
};
|
||||||
expected, actual);
|
debug!(
|
||||||
assert_eq!(actual, expected);
|
"test_ptr_array_each_with_len e: %s, a: %s",
|
||||||
ctr += 1;
|
expected, actual);
|
||||||
iteration_count += 1;
|
assert_eq!(actual, expected);
|
||||||
});
|
ctr += 1;
|
||||||
assert_eq!(iteration_count, 3u);
|
iteration_count += 1;
|
||||||
|
}
|
||||||
|
assert_eq!(iteration_count, 3u);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ptr_array_each() {
|
fn test_ptr_array_each() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let one = ~"oneOne";
|
let one = "oneOne".to_c_str();
|
||||||
let two = ~"twoTwo";
|
let two = "twoTwo".to_c_str();
|
||||||
let three = ~"threeThree";
|
let three = "threeThree".to_c_str();
|
||||||
let arr: ~[*i8] = ~[
|
let arr = ~[
|
||||||
::cast::transmute(&one[0]),
|
one.with_ref(|buf| buf),
|
||||||
::cast::transmute(&two[0]),
|
two.with_ref(|buf| buf),
|
||||||
::cast::transmute(&three[0]),
|
three.with_ref(|buf| buf),
|
||||||
// fake a null terminator
|
// fake a null terminator
|
||||||
0 as *i8
|
null(),
|
||||||
];
|
];
|
||||||
let expected_arr = [
|
let expected_arr = [
|
||||||
one, two, three
|
one, two, three
|
||||||
];
|
];
|
||||||
let arr_ptr = &arr[0];
|
|
||||||
let mut ctr = 0;
|
do arr.as_imm_buf |arr_ptr, arr_len| {
|
||||||
let mut iteration_count = 0;
|
let mut ctr = 0;
|
||||||
array_each(arr_ptr, |e| {
|
let mut iteration_count = 0;
|
||||||
let actual = str::raw::from_c_str(e);
|
do array_each(arr_ptr) |e| {
|
||||||
let expected = expected_arr[ctr].clone();
|
let actual = str::raw::from_c_str(e);
|
||||||
debug!(
|
let expected = do expected_arr[ctr].with_ref |buf| {
|
||||||
"test_ptr_array_each e: %s, a: %s",
|
str::raw::from_c_str(buf)
|
||||||
expected, actual);
|
};
|
||||||
assert_eq!(actual, expected);
|
debug!(
|
||||||
ctr += 1;
|
"test_ptr_array_each e: %s, a: %s",
|
||||||
iteration_count += 1;
|
expected, actual);
|
||||||
});
|
assert_eq!(actual, expected);
|
||||||
assert_eq!(iteration_count, 3);
|
ctr += 1;
|
||||||
|
iteration_count += 1;
|
||||||
|
}
|
||||||
|
assert_eq!(iteration_count, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_fail]
|
#[should_fail]
|
||||||
#[ignore(cfg(windows))]
|
#[ignore(cfg(windows))]
|
||||||
|
|||||||
Reference in New Issue
Block a user