diff --git a/src/uu/pmap/src/pmap.rs b/src/uu/pmap/src/pmap.rs index 20011348..93c133f1 100644 --- a/src/uu/pmap/src/pmap.rs +++ b/src/uu/pmap/src/pmap.rs @@ -99,9 +99,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if let Some(range) = matches.get_one::(options::RANGE) { match range.matches(',').count() { 0 => { - let address = u64::from_str_radix(range, 16).map_err(|_| { - USimpleError::new(1, format!("failed to parse argument: '{range}'")) - })?; + let address = parse_address(range, range)?; pmap_config.range_low = address; pmap_config.range_high = address; } @@ -112,16 +110,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { pmap_config.range_low = if low.is_empty() { 0 } else { - u64::from_str_radix(low, 16).map_err(|_| { - USimpleError::new(1, format!("failed to parse argument: '{range}'")) - })? + parse_address(low, range)? }; pmap_config.range_high = if high.is_empty() { u64::MAX } else { - u64::from_str_radix(high, 16).map_err(|_| { - USimpleError::new(1, format!("failed to parse argument: '{range}'")) - })? + parse_address(high, range)? }; } _ => { @@ -433,6 +427,17 @@ fn output_device_format(pid: &str, pmap_config: &PmapConfig) -> Result<(), Error Ok(()) } +/// Parse an address for --range: hexadecimal, with or without a 0x prefix, +/// as procps-ng takes it. `range` is the whole argument, for the error. +fn parse_address(address: &str, range: &str) -> UResult { + let digits = address + .strip_prefix("0x") + .or_else(|| address.strip_prefix("0X")) + .unwrap_or(address); + u64::from_str_radix(digits, 16) + .map_err(|_| USimpleError::new(1, format!("failed to parse argument: '{range}'"))) +} + pub fn uu_app() -> Command { Command::new(env!("CARGO_PKG_NAME")) .version(crate_version!()) diff --git a/tests/by-util/test_pmap.rs b/tests/by-util/test_pmap.rs index 43d49d13..b4d55b29 100644 --- a/tests/by-util/test_pmap.rs +++ b/tests/by-util/test_pmap.rs @@ -375,6 +375,11 @@ fn test_range_arg() { "ffffffffffffffff,", ",ffffffffffffffff", "ffffffffffffffff,ffffffffffffffff", + // 0x prefix + "0xc00fee", + "0Xc00fee", + "0xc00,0xfee", + ",0xffffffffffffffff", ] { new_ucmd!().arg(&pid_s).arg(opt).arg(arg).succeeds(); } @@ -397,6 +402,10 @@ fn test_range_arg() { "someinvalidtext,", ",someinvalidtext", "someinvalidtext,someinvalidtext", + // 0x prefix without digits + "0x", + "0x,", + "0x0xc00fee", // too large value (> u64) "f0000000000000000", "f0000000000000000,f0000000000000000",