Skip to content

Commit b71319a

Browse files
Fix invalid UTF-8 bug
1 parent 9940e4d commit b71319a

4 files changed

Lines changed: 28 additions & 0 deletions

File tree

.typos.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1+
[files]
2+
extend-exclude = ["**/testdata/**"]
3+
14
[default.extend-words]
25
decorder = "decorder" # Name of a Go linter

internal/diff/chardiff_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ func TestCharDiff(t *testing.T) {
7575
added: []byte("changed\n"),
7676
wantHasChanged: true,
7777
},
78+
{
79+
// Regression: invalid UTF-8 on the added side must not corrupt the join invariant.
80+
// \xe2 is the start of a 3-byte sequence with no continuation bytes.
81+
name: "invalid UTF-8 in added side",
82+
removed: []byte("0"),
83+
added: []byte("\xe2"),
84+
wantHasChanged: true,
85+
},
86+
{
87+
// Regression: invalid UTF-8 on the removed side.
88+
name: "invalid UTF-8 in removed side",
89+
removed: []byte("\xe2"),
90+
added: []byte("0"),
91+
wantHasChanged: true,
92+
},
7893
}
7994

8095
for _, tt := range tests {

internal/diff/chars.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ func CharDiff(removed, added []byte) InlineChange {
3535
addedCore = added[:len(added)-1]
3636
}
3737

38+
// Fall back to whole-line diff for invalid UTF-8: converting invalid bytes
39+
// to runes replaces them with U+FFFD, making it impossible to reconstruct
40+
// the original bytes from the segments.
41+
if !utf8.Valid(removedCore) || !utf8.Valid(addedCore) {
42+
return fallback(removed, added)
43+
}
44+
3845
oldRunes := []rune(string(removedCore))
3946
newRunes := []rune(string(addedCore))
4047

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
go test fuzz v1
2+
[]byte("0")
3+
[]byte("\xe2")

0 commit comments

Comments
 (0)