Skip to content

Commit bcb67ee

Browse files
printf: make negative values wrap around with unsigned/hex format
1 parent e6ff6d5 commit bcb67ee

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

src/uucore/src/lib/features/parser/num_parser.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,19 @@ impl ExtendedParser for u64 {
166166
let (digits, scale) = bd.into_bigint_and_scale();
167167
if scale == 0 {
168168
let negative = digits.sign() == Sign::Minus;
169-
match u64::try_from(digits) {
169+
170+
match u64::try_from(digits.clone()) {
170171
Ok(i) => Ok(i),
171-
_ => Err(ExtendedParserError::Overflow(if negative {
172-
// TODO: We should wrap around here #7488
173-
0
174-
} else {
175-
u64::MAX
176-
})),
172+
_ => {
173+
if negative {
174+
match i64::try_from(digits) {
175+
Ok(i) => Ok(u64::from_ne_bytes(i.to_ne_bytes())),
176+
_ => Err(ExtendedParserError::Overflow(0)),
177+
}
178+
} else {
179+
Err(ExtendedParserError::Overflow(u64::MAX))
180+
}
181+
}
177182
}
178183
} else {
179184
// Should not happen.
@@ -500,10 +505,14 @@ mod tests {
500505
fn test_decimal_u64() {
501506
assert_eq!(Ok(123), u64::extended_parse("123"));
502507
assert_eq!(Ok(u64::MAX), u64::extended_parse(&format!("{}", u64::MAX)));
503-
// TODO: We should wrap around here #7488
508+
assert_eq!(Ok(u64::MAX), u64::extended_parse("-1"));
509+
assert_eq!(
510+
Ok(u64::MAX / 2 - 1),
511+
u64::extended_parse("-9223372036854775808")
512+
);
504513
assert!(matches!(
505-
u64::extended_parse("-123"),
506-
Err(ExtendedParserError::Overflow(0))
514+
u64::extended_parse("-9223372036854775809"),
515+
Err(ExtendedParserError::Overflow(_))
507516
));
508517
assert!(matches!(
509518
u64::extended_parse(""),

tests/by-util/test_printf.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,3 +1102,26 @@ fn float_arg_with_whitespace() {
11021102
.fails()
11031103
.stderr_contains("expected a numeric value");
11041104
}
1105+
1106+
#[test]
1107+
fn unsigned_negative_wraparound() {
1108+
new_ucmd!()
1109+
.args(&["%x", "-0b100"])
1110+
.succeeds()
1111+
.stdout_only("fffffffffffffffc");
1112+
1113+
new_ucmd!()
1114+
.args(&["%x", "-0100"])
1115+
.succeeds()
1116+
.stdout_only("ffffffffffffffc0");
1117+
1118+
new_ucmd!()
1119+
.args(&["%x", "-100"])
1120+
.succeeds()
1121+
.stdout_only("ffffffffffffff9c");
1122+
1123+
new_ucmd!()
1124+
.args(&["%x", "-0x100"])
1125+
.succeeds()
1126+
.stdout_only("ffffffffffffff00");
1127+
}

0 commit comments

Comments
 (0)