diff --git a/src/header/netdb/host.rs b/src/header/netdb/host.rs index 576f8d0593..d16ddb02d2 100644 --- a/src/header/netdb/host.rs +++ b/src/header/netdb/host.rs @@ -78,8 +78,7 @@ pub unsafe extern "C" fn gethostent() -> *mut hostent { let mut iter: SplitWhitespace = r.split_whitespace(); - let mut addr_vec = iter.next().unwrap().as_bytes().to_vec(); - addr_vec.push(b'\0'); + let addr_vec: Vec = iter.next().unwrap().bytes().chain(Some(b'\0')).collect(); let addr_cstr = addr_vec.as_slice().as_ptr() as *const i8; let mut addr = mem::MaybeUninit::uninit(); inet_aton(addr_cstr, addr.as_mut_ptr()); @@ -90,16 +89,11 @@ pub unsafe extern "C" fn gethostent() -> *mut hostent { HOST_ADDR = Some(addr); - let mut host_name = iter.next().unwrap().as_bytes().to_vec(); - host_name.push(b'\0'); + let host_name = iter.next().unwrap().bytes().chain(Some(b'\0')).collect(); - let mut _host_aliases: Vec> = Vec::new(); - - for s in iter { - let mut alias = s.as_bytes().to_vec(); - alias.push(b'\0'); - _host_aliases.push(alias); - } + let mut _host_aliases: Vec> = iter + .map(|alias| alias.bytes().chain(Some(b'\0')).collect()) + .collect(); HOST_ALIASES = Some(_host_aliases); let mut host_aliases: Vec<*mut i8> = HOST_ALIASES @@ -107,9 +101,8 @@ pub unsafe extern "C" fn gethostent() -> *mut hostent { .unwrap() .iter_mut() .map(|x| x.as_mut_ptr() as *mut i8) + .chain([ptr::null_mut(), ptr::null_mut()]) .collect(); - host_aliases.push(ptr::null_mut()); - host_aliases.push(ptr::null_mut()); HOST_NAME = Some(host_name); diff --git a/src/header/netdb/lookup.rs b/src/header/netdb/lookup.rs index e2cfd60696..4b267b2943 100644 --- a/src/header/netdb/lookup.rs +++ b/src/header/netdb/lookup.rs @@ -107,21 +107,28 @@ pub fn lookup_host(host: &str) -> Result { match Dns::parse(&buf[..count as usize]) { Ok(response) => { - let mut addrs = vec![]; - for answer in response.answers.iter() { - if answer.a_type == 0x0001 && answer.a_class == 0x0001 && answer.data.len() == 4 - { - let addr = in_addr { - s_addr: u32::from_ne_bytes([ - answer.data[0], - answer.data[1], - answer.data[2], - answer.data[3], - ]), - }; - addrs.push(addr); - } - } + let addrs: Vec<_> = response + .answers + .into_iter() + .filter_map(|answer| { + if answer.a_type == 0x0001 + && answer.a_class == 0x0001 + && answer.data.len() == 4 + { + let addr = in_addr { + s_addr: u32::from_ne_bytes([ + answer.data[0], + answer.data[1], + answer.data[2], + answer.data[3], + ]), + }; + Some(addr) + } else { + None + } + }) + .collect(); Ok(LookupHost(addrs.into_iter())) } Err(_err) => Err(EINVAL), @@ -146,19 +153,12 @@ pub fn lookup_addr(addr: in_addr) -> Result>, c_int> { dns_arr[i] = *octet; } - let mut addr_vec: Vec = addr.s_addr.to_ne_bytes().to_vec(); - addr_vec.reverse(); - let mut name: Vec = vec![]; - for octet in addr_vec { - for ch in format!("{}", octet).as_bytes() { - name.push(*ch); - } - name.push(b"."[0]); - } - name.pop(); - for ch in b".IN-ADDR.ARPA" { - name.push(*ch); - } + let addr: [u8; 4] = addr.s_addr.to_ne_bytes(); + // Address intentionally backwards for reverse lookup + let name = format!( + "{}.{}.{}.{}.in-addr.arpa", + addr[3], addr[2], addr[1], addr[0] + ); if dns_vec.len() == 4 { let mut timespec = timespec::default(); @@ -169,7 +169,7 @@ pub fn lookup_addr(addr: in_addr) -> Result>, c_int> { transaction_id: tid, flags: 0x0100, queries: vec![DnsQuery { - name: String::from_utf8(name).unwrap(), + name, q_type: 0x000C, q_class: 0x0001, }], @@ -221,18 +221,22 @@ pub fn lookup_addr(addr: in_addr) -> Result>, c_int> { match Dns::parse(&buf[..count as usize]) { Ok(response) => { - let mut names = vec![]; - for answer in response.answers.iter() { - if answer.a_type == 0x000C && answer.a_class == 0x0001 { - // answer.data is encoded kinda weird. - // Basically length-prefixed strings for each - // subsection of the domain. - // We need to parse this to insert periods where - // they belong (ie at the end of each string) - let data = parse_revdns_answer(&answer.data); - names.push(data); - } - } + let names = response + .answers + .into_iter() + .filter_map(|answer| { + if answer.a_type == 0x000C && answer.a_class == 0x0001 { + // answer.data is encoded kinda weird. + // Basically length-prefixed strings for each + // subsection of the domain. + // We need to parse this to insert periods where + // they belong (ie at the end of each string) + Some(parse_revdns_answer(&answer.data)) + } else { + None + } + }) + .collect(); Ok(names) } Err(_err) => Err(EINVAL), diff --git a/src/header/netdb/mod.rs b/src/header/netdb/mod.rs index c01579af9e..d9d2f8103b 100644 --- a/src/header/netdb/mod.rs +++ b/src/header/netdb/mod.rs @@ -462,29 +462,24 @@ pub unsafe extern "C" fn getnetent() -> *mut netent { let mut iter: SplitWhitespace = r.split_whitespace(); - let mut net_name = iter.next().unwrap().as_bytes().to_vec(); - net_name.push(b'\0'); + let net_name = iter.next().unwrap().bytes().chain(Some(b'\0')).collect(); NET_NAME = Some(net_name); - let mut addr_vec = iter.next().unwrap().as_bytes().to_vec(); - addr_vec.push(b'\0'); + let addr_vec: Vec = iter.next().unwrap().bytes().chain(Some(b'\0')).collect(); let addr_cstr = addr_vec.as_slice().as_ptr() as *const i8; let mut addr = mem::MaybeUninit::uninit(); inet_aton(addr_cstr, addr.as_mut_ptr()); let addr = addr.assume_init(); NET_ADDR = Some(ntohl(addr.s_addr)); - let mut _net_aliases: Vec> = Vec::new(); - for s in iter { - let mut alias = s.as_bytes().to_vec(); - alias.push(b'\0'); - _net_aliases.push(alias); - } + let mut _net_aliases: Vec> = iter + .map(|alias| alias.bytes().chain(Some(b'\0')).collect()) + .collect(); let mut net_aliases: Vec<*mut i8> = _net_aliases .iter_mut() .map(|x| x.as_mut_ptr() as *mut i8) + .chain(Some(ptr::null_mut())) .collect(); - net_aliases.push(ptr::null_mut()); NET_ALIASES = Some(_net_aliases); NET_ENTRY = netent { @@ -583,17 +578,14 @@ pub unsafe extern "C" fn getprotoent() -> *mut protoent { num.push(b'\0'); PROTO_NUM = Some(atoi(num.as_mut_slice().as_mut_ptr() as *mut i8)); - let mut _proto_aliases: Vec> = Vec::new(); - for s in iter { - let mut alias = s.as_bytes().to_vec(); - alias.push(b'\0'); - _proto_aliases.push(alias); - } + let mut _proto_aliases: Vec> = iter + .map(|alias| alias.bytes().chain(Some(b'\0')).collect()) + .collect(); let mut proto_aliases: Vec<*mut i8> = _proto_aliases .iter_mut() .map(|x| x.as_mut_ptr() as *mut i8) + .chain(Some(ptr::null_mut())) .collect(); - proto_aliases.push(ptr::null_mut()); PROTO_ALIASES = Some(_proto_aliases); PROTO_NAME = Some(proto_name); @@ -692,28 +684,25 @@ pub unsafe extern "C" fn getservent() -> *mut servent { }; let mut iter = r.split_whitespace(); - let mut serv_name = match iter.next() { - Some(serv_name) => serv_name.as_bytes().to_vec(), + let serv_name = match iter.next() { + Some(serv_name) => serv_name.bytes().chain(Some(b'\0')).collect(), None => continue, }; - serv_name.push(b'\0'); let port_proto = match iter.next() { Some(port_proto) => port_proto, None => continue, }; let mut split = port_proto.split('/'); - let mut port = match split.next() { - Some(port) => port.as_bytes().to_vec(), + let mut port: Vec = match split.next() { + Some(port) => port.bytes().chain(Some(b'\0')).collect(), None => continue, }; - port.push(b'\0'); SERV_PORT = Some(htons(atoi(port.as_mut_slice().as_mut_ptr() as *mut i8) as u16) as u32 as i32); - let mut proto = match split.next() { - Some(proto) => proto.as_bytes().to_vec(), + let proto = match split.next() { + Some(proto) => proto.bytes().chain(Some(b'\0')).collect(), None => continue, }; - proto.push(b'\0'); rlb.next(); S_POS = rlb.line_pos(); diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index df8f8c6fa6..19a09373ee 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -308,9 +308,12 @@ pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) - if !path_env.is_null() { let path_env = CStr::from_ptr(path_env); for path in path_env.to_bytes().split(|&b| b == PATH_SEPARATOR) { - let mut program = path.to_vec(); + let file = file.to_bytes(); + let length = file.len() + path.len() + 2; + let mut program = alloc::vec::Vec::with_capacity(length); + program.extend_from_slice(path); program.push(b'/'); - program.extend_from_slice(file.to_bytes()); + program.extend_from_slice(file); program.push(b'\0'); let program_c = CStr::from_bytes_with_nul(&program).unwrap(); diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 541c9430ad..86ae1af3b7 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -219,10 +219,7 @@ impl Pal for Sys { } fn fpath(fildes: c_int, out: &mut [u8]) -> Result { - let mut proc_path = b"/proc/self/fd/".to_vec(); - write!(proc_path, "{}", fildes).unwrap(); - proc_path.push(0); - + let proc_path = format!("/proc/self/fd/{}\0", fildes).into_bytes(); Self::readlink(CStr::from_bytes_with_nul(&proc_path).unwrap(), out) } diff --git a/src/platform/redox/exec.rs b/src/platform/redox/exec.rs index 990502bdd6..da7bb4e640 100644 --- a/src/platform/redox/exec.rs +++ b/src/platform/redox/exec.rs @@ -337,8 +337,7 @@ where { let mut vec = Vec::new(); for item in iter { - vec.extend(item.as_ref()); - vec.push(b'\0'); + vec.extend(item.as_ref().iter().copied().chain(Some(b'\0'))); } vec.into_boxed_slice() }