From 8ac8efdb5c06d74ec9d9d628bec07fba0ec61a3b Mon Sep 17 00:00:00 2001 From: youdie006 Date: Tue, 1 Sep 2026 12:21:43 +0900 Subject: [PATCH] Do not panic on a repeated or leading no-newline marker iter_lines_handle_nl asserted that the held line ends in a newline before stripping it, so a second consecutive marker aborted, and a marker with no line before it hit an unconditional panic. Both are reachable from parse_patch, which returns Result. --- src/unified.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/unified.rs b/src/unified.rs index 7caad91..e2c2797 100644 --- a/src/unified.rs +++ b/src/unified.rs @@ -126,12 +126,11 @@ where std::iter::from_fn(move || { for line in iter_lines.by_ref() { if line == NO_NL { + // A repeated or leading marker has nothing to strip; it is not fatal. if let Some(last) = last_line.as_mut() { - assert!(last.ends_with(b"\n")); - // Drop the last newline from `last` - *last = &last[..last.len() - 1]; - } else { - panic!("No newline indicator without previous line"); + if let Some(stripped) = last.strip_suffix(b"\n") { + *last = stripped; + } } } else { if let Some(last) = last_line.take() { @@ -162,6 +161,26 @@ fn test_iter_lines_handle_nl() { assert_eq!(iter.next(), None); } +#[test] +fn test_iter_lines_handle_nl_repeated_marker() { + let lines = vec![ + &b"line 1\n"[..], + &b"\\ No newline at end of file\n"[..], + &b"\\ No newline at end of file\n"[..], + ]; + let mut iter = iter_lines_handle_nl(lines.into_iter()); + assert_eq!(iter.next(), Some("line 1".as_bytes())); + assert_eq!(iter.next(), None); +} + +#[test] +fn test_iter_lines_handle_nl_leading_marker() { + let lines = vec![&b"\\ No newline at end of file\n"[..], &b"line 1\n"[..]]; + let mut iter = iter_lines_handle_nl(lines.into_iter()); + assert_eq!(iter.next(), Some("line 1\n".as_bytes())); + assert_eq!(iter.next(), None); +} + static BINARY_FILES_RE: once_cell::sync::Lazy = once_cell::sync::Lazy::new(|| { lazy_regex::BytesRegex::new(r"^Binary files (.+) and (.+) differ").unwrap()