fsck: move typename() printing to its own function

When an object has a problem, we mention its type. But we do so by feeding the result of typename() directly to fprintf(). This is potentially dangerous because typename() can return NULL for some type values (like OBJ_NONE). It's doubtful that this can be triggered in practice with the current code, so this is probably not fixing a bug. But it future-proofs us against modifications that make things like OBJ_NONE more likely (and gives future patches a central point to handle them). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jan 25, 2017 at 23:11 UTC 97ca7ca8ba3acbc7166fb7ff40819696ed20e8c6
1 file changed +20 -9
builtin/fsck.c
+20 -9
@@ -56,6 +56,17 @@ static const char *describe_object(struct object *obj)
56 return buf.buf;
57 }
58
59 +static const char *printable_type(struct object *obj)
60 +{
61 + const char *ret;
62 +
63 + ret = typename(obj->type);
64 + if (!ret)
65 + ret = "unknown";
66 +
67 + return ret;
68 +}
69 +
70 static int fsck_config(const char *var, const char *value, void *cb)
71 {
72 if (strcmp(var, "fsck.skiplist") == 0) {
@@ -83,7 +94,7 @@ static void objreport(struct object *obj, const char *msg_type,
94 const char *err)
95 {
96 fprintf(stderr, "%s in %s %s: %s\n",
86 - msg_type, typename(obj->type), describe_object(obj), err);
97 + msg_type, printable_type(obj), describe_object(obj), err);
98 }
99
100 static int objerror(struct object *obj, const char *err)
@@ -114,7 +125,7 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
125 if (!obj) {
126 /* ... these references to parent->fld are safe here */
127 printf("broken link from %7s %s\n",
117 - typename(parent->type), describe_object(parent));
128 + printable_type(parent), describe_object(parent));
129 printf("broken link from %7s %s\n",
130 (type == OBJ_ANY ? "unknown" : typename(type)), "unknown");
131 errors_found |= ERROR_REACHABLE;
@@ -131,9 +142,9 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
142 if (!(obj->flags & HAS_OBJ)) {
143 if (parent && !has_object_file(&obj->oid)) {
144 printf("broken link from %7s %s\n",
134 - typename(parent->type), describe_object(parent));
145 + printable_type(parent), describe_object(parent));
146 printf(" to %7s %s\n",
136 - typename(obj->type), describe_object(obj));
147 + printable_type(obj), describe_object(obj));
148 errors_found |= ERROR_REACHABLE;
149 }
150 return 1;
@@ -205,7 +216,7 @@ static void check_reachable_object(struct object *obj)
216 if (!(obj->flags & HAS_OBJ)) {
217 if (has_sha1_pack(obj->oid.hash))
218 return; /* it is in pack - forget about it */
208 - printf("missing %s %s\n", typename(obj->type),
219 + printf("missing %s %s\n", printable_type(obj),
220 describe_object(obj));
221 errors_found |= ERROR_REACHABLE;
222 return;
@@ -231,7 +242,7 @@ static void check_unreachable_object(struct object *obj)
242 * since this is something that is prunable.
243 */
244 if (show_unreachable) {
234 - printf("unreachable %s %s\n", typename(obj->type),
245 + printf("unreachable %s %s\n", printable_type(obj),
246 describe_object(obj));
247 return;
248 }
@@ -250,7 +261,7 @@ static void check_unreachable_object(struct object *obj)
261 */
262 if (!obj->used) {
263 if (show_dangling)
253 - printf("dangling %s %s\n", typename(obj->type),
264 + printf("dangling %s %s\n", printable_type(obj),
265 describe_object(obj));
266 if (write_lost_and_found) {
267 char *filename = git_pathdup("lost-found/%s/%s",
@@ -324,7 +335,7 @@ static int fsck_obj(struct object *obj)
335
336 if (verbose)
337 fprintf(stderr, "Checking %s %s\n",
327 - typename(obj->type), describe_object(obj));
338 + printable_type(obj), describe_object(obj));
339
340 if (fsck_walk(obj, NULL, &fsck_obj_options))
341 objerror(obj, "broken links");
@@ -350,7 +361,7 @@ static int fsck_obj(struct object *obj)
361 struct tag *tag = (struct tag *) obj;
362
363 if (show_tags && tag->tagged) {
353 - printf("tagged %s %s", typename(tag->tagged->type),
364 + printf("tagged %s %s", printable_type(tag->tagged),
365 describe_object(tag->tagged));
366 printf(" (%s) in %s\n", tag->tag,
367 describe_object(&tag->object));