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 <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Mar 17, 2013 at 04:22 UTC 75a95490474ab6e991cbbbd10d980498a9109648
4 files changed +26 -5
bundle.c
+3 -3
@@ -279,12 +279,12 @@ int create_bundle(struct bundle_header *header, const char *path,
279 if (buf.len > 0 && buf.buf[0] == '-') {
280 write_or_die(bundle_fd, buf.buf, buf.len);
281 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);
283 object->flags |= UNINTERESTING;
284 add_pending_object(&revs, object, xstrdup(buf.buf));
285 }
286 } 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);
288 object->flags |= SHOWN;
289 }
290 }
@@ -361,7 +361,7 @@ int create_bundle(struct bundle_header *header, const char *path,
361 * end up triggering "empty bundle"
362 * error.
363 */
364 - obj = parse_object(sha1);
364 + obj = parse_object_or_die(sha1, e->name);
365 obj->flags |= SHOWN;
366 add_pending_object(&revs, obj, e->name);
367 }
object.c
+10
@@ -185,6 +185,16 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
185 return obj;
186 }
187
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 +
198 struct object *parse_object(const unsigned char *sha1)
199 {
200 unsigned long size;
object.h
+12 -1
@@ -54,9 +54,20 @@ struct object *lookup_object(const unsigned char *sha1);
54
55 extern void *create_object(const unsigned char *sha1, int type, void *obj);
56
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 + */
62 struct object *parse_object(const unsigned char *sha1);
63
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 +
71 /* Given the result of read_sha1_file(), returns the object after
72 * parsing it. eaten_p indicates if the object has a borrowed copy
73 * of buffer and the caller should not free() it.
pack-refs.c
+1 -1
@@ -40,7 +40,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
40
41 fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
42 if (is_tag_ref) {
43 - struct object *o = parse_object(sha1);
43 + struct object *o = parse_object_or_die(sha1, path);
44 if (o->type == OBJ_TAG) {
45 o = deref_tag(o, path, 0);
46 if (o)