From 8fdc8820531aa5d45a686bdfd5d107a9ccffb5fb Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Fri, 19 Jun 2026 18:41:09 -0700 Subject: [PATCH 1/2] diffutils: fix panic on non-UTF-8 argument ending in --width=N Signed-off-by: Sai Asish Y --- src/params.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/params.rs b/src/params.rs index 74ef3e37..202f7090 100644 --- a/src/params.rs +++ b/src/params.rs @@ -60,7 +60,7 @@ pub fn parse_params>(mut opts: Peekable) -> Resu let mut format = None; let mut context = None; let tabsize_re = Regex::new(r"^--tabsize=(?\d+)$").unwrap(); - let width_re = Regex::new(r"--width=(?P\d+)$").unwrap(); + let width_re = Regex::new(r"^--width=(?P\d+)$").unwrap(); while let Some(param) = opts.next() { let next_param = opts.peek(); if param == "--" { @@ -813,6 +813,40 @@ mod tests { .is_err()); } #[test] + fn width() { + assert_eq!( + Ok(Params { + executable: os("diff"), + from: os("foo"), + to: os("bar"), + width: 100, + ..Default::default() + }), + parse_params( + [os("diff"), os("--width=100"), os("foo"), os("bar")] + .iter() + .cloned() + .peekable() + ) + ); + } + #[cfg(unix)] + #[test] + fn width_non_utf8_is_not_an_option() { + use std::os::unix::ffi::OsStringExt; + // A non-UTF-8 argument whose lossy form ends in `--width=N` must be + // treated as an operand, not parsed as the width option (which used to + // panic in `into_string().unwrap()`). + let bad = OsString::from_vec(b"\xff--width=5".to_vec()); + assert!(parse_params( + [os("diff"), bad, os("foo"), os("bar")] + .iter() + .cloned() + .peekable() + ) + .is_err()); + } + #[test] fn double_dash() { assert_eq!( Ok(Params { From 8c9a0b38f17a3cf21e50685f6806bd3d1140f3be Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Fri, 25 Sep 2026 09:25:19 -0700 Subject: [PATCH 2/2] diffutils: assert width-like operands are kept as filenames in tests Signed-off-by: Sai Asish Y --- src/params.rs | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/params.rs b/src/params.rs index 202f7090..239ebca4 100644 --- a/src/params.rs +++ b/src/params.rs @@ -830,21 +830,37 @@ mod tests { ) ); } + #[test] + fn width_suffix_is_an_operand() { + assert_eq!( + Ok(Params { + executable: os("diff"), + from: os("xyz--width=5"), + to: os("foo"), + ..Default::default() + }), + parse_params( + [os("diff"), os("xyz--width=5"), os("foo")] + .iter() + .cloned() + .peekable() + ) + ); + } #[cfg(unix)] #[test] fn width_non_utf8_is_not_an_option() { use std::os::unix::ffi::OsStringExt; - // A non-UTF-8 argument whose lossy form ends in `--width=N` must be - // treated as an operand, not parsed as the width option (which used to - // panic in `into_string().unwrap()`). + // used to panic in into_string().unwrap() let bad = OsString::from_vec(b"\xff--width=5".to_vec()); - assert!(parse_params( - [os("diff"), bad, os("foo"), os("bar")] + let params = parse_params( + [os("diff"), bad.clone(), os("foo")] .iter() .cloned() - .peekable() + .peekable(), ) - .is_err()); + .unwrap(); + assert_eq!(params.from, bad); } #[test] fn double_dash() {