diff options
| author | Peter Atashian <retep998@gmail.com> | 2014-09-06 12:51:42 -0400 |
|---|---|---|
| committer | Peter Atashian <retep998@gmail.com> | 2014-09-06 12:51:42 -0400 |
| commit | d3ec0674bbf031008a5b741d04edc9ebdc466264 (patch) | |
| tree | e8ccb6bf56d87d32a931f7989aa17742fc6587ea /src/libnative | |
| parent | 82c052794d4234752f0154c150d0b40779240db4 (diff) | |
| download | rust-d3ec0674bbf031008a5b741d04edc9ebdc466264.tar.gz rust-d3ec0674bbf031008a5b741d04edc9ebdc466264.zip | |
readdir: return error instead of failing on invalid UTF-16
Fixes #15279 Signed-off-by: Peter Atashian <retep998@gmail.com>
Diffstat (limited to 'src/libnative')
| -rw-r--r-- | src/libnative/io/file_windows.rs | 45 |
1 files changed, 19 insertions, 26 deletions
diff --git a/src/libnative/io/file_windows.rs b/src/libnative/io/file_windows.rs index cb1d79b8397..adc97c6bede 100644 --- a/src/libnative/io/file_windows.rs +++ b/src/libnative/io/file_windows.rs @@ -11,8 +11,7 @@ //! Blocking Windows-based file I/O use alloc::arc::Arc; -use libc::{c_int, c_void}; -use libc; +use libc::{mod, c_int}; use std::c_str::CString; use std::mem; use std::os::windows::fill_utf16_buf_and_decode; @@ -20,7 +19,6 @@ use std::ptr; use std::rt::rtio; use std::rt::rtio::{IoResult, IoError}; use std::str; -use std::vec; pub type fd_t = libc::c_int; @@ -344,8 +342,6 @@ pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> { } pub fn readdir(p: &CString) -> IoResult<Vec<CString>> { - use std::rt::libc_heap::malloc_raw; - fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> { let root = unsafe { CString::new(root.as_ptr(), false) }; let root = Path::new(root); @@ -355,38 +351,35 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> { }).map(|path| root.join(path).to_c_str()).collect() } - extern { - fn rust_list_dir_wfd_size() -> libc::size_t; - fn rust_list_dir_wfd_fp_buf(wfd: *mut libc::c_void) -> *const u16; - } let star = Path::new(unsafe { CString::new(p.as_ptr(), false) }).join("*"); let path = try!(to_utf16(&star.to_c_str())); unsafe { - let wfd_ptr = malloc_raw(rust_list_dir_wfd_size() as uint); - let find_handle = libc::FindFirstFileW(path.as_ptr(), - wfd_ptr as libc::HANDLE); + let mut wfd = mem::zeroed(); + let find_handle = libc::FindFirstFileW(path.as_ptr(), &mut wfd); if find_handle != libc::INVALID_HANDLE_VALUE { - let mut paths = vec!(); - let mut more_files = 1 as libc::c_int; + let mut paths = vec![]; + let mut more_files = 1 as libc::BOOL; while more_files != 0 { - let fp_buf = rust_list_dir_wfd_fp_buf(wfd_ptr as *mut c_void); - if fp_buf as uint == 0 { - fail!("os::list_dir() failure: got null ptr from wfd"); - } else { - let fp_vec = vec::raw::from_buf(fp_buf, libc::wcslen(fp_buf) as uint); - let fp_trimmed = str::truncate_utf16_at_nul(fp_vec.as_slice()); - let fp_str = String::from_utf16(fp_trimmed) - .expect("rust_list_dir_wfd_fp_buf returned invalid UTF-16"); - paths.push(Path::new(fp_str)); + { + let filename = str::truncate_utf16_at_nul(wfd.cFileName); + match String::from_utf16(filename) { + Some(filename) => paths.push(Path::new(filename)), + None => { + assert!(libc::FindClose(find_handle) != 0); + return Err(IoError { + code: super::c::ERROR_ILLEGAL_CHARACTER as uint, + extra: 0, + detail: Some(format!("path was not valid UTF-16: {}", filename)), + }) + }, // FIXME #12056: Convert the UCS-2 to invalid utf-8 instead of erroring + } } - more_files = libc::FindNextFileW(find_handle, - wfd_ptr as libc::HANDLE); + more_files = libc::FindNextFileW(find_handle, &mut wfd); } assert!(libc::FindClose(find_handle) != 0); - libc::free(wfd_ptr as *mut c_void); Ok(prune(p, paths)) } else { Err(super::last_error()) |
