Skip to content

Commit 75a9549

Browse files
peffgitster
authored andcommitted
avoid segfaults on parse_object failure
Many call-sites of parse_object assume that they will get a non-NULL return value; this is not the case if we encounter an error while parsing the object. This patch adds a wrapper function around parse_object that handles dying automatically, and uses it anywhere we immediately try to access the return value as a non-NULL pointer (i.e., anywhere that we would currently segfault). This wrapper may also be useful in other places. The most obvious one is code like: o = parse_object(sha1); if (!o) die(...); However, these should not be mechanically converted to parse_object_or_die, as the die message is sometimes customized. Later patches can address these sites on a case-by-case basis. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7e20105 commit 75a9549

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

bundle.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,12 @@ int create_bundle(struct bundle_header *header, const char *path,
279279
if (buf.len > 0 && buf.buf[0] == '-') {
280280
write_or_die(bundle_fd, buf.buf, buf.len);
281281
if (!get_sha1_hex(buf.buf + 1, sha1)) {
282-
struct object *object = parse_object(sha1);
282+
struct object *object = parse_object_or_die(sha1, buf.buf);
283283
object->flags |= UNINTERESTING;
284284
add_pending_object(&revs, object, xstrdup(buf.buf));
285285
}
286286
} else if (!get_sha1_hex(buf.buf, sha1)) {
287-
struct object *object = parse_object(sha1);
287+
struct object *object = parse_object_or_die(sha1, buf.buf);
288288
object->flags |= SHOWN;
289289
}
290290
}
@@ -361,7 +361,7 @@ int create_bundle(struct bundle_header *header, const char *path,
361361
* end up triggering "empty bundle"
362362
* error.
363363
*/
364-
obj = parse_object(sha1);
364+
obj = parse_object_or_die(sha1, e->name);
365365
obj->flags |= SHOWN;
366366
add_pending_object(&revs, obj, e->name);
367367
}

object.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,16 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
185185
return obj;
186186
}
187187

188+
struct object *parse_object_or_die(const unsigned char *sha1,
189+
const char *name)
190+
{
191+
struct object *o = parse_object(sha1);
192+
if (o)
193+
return o;
194+
195+
die(_("unable to parse object: %s"), name ? name : sha1_to_hex(sha1));
196+
}
197+
188198
struct object *parse_object(const unsigned char *sha1)
189199
{
190200
unsigned long size;

object.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,20 @@ struct object *lookup_object(const unsigned char *sha1);
5454

5555
extern void *create_object(const unsigned char *sha1, int type, void *obj);
5656

57-
/** Returns the object, having parsed it to find out what it is. **/
57+
/*
58+
* Returns the object, having parsed it to find out what it is.
59+
*
60+
* Returns NULL if the object is missing or corrupt.
61+
*/
5862
struct object *parse_object(const unsigned char *sha1);
5963

64+
/*
65+
* Like parse_object, but will die() instead of returning NULL. If the
66+
* "name" parameter is not NULL, it is included in the error message
67+
* (otherwise, the sha1 hex is given).
68+
*/
69+
struct object *parse_object_or_die(const unsigned char *sha1, const char *name);
70+
6071
/* Given the result of read_sha1_file(), returns the object after
6172
* parsing it. eaten_p indicates if the object has a borrowed copy
6273
* of buffer and the caller should not free() it.

pack-refs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
4040

4141
fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
4242
if (is_tag_ref) {
43-
struct object *o = parse_object(sha1);
43+
struct object *o = parse_object_or_die(sha1, path);
4444
if (o->type == OBJ_TAG) {
4545
o = deref_tag(o, path, 0);
4646
if (o)

0 commit comments

Comments
 (0)