From 573a3a8ba4cefca1eafc3e2df5d0b19c973ab6d9 Mon Sep 17 00:00:00 2001 From: Coro Date: Wed, 12 Aug 2026 09:06:21 -0600 Subject: [PATCH] od: wrap the offset instead of overflowing on a large --traditional label InputOffset::increase_position used unchecked u64 arithmetic, so a --traditional label near u64::MAX aborted on the first read. Byte offset and label are fixed-width addresses, so wrap them like GNU od. Adds a unit test. Fixes #13225. --- src/uu/od/src/input_offset.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/uu/od/src/input_offset.rs b/src/uu/od/src/input_offset.rs index fa8e66c1a05..8f3ed2df1c2 100644 --- a/src/uu/od/src/input_offset.rs +++ b/src/uu/od/src/input_offset.rs @@ -35,9 +35,12 @@ impl InputOffset { /// Increase `byte_pos` and `label` if a label is used. pub fn increase_position(&mut self, n: u64) { - self.byte_pos += n; + // Byte offset and label are fixed-width addresses, so they wrap around + // like GNU od instead of aborting on overflow (a `--traditional` label + // near u64::MAX overflowed the unchecked add). See #13225. + self.byte_pos = self.byte_pos.wrapping_add(n); if let Some(l) = self.label { - self.label = Some(l + n); + self.label = Some(l.wrapping_add(n)); } } @@ -95,6 +98,14 @@ fn test_input_offset() { assert_eq!("0000036", &sut.format_byte_offset()); } +#[test] +fn test_increase_position_wraps_instead_of_overflowing() { + // A --traditional label near u64::MAX must wrap, not abort (#13225). + let mut sut = InputOffset::new(Radix::Hexadecimal, u64::MAX, Some(u64::MAX)); + sut.increase_position(16); + assert_eq!("00000f (00000f)", &sut.format_byte_offset()); +} + #[test] fn test_input_offset_with_label() { let mut sut = InputOffset::new(Radix::Hexadecimal, 10, Some(20));