From 538db929cfe596ab6e2695420050271bf4b95589 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Wed, 27 May 2026 23:39:44 +0200 Subject: [PATCH] fix arpa_inet/inet_addr --- src/header/arpa_inet/mod.rs | 63 +++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/header/arpa_inet/mod.rs b/src/header/arpa_inet/mod.rs index 10c13dae35..77d0aefc19 100644 --- a/src/header/arpa_inet/mod.rs +++ b/src/header/arpa_inet/mod.rs @@ -44,42 +44,51 @@ pub unsafe extern "C" fn inet_addr(cp: *const c_char) -> in_addr_t { #[unsafe(no_mangle)] pub unsafe extern "C" fn inet_aton(cp: *const c_char, inp: *mut in_addr) -> c_int { let cp_cstr = unsafe { CStr::from_ptr(cp) }; - let mut four_parts_decimal_only = false; - if cp_cstr.contains(b'.') { - // 2, 3 or 4 part address - let parts = unsafe { str::from_utf8_unchecked(cp_cstr.to_bytes()).split('.') }; - let mut count = 0; - for part in parts { + let parts = unsafe { str::from_utf8_unchecked(cp_cstr.to_bytes()).split('.') }; + let count = parts.clone().count(); + if count > 4 { + return 0; + } + let mut result = 0; + let mut parts_iter = parts.peekable(); + let mut index = 0u32; + while index < 4 + && let Some(part) = parts_iter.next() + { + if let Ok(parsed_value) = { if let Some(hex_or_oct) = part.strip_prefix('0') && part.len() > 1 { match hex_or_oct.bytes().next() { - Some(b'x' | b'X') => todo_skip!(0, "parsing hex values unimplemented"), - // TODO: C2Y accept `0o` or `0O` as octal prefixes, C23 and below only use `0` - _ => todo_skip!(0, "parsing octal values unimplemented"), + Some(b'x' | b'X') => u32::from_str_radix(&hex_or_oct[1..], 16), + Some(b'o' | b'O') => u32::from_str_radix(&hex_or_oct[1..], 8), + _ => u32::from_str_radix(&hex_or_oct, 8), } } else { - count += 1; + u32::from_str_radix(&part, 10) } + } { + if parts_iter.peek().is_some() { + // this is not the last part + if parsed_value > 0xff { + return 0; + } + result += parsed_value << (24 - index * 8); + } else { + // this is the last part + if index > 0 && parsed_value >= 1 << (32 - index * 8) { + return 0; + } else { + result += parsed_value; + } + } + } else { + return 0; } - if count == 4 { - four_parts_decimal_only = true; - } - } else if cp_cstr.len() == 4 { - // 1 part address (32 bit value to be stored directly into address without byte rearrangement) - let s_addr_bytes: [u8; 4] = cp_cstr.to_bytes().try_into().expect("guaranteed 4 bytes"); - unsafe { - (*inp.cast::()).s_addr = in_addr_t::from_ne_bytes(s_addr_bytes); - } - return 1; // successful - } - if four_parts_decimal_only { - unsafe { inet_pton(AF_INET, cp, inp.cast::()) } - } else { - todo_skip!(0, "parsing 2 or more non-decimal values unimplemented"); - // TODO convert octal and hexadecimal parts into decimal and feed into `inet_pton` - 0 // indicates `cp` is an invalid string + index += 1; } + unsafe { (*inp.cast::()).s_addr = result.to_be() }; + 1 } /// See .