{"thread":{"id":"54390","subject":"[PATCH] grep: handle deref_tag() returning NULL","startedAt":"2020-10-11T16:03:59Z","lastAt":"2020-10-11T16:03:59Z","messageCount":1,"participants":["René Scharfe"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"407304","messageId":"bd488081-390f-bad2-0fd3-c5c77ce57795@web.de","threadId":"54390","inReplyTo":null,"subject":"[PATCH] grep: handle deref_tag() returning NULL","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2020-10-11T16:03:28Z","receivedAt":"2020-10-11T16:03:59Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"deref_tag() can return NULL.  Exit gracefully in that case instead\nof blindly dereferencing the return value.\n\n.name shouldn't ever be NULL, but grep_object() handles that case\nexplicitly, so let's be defensive here as well and show the broken\nobject's ID if it happens to lack a name after all.\n\nSigned-off-by: René Scharfe <l.s.r@web.de>\n---\nPatch generated with --function-context for easier review.\n\n builtin/grep.c | 11 +++++++++++\n 1 file changed, 11 insertions(+)\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex c8037388c6..e58e57504c 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -658,31 +658,42 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,\n static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,\n \t\t\tconst struct object_array *list)\n {\n \tunsigned int i;\n \tint hit = 0;\n \tconst unsigned int nr = list->nr;\n\n \tfor (i = 0; i < nr; i++) {\n \t\tstruct object *real_obj;\n\n \t\tobj_read_lock();\n \t\treal_obj = deref_tag(opt->repo, list->objects[i].item,\n \t\t\t\t     NULL, 0);\n \t\tobj_read_unlock();\n\n+\t\tif (!real_obj) {\n+\t\t\tchar hex[GIT_MAX_HEXSZ + 1];\n+\t\t\tconst char *name = list->objects[i].name;\n+\n+\t\t\tif (!name) {\n+\t\t\t\toid_to_hex_r(hex, &list->objects[i].item->oid);\n+\t\t\t\tname = hex;\n+\t\t\t}\n+\t\t\tdie(_(\"invalid object '%s' given.\"), name);\n+\t\t}\n+\n \t\t/* load the gitmodules file for this rev */\n \t\tif (recurse_submodules) {\n \t\t\tsubmodule_free(opt->repo);\n \t\t\tobj_read_lock();\n \t\t\tgitmodules_config_oid(&real_obj->oid);\n \t\t\tobj_read_unlock();\n \t\t}\n \t\tif (grep_object(opt, pathspec, real_obj, list->objects[i].name,\n \t\t\t\tlist->objects[i].path)) {\n \t\t\thit = 1;\n \t\t\tif (opt->status_only)\n \t\t\t\tbreak;\n \t\t}\n \t}\n \treturn hit;\n }\n--\n2.28.0\n"}]}