diff options
author | Jonathan Nieder <jrnieder@gmail.com> | 2010-04-19 03:03:40 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2010-04-19 22:16:35 -0700 |
commit | 97a20eea199f490760cc25b1b7df28361f54e536 (patch) | |
tree | fb44adfef431d3a230420a11056b23b39b4d1769 /object.c | |
parent | f62e0a39b69c2752b92f01bb05a6676639f46a65 (diff) | |
download | git-97a20eea199f490760cc25b1b7df28361f54e536.tar.gz git-97a20eea199f490760cc25b1b7df28361f54e536.tar.xz |
fix "bundle --stdin" segfault
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>
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 4 |
1 files changed, 2 insertions, 2 deletions
@@ -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++) { |