Skip to content

Commit 382dc5d

Browse files
authored
Merge pull request #2164 from GitoxideLabs/improvements
fix: make non-UTF8 unified diffs possible again.
2 parents a78bf84 + e4eb98e commit 382dc5d

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

gix-diff/src/blob/unified_diff/impls.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ where
200200
buf.clear();
201201
for &(line_type, content) in lines {
202202
buf.push(line_type.to_prefix() as u8);
203-
buf.push_str(std::str::from_utf8(content).map_err(std::io::Error::other)?);
203+
buf.extend_from_slice(content);
204204

205205
if !content.ends_with_str(self.newline) {
206206
buf.push_str(self.newline);

gix-diff/tests/diff/blob/unified_diff.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use gix_diff::blob::{
33
unified_diff::{ConsumeHunk, ContextSize, DiffLineKind, HunkHeader},
44
Algorithm, UnifiedDiff,
55
};
6+
use gix_object::bstr::BString;
67

78
#[test]
89
fn removed_modified_added() -> crate::Result {
@@ -131,6 +132,45 @@ fn context_overlap_by_one_line_move_up() -> crate::Result {
131132
Ok(())
132133
}
133134

135+
#[test]
136+
fn non_utf8() -> crate::Result {
137+
let a = &b"\xC0\x80"[..];
138+
let b = b"ascii";
139+
140+
let interner = gix_diff::blob::intern::InternedInput::new(a, b);
141+
let err = gix_diff::blob::diff(
142+
Algorithm::Myers,
143+
&interner,
144+
UnifiedDiff::new(
145+
&interner,
146+
ConsumeBinaryHunk::new(String::new(), "\n"),
147+
ContextSize::symmetrical(3),
148+
),
149+
)
150+
.unwrap_err();
151+
assert_eq!(
152+
err.to_string(),
153+
"invalid UTF-8 found at byte offset 1",
154+
"strings enforce an encoding, which fails here"
155+
);
156+
157+
let actual = gix_diff::blob::diff(
158+
Algorithm::Myers,
159+
&interner,
160+
UnifiedDiff::new(
161+
&interner,
162+
ConsumeBinaryHunk::new(BString::default(), "\n"),
163+
ContextSize::symmetrical(3),
164+
),
165+
)?;
166+
insta::assert_snapshot!(actual, @r"
167+
@@ -1,1 +1,1 @@
168+
-��
169+
+ascii
170+
");
171+
Ok(())
172+
}
173+
134174
#[test]
135175
fn context_overlap_by_one_line_move_down() -> crate::Result {
136176
let a = "2\n3\n4\n5\n6\n7\n";

0 commit comments

Comments
 (0)