git: Fix out-of-bounds indexing when diff bases contain CRLF (#52605)

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A
This commit is contained in:
Cole Miller authored and GitHub committed 2026-03-27 21:15:39 +00:00
1 parent 739a532ae2
commit b4d60f9cc9
1 file changed
+33
+33
View File
@@ -1651,6 +1651,7 @@ impl BufferDiff {
language: Option<Arc<Language>>,
cx: &App,
) -> Task<BufferDiffUpdate> {
let base_text = base_text.map(|t| text::LineEnding::normalize_arc(t));
let prev_base_text = self.base_text(cx).as_rope().clone();
let base_text_changed = base_text_change.is_some();
let compute_base_text_edits = base_text_change == Some(true);
@@ -3947,4 +3948,36 @@ mod tests {
}
}
}
#[gpui::test]
async fn test_set_base_text_with_crlf(cx: &mut gpui::TestAppContext) {
let base_text_crlf = "one\r\ntwo\r\nthree\r\nfour\r\nfive\r\n";
let base_text_lf = "one\ntwo\nthree\nfour\nfive\n";
assert_ne!(base_text_crlf.len(), base_text_lf.len());
let buffer_text = "one\nTWO\nthree\nfour\nfive\n";
let buffer = Buffer::new(
ReplicaId::LOCAL,
BufferId::new(1).unwrap(),
buffer_text.to_string(),
);
let buffer_snapshot = buffer.snapshot();
let diff = cx.new(|cx| BufferDiff::new(&buffer_snapshot, cx));
diff.update(cx, |diff, cx| {
diff.set_base_text(
Some(Arc::from(base_text_crlf)),
None,
buffer_snapshot.clone(),
cx,
)
})
.await
.ok();
cx.run_until_parked();
let snapshot = diff.update(cx, |diff, cx| diff.snapshot(cx));
snapshot.buffer_point_to_base_text_range(Point::new(0, 0), &buffer_snapshot);
snapshot.buffer_point_to_base_text_range(Point::new(1, 0), &buffer_snapshot);
}
}