From 662174d299a2221016a8756d35d485b576ebcec2 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 26 Aug 2014 06:23:36 -0400 Subject: [PATCH] log-tree: make add_name_decoration a public function The log-tree code keeps a "struct decoration" hash to show text decorations for each commit during log traversals. It makes this available to other files by providing global access to the hash. This can result in other code adding entries that do not conform to what log-tree expects. For example, the bisect code adds its own "dist" decorations to be shown. Originally the bisect code was correct, but when the name_decoration code grew a new field in eb3005e (commit.h: add 'type' to struct name_decoration, 2010-06-19), the bisect code was not updated. As a result, the log-tree code can access uninitialized memory and even segfault. We can fix this by making name_decoration's adding function public. If all callers use it, then any changes to struct initialization only need to happen in one place (and because the members come in as parameters, the compiler can notice a caller who does not supply enough information). As a bonus, this also means that the decoration hashes created by the bisect code will use less memory (previously we over-allocated space for the distance integer, but now we format it into a temporary buffer and copy it to the final flex-array). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- bisect.c | 7 ++++--- commit.h | 12 ++++++++++++ log-tree.c | 12 +----------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/bisect.c b/bisect.c index 37200b41f1..59f1aeebe3 100644 --- a/bisect.c +++ b/bisect.c @@ -216,11 +216,12 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n } qsort(array, cnt, sizeof(*array), compare_commit_dist); for (p = list, i = 0; i < cnt; i++) { - struct name_decoration *r = xmalloc(sizeof(*r) + 100); + char buf[100]; /* enough for dist=%d */ struct object *obj = &(array[i].commit->object); - sprintf(r->name, "dist=%d", array[i].distance); - r->next = add_decoration(&name_decoration, obj, r); + snprintf(buf, sizeof(buf), "dist=%d", array[i].distance); + add_name_decoration(DECORATION_NONE, buf, obj); + p->item = array[i].commit; p = p->next; } diff --git a/commit.h b/commit.h index a9f177ba48..06c06df3ec 100644 --- a/commit.h +++ b/commit.h @@ -34,6 +34,18 @@ struct name_decoration { char name[1]; }; +enum decoration_type { + DECORATION_NONE = 0, + DECORATION_REF_LOCAL, + DECORATION_REF_REMOTE, + DECORATION_REF_TAG, + DECORATION_REF_STASH, + DECORATION_REF_HEAD, + DECORATION_GRAFTED, +}; + +void add_name_decoration(enum decoration_type type, const char *name, struct object *obj); + struct commit *lookup_commit(const unsigned char *sha1); struct commit *lookup_commit_reference(const unsigned char *sha1); struct commit *lookup_commit_reference_gently(const unsigned char *sha1, diff --git a/log-tree.c b/log-tree.c index 08970bf46e..f7c6b035c9 100644 --- a/log-tree.c +++ b/log-tree.c @@ -14,16 +14,6 @@ struct decoration name_decoration = { "object names" }; -enum decoration_type { - DECORATION_NONE = 0, - DECORATION_REF_LOCAL, - DECORATION_REF_REMOTE, - DECORATION_REF_TAG, - DECORATION_REF_STASH, - DECORATION_REF_HEAD, - DECORATION_GRAFTED, -}; - static char decoration_colors[][COLOR_MAXLEN] = { GIT_COLOR_RESET, GIT_COLOR_BOLD_GREEN, /* REF_LOCAL */ @@ -84,7 +74,7 @@ int parse_decorate_color_config(const char *var, const int ofs, const char *valu #define decorate_get_color_opt(o, ix) \ decorate_get_color((o)->use_color, ix) -static void add_name_decoration(enum decoration_type type, const char *name, struct object *obj) +void add_name_decoration(enum decoration_type type, const char *name, struct object *obj) { int nlen = strlen(name); struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + nlen);