Skip to content

Commit 7067793

Browse files
peffgitster
authored andcommitted
combine-diff: add combine_diff_path_new()
The combine_diff_path struct has variable size, since it embeds both the memory allocation for the path field as well as a variable-sized parent array. This makes allocating one a bit tricky. We have a helper to compute the required size, but it's up to individual sites to actually initialize all of the fields. Let's provide a constructor function to make that a little nicer. Besides being shorter, it also hides away tricky bits like the computation of the "path" pointer (which is right after the "parent" flex array). As a bonus, using the same constructor everywhere means that we'll consistently initialize all parts of the struct. A few code paths left the parent array unitialized. This didn't cause any bugs, but we'll be able to simplify some code in the next few patches knowing that the parent fields have all been zero'd. This also gets rid of some questionable uses of "int" to store buffer lengths. Though we do use them to allocate, I don't think there are any integer overflow vulnerabilities here (the allocation helper promotes them to size_t and checks arithmetic for overflow, and the actual memcpy of the bytes is done using the possibly-truncated "int" value). Sadly we can't use the FLEX_* macros to simplify the allocation here, because there are two variable-sized parts to the struct (and those macros only handle one). Nor can we get stop publicly declaring combine_diff_path_size(). This patch does not touch the code in path_appendnew() at all, which is not ready to be moved to our new constructor for a few reasons: - path_appendnew() has a memory-reuse optimization where it tries to reuse combine_diff_path structs rather than freeing and reallocating. - path_appendnew() does not create the struct from a single path string, but rather allocates and copies into the buffer from multiple sources. These can be addressed by some refactoring, but let's leave it as-is for now. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 949bb8f commit 7067793

File tree

3 files changed

+37
-37
lines changed

3 files changed

+37
-37
lines changed

combine-diff.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,13 @@ static struct combine_diff_path *intersect_paths(
4747

4848
if (!n) {
4949
for (i = 0; i < q->nr; i++) {
50-
int len;
51-
const char *path;
5250
if (diff_unmodified_pair(q->queue[i]))
5351
continue;
54-
path = q->queue[i]->two->path;
55-
len = strlen(path);
56-
p = xmalloc(combine_diff_path_size(num_parent, len));
57-
p->path = (char *) &(p->parent[num_parent]);
58-
memcpy(p->path, path, len);
59-
p->path[len] = 0;
60-
p->next = NULL;
61-
memset(p->parent, 0,
62-
sizeof(p->parent[0]) * num_parent);
63-
64-
oidcpy(&p->oid, &q->queue[i]->two->oid);
65-
p->mode = q->queue[i]->two->mode;
52+
p = combine_diff_path_new(q->queue[i]->two->path,
53+
strlen(q->queue[i]->two->path),
54+
q->queue[i]->two->mode,
55+
&q->queue[i]->two->oid,
56+
num_parent);
6657
oidcpy(&p->parent[n].oid, &q->queue[i]->one->oid);
6758
p->parent[n].mode = q->queue[i]->one->mode;
6859
p->parent[n].status = q->queue[i]->status;
@@ -1667,3 +1658,24 @@ void diff_tree_combined_merge(const struct commit *commit,
16671658
diff_tree_combined(&commit->object.oid, &parents, rev);
16681659
oid_array_clear(&parents);
16691660
}
1661+
1662+
struct combine_diff_path *combine_diff_path_new(const char *path,
1663+
size_t path_len,
1664+
unsigned int mode,
1665+
const struct object_id *oid,
1666+
size_t num_parents)
1667+
{
1668+
struct combine_diff_path *p;
1669+
1670+
p = xmalloc(combine_diff_path_size(num_parents, path_len));
1671+
p->path = (char *)&(p->parent[num_parents]);
1672+
memcpy(p->path, path, path_len);
1673+
p->path[path_len] = 0;
1674+
p->next = NULL;
1675+
p->mode = mode;
1676+
oidcpy(&p->oid, oid);
1677+
1678+
memset(p->parent, 0, sizeof(p->parent[0]) * num_parents);
1679+
1680+
return p;
1681+
}

diff-lib.c

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
153153
struct diff_filepair *pair;
154154
unsigned int wt_mode = 0;
155155
int num_compare_stages = 0;
156-
size_t path_len;
157156
struct stat st;
158157

159158
changed = check_removed(ce, &st);
@@ -167,18 +166,8 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
167166
wt_mode = 0;
168167
}
169168

170-
path_len = ce_namelen(ce);
171-
172-
dpath = xmalloc(combine_diff_path_size(5, path_len));
173-
dpath->path = (char *) &(dpath->parent[5]);
174-
175-
dpath->next = NULL;
176-
memcpy(dpath->path, ce->name, path_len);
177-
dpath->path[path_len] = '\0';
178-
oidclr(&dpath->oid, the_repository->hash_algo);
179-
dpath->mode = wt_mode;
180-
memset(&(dpath->parent[0]), 0,
181-
sizeof(struct combine_diff_parent)*5);
169+
dpath = combine_diff_path_new(ce->name, ce_namelen(ce),
170+
wt_mode, null_oid(), 5);
182171

183172
while (i < entries) {
184173
struct cache_entry *nce = istate->cache[i];
@@ -405,16 +394,10 @@ static int show_modified(struct rev_info *revs,
405394
if (revs->combine_merges && !cached &&
406395
(!oideq(oid, &old_entry->oid) || !oideq(&old_entry->oid, &new_entry->oid))) {
407396
struct combine_diff_path *p;
408-
int pathlen = ce_namelen(new_entry);
409-
410-
p = xmalloc(combine_diff_path_size(2, pathlen));
411-
p->path = (char *) &p->parent[2];
412-
p->next = NULL;
413-
memcpy(p->path, new_entry->name, pathlen);
414-
p->path[pathlen] = 0;
415-
p->mode = mode;
416-
oidclr(&p->oid, the_repository->hash_algo);
417-
memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));
397+
398+
p = combine_diff_path_new(new_entry->name,
399+
ce_namelen(new_entry),
400+
mode, null_oid(), 2);
418401
p->parent[0].status = DIFF_STATUS_MODIFIED;
419402
p->parent[0].mode = new_entry->ce_mode;
420403
oidcpy(&p->parent[0].oid, &new_entry->oid);

diff.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,11 @@ struct combine_diff_path {
486486
#define combine_diff_path_size(n, l) \
487487
st_add4(sizeof(struct combine_diff_path), (l), 1, \
488488
st_mult(sizeof(struct combine_diff_parent), (n)))
489+
struct combine_diff_path *combine_diff_path_new(const char *path,
490+
size_t path_len,
491+
unsigned int mode,
492+
const struct object_id *oid,
493+
size_t num_parents);
489494

490495
void show_combined_diff(struct combine_diff_path *elem, int num_parent,
491496
struct rev_info *);

0 commit comments

Comments
 (0)