Merge branch 'hy/diff-lazy-fetch-with-break-fix' into jch

A prefetch call can be triggered to access a stale diff_queue entry
after diffcore-break breaks a filepair into two and freed the
original entry that is no longer used, leading to a segfault, which
has been corrected.

* hy/diff-lazy-fetch-with-break-fix:
  diffcore-break: prevent dangling pointer
This commit is contained in:
Junio C Hamano
2026-02-23 16:25:16 -08:00
2 changed files with 30 additions and 0 deletions

View File

@@ -222,6 +222,7 @@ void diffcore_break(struct repository *r, int break_score)
free(p); /* not diff_free_filepair(), we are
* reusing one and two here.
*/
q->queue[i] = NULL;
continue;
}
}

View File

@@ -132,6 +132,35 @@ test_expect_success 'diff with rename detection batches blobs' '
test_line_count = 1 done_lines
'
test_expect_success 'diff succeeds even if prefetch triggered by break-rewrites' '
test_when_finished "rm -rf server client trace" &&
test_create_repo server &&
echo xyz >server/foo &&
mkdir server/bar &&
test_seq -f "line %d" 1 100 >server/bar/baz &&
git -C server add -A &&
git -C server commit -m x &&
echo xyzz >server/foo &&
rm server/bar/baz &&
test_seq -f "line %d" 90 190 >server/bar/baz &&
git -C server add -A &&
git -C server commit -m x &&
test_config -C server uploadpack.allowfilter 1 &&
test_config -C server uploadpack.allowanysha1inwant 1 &&
git clone --filter=blob:limit=0 "file://$(pwd)/server" client &&
# Fetch bar/baz without fetching foo.
git -C client checkout HEAD~1 bar &&
# Ensure baz has diff
git -C client reset --hard HEAD &&
# break-rewrites detection in reset will trigger prefetch
git -C client reset HEAD~1
'
test_expect_success 'diff succeeds even if entries are removed from queue' '
test_when_finished "rm -rf server client trace" &&