From: Nguyễn Thái Ngọc Duy Date: Mon, 24 Oct 2011 06:36:09 +0000 (+1100) Subject: tree-walk.c: do not leak internal structure in tree_entry_len() X-Git-Tag: v1.7.8.1~14^2~5 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0de1633783685e9fb1943551217cdda7edbd245b;p=git.git tree-walk.c: do not leak internal structure in tree_entry_len() tree_entry_len() does not simply take two random arguments and return a tree length. The two pointers must point to a tree item structure, or struct name_entry. Passing random pointers will return incorrect value. Force callers to pass struct name_entry instead of two pointers (with hope that they don't manually construct struct name_entry themselves) Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- diff --git a/builtin/grep.c b/builtin/grep.c index 7d0779f6c..2cd06126d 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -547,7 +547,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, int old_baselen = base->len; while (tree_entry(tree, &entry)) { - int te_len = tree_entry_len(entry.path, entry.sha1); + int te_len = tree_entry_len(&entry); if (match != 2) { match = tree_entry_interesting(&entry, base, tn_len, pathspec); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index ba3705d1d..b4f785555 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -979,7 +979,7 @@ static void add_pbase_object(struct tree_desc *tree, while (tree_entry(tree,&entry)) { if (S_ISGITLINK(entry.mode)) continue; - cmp = tree_entry_len(entry.path, entry.sha1) != cmplen ? 1 : + cmp = tree_entry_len(&entry) != cmplen ? 1 : memcmp(name, entry.path, cmplen); if (cmp > 0) continue; diff --git a/tree-diff.c b/tree-diff.c index b3cc2e475..678248448 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -21,8 +21,8 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, sha1 = tree_entry_extract(t1, &path1, &mode1); sha2 = tree_entry_extract(t2, &path2, &mode2); - pathlen1 = tree_entry_len(path1, sha1); - pathlen2 = tree_entry_len(path2, sha2); + pathlen1 = tree_entry_len(&t1->entry); + pathlen2 = tree_entry_len(&t2->entry); cmp = base_name_compare(path1, pathlen1, mode1, path2, pathlen2, mode2); if (cmp < 0) { show_entry(opt, "-", t1, base); @@ -85,7 +85,7 @@ static void show_entry(struct diff_options *opt, const char *prefix, unsigned mode; const char *path; const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); - int pathlen = tree_entry_len(path, sha1); + int pathlen = tree_entry_len(&desc->entry); int old_baselen = base->len; strbuf_add(base, path, pathlen); diff --git a/tree-walk.c b/tree-walk.c index 418107ec8..f5d19f9cc 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -116,7 +116,7 @@ void setup_traverse_info(struct traverse_info *info, const char *base) char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n) { - int len = tree_entry_len(n->path, n->sha1); + int len = tree_entry_len(n); int pathlen = info->pathlen; path[pathlen + len] = 0; @@ -126,7 +126,7 @@ char *make_traverse_path(char *path, const struct traverse_info *info, const str break; path[--pathlen] = '/'; n = &info->name; - len = tree_entry_len(n->path, n->sha1); + len = tree_entry_len(n); info = info->prev; pathlen -= len; } @@ -253,7 +253,7 @@ static void extended_entry_extract(struct tree_desc_x *t, * The caller wants "first" from this tree, or nothing. */ path = a->path; - len = tree_entry_len(a->path, a->sha1); + len = tree_entry_len(a); switch (check_entry_match(first, first_len, path, len)) { case -1: entry_clear(a); @@ -271,7 +271,7 @@ static void extended_entry_extract(struct tree_desc_x *t, while (probe.size) { entry_extract(&probe, a); path = a->path; - len = tree_entry_len(a->path, a->sha1); + len = tree_entry_len(a); switch (check_entry_match(first, first_len, path, len)) { case -1: entry_clear(a); @@ -362,7 +362,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) e = entry + i; if (!e->path) continue; - len = tree_entry_len(e->path, e->sha1); + len = tree_entry_len(e); if (!first) { first = e->path; first_len = len; @@ -381,7 +381,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) /* Cull the ones that are not the earliest */ if (!e->path) continue; - len = tree_entry_len(e->path, e->sha1); + len = tree_entry_len(e); if (name_compare(e->path, len, first, first_len)) entry_clear(e); } @@ -434,8 +434,8 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char int entrylen, cmp; sha1 = tree_entry_extract(t, &entry, mode); + entrylen = tree_entry_len(&t->entry); update_tree_entry(t); - entrylen = tree_entry_len(entry, sha1); if (entrylen > namelen) continue; cmp = memcmp(name, entry, entrylen); @@ -596,7 +596,7 @@ int tree_entry_interesting(const struct name_entry *entry, ps->max_depth); } - pathlen = tree_entry_len(entry->path, entry->sha1); + pathlen = tree_entry_len(entry); for (i = ps->nr - 1; i >= 0; i--) { const struct pathspec_item *item = ps->items+i; diff --git a/tree-walk.h b/tree-walk.h index 0089581e1..884d01ac3 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -20,9 +20,9 @@ static inline const unsigned char *tree_entry_extract(struct tree_desc *desc, co return desc->entry.sha1; } -static inline int tree_entry_len(const char *name, const unsigned char *sha1) +static inline int tree_entry_len(const struct name_entry *ne) { - return (const char *)sha1 - name - 1; + return (const char *)ne->sha1 - ne->path - 1; } void update_tree_entry(struct tree_desc *); @@ -58,7 +58,7 @@ extern void setup_traverse_info(struct traverse_info *info, const char *base); static inline int traverse_path_len(const struct traverse_info *info, const struct name_entry *n) { - return info->pathlen + tree_entry_len(n->path, n->sha1); + return info->pathlen + tree_entry_len(n); } extern int tree_entry_interesting(const struct name_entry *, struct strbuf *, int, const struct pathspec *ps); diff --git a/tree.c b/tree.c index 698ecf7af..e62219803 100644 --- a/tree.c +++ b/tree.c @@ -99,7 +99,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base, else continue; - len = tree_entry_len(entry.path, entry.sha1); + len = tree_entry_len(&entry); strbuf_add(base, entry.path, len); strbuf_addch(base, '/'); retval = read_tree_1(lookup_tree(sha1), diff --git a/unpack-trees.c b/unpack-trees.c index 8282f5e5f..7c9ecf665 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -446,7 +446,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask, newinfo.prev = info; newinfo.pathspec = info->pathspec; newinfo.name = *p; - newinfo.pathlen += tree_entry_len(p->path, p->sha1) + 1; + newinfo.pathlen += tree_entry_len(p) + 1; newinfo.conflicts |= df_conflicts; for (i = 0; i < n; i++, dirmask >>= 1) { @@ -495,7 +495,7 @@ static int do_compare_entry(const struct cache_entry *ce, const struct traverse_ ce_len -= pathlen; ce_name = ce->name + pathlen; - len = tree_entry_len(n->path, n->sha1); + len = tree_entry_len(n); return df_name_compare(ce_name, ce_len, S_IFREG, n->path, len, n->mode); } @@ -626,7 +626,7 @@ static int find_cache_pos(struct traverse_info *info, struct unpack_trees_options *o = info->data; struct index_state *index = o->src_index; int pfxlen = info->pathlen; - int p_len = tree_entry_len(p->path, p->sha1); + int p_len = tree_entry_len(p); for (pos = o->cache_bottom; pos < index->cache_nr; pos++) { struct cache_entry *ce = index->cache[pos];