When passed an empty list, objects_array_remove_duplicates() corrupts it
by changing the number of entries from 0 to 1.

The problem lies in the condition of its main loop:

	for (ref = 0; ref < array->nr - 1; ref++) {

The loop body manipulates the supplied object array.  In the case of an
empty array, it should not be doing anything at all.  But array->nr is an
unsigned quantity, so the code enters the loop, in particular increasing
array->nr.  Fix this by comparing (ref + 1 < array->nr) instead.

This bug can be triggered by git bundle --stdin:

	$ echo HEAD | git bundle create some.bundle --stdin’
	Segmentation fault (core dumped)

The list of commits to bundle appears to be empty because of another bug:
by the time the revision-walking machinery gets to look at it, standard
input has already been consumed by rev-list, so this function gets an
empty list of revisions.

After this patch, git bundle --stdin still does not work; it just doesn’t
segfault any more.

Reported-by: Joey Hess <joey@kitenet.net>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jonathan Nieder 2010-04-19 03:03:40 -05:00 коммит произвёл Junio C Hamano
Родитель f62e0a39b6
Коммит 97a20eea19
1 изменённых файлов: 2 добавлений и 2 удалений

Просмотреть файл

@ -252,10 +252,10 @@ void add_object_array_with_mode(struct object *obj, const char *name, struct obj
void object_array_remove_duplicates(struct object_array *array)
{
int ref, src, dst;
unsigned int ref, src, dst;
struct object_array_entry *objects = array->objects;
for (ref = 0; ref < array->nr - 1; ref++) {
for (ref = 0; ref + 1 < array->nr; ref++) {
for (src = ref + 1, dst = src;
src < array->nr;
src++) {