mirror of
https://github.com/git/git
synced 2024-08-27 19:49:21 +00:00
diff: check for merge bases before assigning sym->base
In symdiff_prepare(), we iterate over the set of parsed objects to pick out any symmetric differences, including the left, right, and base elements. We assign the results into pointers in a "struct symdiff", and then complain if we didn't find a base, like so: sym->left = rev->pending.objects[lpos].name; sym->right = rev->pending.objects[rpos].name; sym->base = rev->pending.objects[basepos].name; if (basecount == 0) die(_("%s...%s: no merge base"), sym->left, sym->right); But the least lines are backwards. If basecount is 0, then basepos will be -1, and we will access memory outside of the pending array. This isn't usually that big a deal, since we don't do anything besides a single pointer-sized read before exiting anyway, but it does violate the C standard, and of course memory-checking tools like ASan complain. Let's put the basecount check first. Note that we haveto split it from the other assignments, since the die() relies on sym->left and sym->right having been assigned (this isn't strictly necessary, but is easier to read than dereferencing the pending array again). Reported-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
b7e10b2ca2
commit
5f46e610cb
|
@ -355,9 +355,9 @@ static void symdiff_prepare(struct rev_info *rev, struct symdiff *sym)
|
||||||
|
|
||||||
sym->left = rev->pending.objects[lpos].name;
|
sym->left = rev->pending.objects[lpos].name;
|
||||||
sym->right = rev->pending.objects[rpos].name;
|
sym->right = rev->pending.objects[rpos].name;
|
||||||
sym->base = rev->pending.objects[basepos].name;
|
|
||||||
if (basecount == 0)
|
if (basecount == 0)
|
||||||
die(_("%s...%s: no merge base"), sym->left, sym->right);
|
die(_("%s...%s: no merge base"), sym->left, sym->right);
|
||||||
|
sym->base = rev->pending.objects[basepos].name;
|
||||||
bitmap_unset(map, basepos); /* unmark the base we want */
|
bitmap_unset(map, basepos); /* unmark the base we want */
|
||||||
sym->warn = basecount > 1;
|
sym->warn = basecount > 1;
|
||||||
sym->skip = map;
|
sym->skip = map;
|
||||||
|
|
Loading…
Reference in a new issue