From 1d3ffdf98d87734c8c2928a3398e5d80dde1be0c Mon Sep 17 00:00:00 2001 From: Pablo Garcia Date: Mon, 17 Aug 2026 22:49:20 +0200 Subject: [PATCH] cmp: use checked subtraction for the verbose offset padding The --verbose branch of format_verbose_difference padded the byte-offset column with a plain subtraction while the --print-bytes branch above it already used saturating_sub. offset_width is derived from the smaller file's metadata length, so a file reporting length 0 that still yields bytes (/dev/zero) collapses it to 2 and the subtraction underflows once the offset reaches three digits. Fixes #265 --- src/cmp.rs | 2 +- tests/integration.rs | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/cmp.rs b/src/cmp.rs index e3534a0..0f7250c 100644 --- a/src/cmp.rs +++ b/src/cmp.rs @@ -607,7 +607,7 @@ fn format_verbose_difference( } else { // "{:>width$} {:>3o} {:>3o}" let at_byte_str = at_byte_buf.format(at_byte); - let at_byte_padding = offset_width - at_byte_str.len(); + let at_byte_padding = offset_width.saturating_sub(at_byte_str.len()); for _ in 0..at_byte_padding { output.push(b' ') diff --git a/tests/integration.rs b/tests/integration.rs index e6b14e2..12aabb8 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -348,6 +348,26 @@ mod diff { mod cmp { use super::*; + // A file whose metadata length is 0 but which still yields bytes (/dev/zero) + // collapses the offset column to two characters, so the padding subtraction + // underflowed once the running offset reached three digits. + #[test] + #[cfg(unix)] + fn cmp_verbose_zero_length_metadata() -> Result<(), Box> { + let mut file = NamedTempFile::new()?; + file.write_all(&[0xffu8; 150])?; + + let mut cmd = cargo_bin_cmd!("diffutils"); + cmd.arg("cmp") + .arg("--verbose") + .arg("/dev/zero") + .arg(file.path()); + cmd.assert() + .code(predicate::eq(1)) + .stdout(predicate::str::contains("150 0 377")); + Ok(()) + } + #[test] fn cmp_incompatible_params() -> Result<(), Box> { let mut cmd = cargo_bin_cmd!("diffutils");