Skip to content

Commit ea82b2a

Browse files
bk2204gitster
authored andcommitted
tree-walk: store object_id in a separate member
When parsing a tree, we read the object ID directly out of the tree buffer. This is normally fine, but such an object ID cannot be used with oidcpy, which copies GIT_MAX_RAWSZ bytes, because if we are using SHA-1, there may not be that many bytes to copy. Instead, store the object ID in a separate struct member. Since we can no longer efficiently compute the path length, store that information as well in struct name_entry. Ensure we only copy the object ID into the new buffer if the path length is nonzero, as some callers will pass us an empty path with no object ID following it, and we will not want to read past the end of the buffer. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent f55ac43 commit ea82b2a

19 files changed

+60
-54
lines changed

builtin/grep.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -566,26 +566,26 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
566566
strbuf_add(base, entry.path, te_len);
567567

568568
if (S_ISREG(entry.mode)) {
569-
hit |= grep_oid(opt, entry.oid, base->buf, tn_len,
569+
hit |= grep_oid(opt, &entry.oid, base->buf, tn_len,
570570
check_attr ? base->buf + tn_len : NULL);
571571
} else if (S_ISDIR(entry.mode)) {
572572
enum object_type type;
573573
struct tree_desc sub;
574574
void *data;
575575
unsigned long size;
576576

577-
data = lock_and_read_oid_file(entry.oid, &type, &size);
577+
data = lock_and_read_oid_file(&entry.oid, &type, &size);
578578
if (!data)
579579
die(_("unable to read tree (%s)"),
580-
oid_to_hex(entry.oid));
580+
oid_to_hex(&entry.oid));
581581

582582
strbuf_addch(base, '/');
583583
init_tree_desc(&sub, data, size);
584584
hit |= grep_tree(opt, pathspec, &sub, base, tn_len,
585585
check_attr, repo);
586586
free(data);
587587
} else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
588-
hit |= grep_submodule(opt, repo, pathspec, entry.oid,
588+
hit |= grep_submodule(opt, repo, pathspec, &entry.oid,
589589
base->buf, base->buf + tn_len);
590590
}
591591

builtin/merge-tree.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,15 @@ static void show_result(void)
154154
/* An empty entry never compares same, not even to another empty entry */
155155
static int same_entry(struct name_entry *a, struct name_entry *b)
156156
{
157-
return a->oid &&
158-
b->oid &&
159-
oideq(a->oid, b->oid) &&
157+
return !is_null_oid(&a->oid) &&
158+
!is_null_oid(&b->oid) &&
159+
oideq(&a->oid, &b->oid) &&
160160
a->mode == b->mode;
161161
}
162162

163163
static int both_empty(struct name_entry *a, struct name_entry *b)
164164
{
165-
return !(a->oid || b->oid);
165+
return is_null_oid(&a->oid) && is_null_oid(&b->oid);
166166
}
167167

168168
static struct merge_list *create_entry(unsigned stage, unsigned mode, const struct object_id *oid, const char *path)
@@ -178,7 +178,7 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const stru
178178

179179
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
180180
{
181-
char *path = xmallocz(traverse_path_len(info, n));
181+
char *path = xmallocz(traverse_path_len(info, n) + the_hash_algo->rawsz);
182182
return make_traverse_path(path, info, n);
183183
}
184184

@@ -192,8 +192,8 @@ static void resolve(const struct traverse_info *info, struct name_entry *ours, s
192192
return;
193193

194194
path = traverse_path(info, result);
195-
orig = create_entry(2, ours->mode, ours->oid, path);
196-
final = create_entry(0, result->mode, result->oid, path);
195+
orig = create_entry(2, ours->mode, &ours->oid, path);
196+
final = create_entry(0, result->mode, &result->oid, path);
197197

198198
final->link = orig;
199199

@@ -217,7 +217,7 @@ static void unresolved_directory(const struct traverse_info *info,
217217

218218
newbase = traverse_path(info, p);
219219

220-
#define ENTRY_OID(e) (((e)->mode && S_ISDIR((e)->mode)) ? (e)->oid : NULL)
220+
#define ENTRY_OID(e) (((e)->mode && S_ISDIR((e)->mode)) ? &(e)->oid : NULL)
221221
buf0 = fill_tree_descriptor(t + 0, ENTRY_OID(n + 0));
222222
buf1 = fill_tree_descriptor(t + 1, ENTRY_OID(n + 1));
223223
buf2 = fill_tree_descriptor(t + 2, ENTRY_OID(n + 2));
@@ -243,7 +243,7 @@ static struct merge_list *link_entry(unsigned stage, const struct traverse_info
243243
path = entry->path;
244244
else
245245
path = traverse_path(info, n);
246-
link = create_entry(stage, n->mode, n->oid, path);
246+
link = create_entry(stage, n->mode, &n->oid, path);
247247
link->link = entry;
248248
return link;
249249
}
@@ -318,7 +318,7 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s
318318
}
319319

320320
if (same_entry(entry+0, entry+1)) {
321-
if (entry[2].oid && !S_ISDIR(entry[2].mode)) {
321+
if (!is_null_oid(&entry[2].oid) && !S_ISDIR(entry[2].mode)) {
322322
/* We did not touch, they modified -- take theirs */
323323
resolve(info, entry+1, entry+2);
324324
return mask;

builtin/pack-objects.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,7 @@ static void add_pbase_object(struct tree_desc *tree,
13341334
if (cmp < 0)
13351335
return;
13361336
if (name[cmplen] != '/') {
1337-
add_object_entry(entry.oid,
1337+
add_object_entry(&entry.oid,
13381338
object_type(entry.mode),
13391339
fullname, 1);
13401340
return;
@@ -1345,7 +1345,7 @@ static void add_pbase_object(struct tree_desc *tree,
13451345
const char *down = name+cmplen+1;
13461346
int downlen = name_cmp_len(down);
13471347

1348-
tree = pbase_tree_get(entry.oid);
1348+
tree = pbase_tree_get(&entry.oid);
13491349
if (!tree)
13501350
return;
13511351
init_tree_desc(&sub, tree->tree_data, tree->tree_size);

builtin/reflog.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ static int tree_is_complete(const struct object_id *oid)
9494
init_tree_desc(&desc, tree->buffer, tree->size);
9595
complete = 1;
9696
while (tree_entry(&desc, &entry)) {
97-
if (!has_sha1_file(entry.oid->hash) ||
98-
(S_ISDIR(entry.mode) && !tree_is_complete(entry.oid))) {
97+
if (!has_sha1_file(entry.oid.hash) ||
98+
(S_ISDIR(entry.mode) && !tree_is_complete(&entry.oid))) {
9999
tree->object.flags |= INCOMPLETE;
100100
complete = 0;
101101
}

cache-tree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ static void prime_cache_tree_rec(struct repository *r,
675675
cnt++;
676676
else {
677677
struct cache_tree_sub *sub;
678-
struct tree *subtree = lookup_tree(r, entry.oid);
678+
struct tree *subtree = lookup_tree(r, &entry.oid);
679679
if (!subtree->object.parsed)
680680
parse_tree(subtree);
681681
sub = cache_tree_sub(it, entry.path);
@@ -724,7 +724,7 @@ int cache_tree_matches_traversal(struct cache_tree *root,
724724

725725
it = find_cache_tree_from_traversal(root, info);
726726
it = cache_tree_find(it, ent->path);
727-
if (it && it->entry_count > 0 && oideq(ent->oid, &it->oid))
727+
if (it && it->entry_count > 0 && oideq(&ent->oid, &it->oid))
728728
return it->entry_count;
729729
return 0;
730730
}

delta-islands.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ void resolve_tree_islands(struct repository *r,
296296
if (S_ISGITLINK(entry.mode))
297297
continue;
298298

299-
obj = lookup_object(r, entry.oid->hash);
299+
obj = lookup_object(r, entry.oid.hash);
300300
if (!obj)
301301
continue;
302302

fsck.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,14 +410,14 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
410410
continue;
411411

412412
if (S_ISDIR(entry.mode)) {
413-
obj = (struct object *)lookup_tree(the_repository, entry.oid);
413+
obj = (struct object *)lookup_tree(the_repository, &entry.oid);
414414
if (name && obj)
415415
put_object_name(options, obj, "%s%s/", name,
416416
entry.path);
417417
result = options->walk(obj, OBJ_TREE, data, options);
418418
}
419419
else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) {
420-
obj = (struct object *)lookup_blob(the_repository, entry.oid);
420+
obj = (struct object *)lookup_blob(the_repository, &entry.oid);
421421
if (name && obj)
422422
put_object_name(options, obj, "%s%s", name,
423423
entry.path);

http-push.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,11 +1311,11 @@ static struct object_list **process_tree(struct tree *tree,
13111311
while (tree_entry(&desc, &entry))
13121312
switch (object_type(entry.mode)) {
13131313
case OBJ_TREE:
1314-
p = process_tree(lookup_tree(the_repository, entry.oid),
1314+
p = process_tree(lookup_tree(the_repository, &entry.oid),
13151315
p);
13161316
break;
13171317
case OBJ_BLOB:
1318-
p = process_blob(lookup_blob(the_repository, entry.oid),
1318+
p = process_blob(lookup_blob(the_repository, &entry.oid),
13191319
p);
13201320
break;
13211321
default:

list-objects.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ static void process_tree_contents(struct traversal_context *ctx,
123123
}
124124

125125
if (S_ISDIR(entry.mode)) {
126-
struct tree *t = lookup_tree(ctx->revs->repo, entry.oid);
126+
struct tree *t = lookup_tree(ctx->revs->repo, &entry.oid);
127127
t->object.flags |= NOT_USER_GIVEN;
128128
process_tree(ctx, t, base, entry.path);
129129
}
130130
else if (S_ISGITLINK(entry.mode))
131-
process_gitlink(ctx, entry.oid->hash,
131+
process_gitlink(ctx, entry.oid.hash,
132132
base, entry.path);
133133
else {
134-
struct blob *b = lookup_blob(ctx->revs->repo, entry.oid);
134+
struct blob *b = lookup_blob(ctx->revs->repo, &entry.oid);
135135
b->object.flags |= NOT_USER_GIVEN;
136136
process_blob(ctx, b, base, entry.path);
137137
}

match-trees.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static int score_trees(const struct object_id *hash1, const struct object_id *ha
106106
update_tree_entry(&two);
107107
} else {
108108
/* path appears in both */
109-
if (!oideq(one.entry.oid, two.entry.oid)) {
109+
if (!oideq(&one.entry.oid, &two.entry.oid)) {
110110
/* they are different */
111111
score += score_differs(one.entry.mode,
112112
two.entry.mode,

0 commit comments

Comments
 (0)