Skip to content

Commit aa1d4b4

Browse files
committed
Merge branch 'jk/fetch-prefetch-double-free-fix'
Double-free fix. * jk/fetch-prefetch-double-free-fix: refspec: store raw refspecs inside refspec_item refspec: drop separate raw_nr count fetch: adjust refspec->raw_nr when filtering prefetch refspecs
2 parents 0b9b6cd + fe17a25 commit aa1d4b4

File tree

6 files changed

+30
-38
lines changed

6 files changed

+30
-38
lines changed

builtin/fetch.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,14 +454,10 @@ static void filter_prefetch_refspec(struct refspec *rs)
454454
ref_namespace[NAMESPACE_TAGS].ref))) {
455455
int j;
456456

457-
free(rs->items[i].src);
458-
free(rs->items[i].dst);
459-
free(rs->raw[i]);
457+
refspec_item_clear(&rs->items[i]);
460458

461-
for (j = i + 1; j < rs->nr; j++) {
459+
for (j = i + 1; j < rs->nr; j++)
462460
rs->items[j - 1] = rs->items[j];
463-
rs->raw[j - 1] = rs->raw[j];
464-
}
465461
rs->nr--;
466462
i--;
467463
continue;

builtin/remote.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
377377
for (i = 0; i < states->remote->fetch.nr; i++)
378378
if (get_fetch_map(remote_refs, &states->remote->fetch.items[i], &tail, 1))
379379
die(_("Could not get fetch map for refspec %s"),
380-
states->remote->fetch.raw[i]);
380+
states->remote->fetch.items[i].raw);
381381

382382
for (ref = fetch_map; ref; ref = ref->next) {
383383
if (omit_name_by_refspec(ref->name, &states->remote->fetch))
@@ -633,12 +633,12 @@ static int migrate_file(struct remote *remote)
633633
git_config_set_multivar(buf.buf, remote->url.v[i], "^$", 0);
634634
strbuf_reset(&buf);
635635
strbuf_addf(&buf, "remote.%s.push", remote->name);
636-
for (i = 0; i < remote->push.raw_nr; i++)
637-
git_config_set_multivar(buf.buf, remote->push.raw[i], "^$", 0);
636+
for (i = 0; i < remote->push.nr; i++)
637+
git_config_set_multivar(buf.buf, remote->push.items[i].raw, "^$", 0);
638638
strbuf_reset(&buf);
639639
strbuf_addf(&buf, "remote.%s.fetch", remote->name);
640-
for (i = 0; i < remote->fetch.raw_nr; i++)
641-
git_config_set_multivar(buf.buf, remote->fetch.raw[i], "^$", 0);
640+
for (i = 0; i < remote->fetch.nr; i++)
641+
git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0);
642642
if (remote->origin == REMOTE_REMOTES)
643643
unlink_or_warn(git_path("remotes/%s", remote->name));
644644
else if (remote->origin == REMOTE_BRANCHES)
@@ -759,16 +759,16 @@ static int mv(int argc, const char **argv, const char *prefix)
759759
goto out;
760760
}
761761

762-
if (oldremote->fetch.raw_nr) {
762+
if (oldremote->fetch.nr) {
763763
strbuf_reset(&buf);
764764
strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
765765
git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
766766
strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
767-
for (i = 0; i < oldremote->fetch.raw_nr; i++) {
767+
for (i = 0; i < oldremote->fetch.nr; i++) {
768768
char *ptr;
769769

770770
strbuf_reset(&buf2);
771-
strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
771+
strbuf_addstr(&buf2, oldremote->fetch.items[i].raw);
772772
ptr = strstr(buf2.buf, old_remote_context.buf);
773773
if (ptr) {
774774
refspec_updated = 1;

refspec.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet
153153
int refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
154154
{
155155
memset(item, 0, sizeof(*item));
156+
item->raw = xstrdup(refspec);
156157
return parse_refspec(item, refspec, fetch);
157158
}
158159

@@ -167,6 +168,7 @@ void refspec_item_clear(struct refspec_item *item)
167168
{
168169
FREE_AND_NULL(item->src);
169170
FREE_AND_NULL(item->dst);
171+
FREE_AND_NULL(item->raw);
170172
item->force = 0;
171173
item->pattern = 0;
172174
item->matching = 0;
@@ -179,31 +181,29 @@ void refspec_init(struct refspec *rs, int fetch)
179181
rs->fetch = fetch;
180182
}
181183

182-
static void refspec_append_nodup(struct refspec *rs, char *refspec)
184+
void refspec_append(struct refspec *rs, const char *refspec)
183185
{
184186
struct refspec_item item;
185187

186188
refspec_item_init_or_die(&item, refspec, rs->fetch);
187189

188190
ALLOC_GROW(rs->items, rs->nr + 1, rs->alloc);
189-
rs->items[rs->nr++] = item;
191+
rs->items[rs->nr] = item;
190192

191-
ALLOC_GROW(rs->raw, rs->raw_nr + 1, rs->raw_alloc);
192-
rs->raw[rs->raw_nr++] = refspec;
193-
}
194-
195-
void refspec_append(struct refspec *rs, const char *refspec)
196-
{
197-
refspec_append_nodup(rs, xstrdup(refspec));
193+
rs->nr++;
198194
}
199195

200196
void refspec_appendf(struct refspec *rs, const char *fmt, ...)
201197
{
202198
va_list ap;
199+
char *buf;
203200

204201
va_start(ap, fmt);
205-
refspec_append_nodup(rs, xstrvfmt(fmt, ap));
202+
buf = xstrvfmt(fmt, ap);
206203
va_end(ap);
204+
205+
refspec_append(rs, buf);
206+
free(buf);
207207
}
208208

209209
void refspec_appendn(struct refspec *rs, const char **refspecs, int nr)
@@ -224,12 +224,6 @@ void refspec_clear(struct refspec *rs)
224224
rs->alloc = 0;
225225
rs->nr = 0;
226226

227-
for (i = 0; i < rs->raw_nr; i++)
228-
free(rs->raw[i]);
229-
FREE_AND_NULL(rs->raw);
230-
rs->raw_alloc = 0;
231-
rs->raw_nr = 0;
232-
233227
rs->fetch = 0;
234228
}
235229

refspec.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ struct refspec_item {
2626

2727
char *src;
2828
char *dst;
29+
30+
char *raw;
2931
};
3032

3133
#define REFSPEC_FETCH 1
@@ -43,10 +45,6 @@ struct refspec {
4345
int alloc;
4446
int nr;
4547

46-
char **raw;
47-
int raw_alloc;
48-
int raw_nr;
49-
5048
int fetch;
5149
};
5250

submodule.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,8 +1174,8 @@ static int push_submodule(const char *path,
11741174
if (remote->origin != REMOTE_UNCONFIGURED) {
11751175
int i;
11761176
strvec_push(&cp.args, remote->name);
1177-
for (i = 0; i < rs->raw_nr; i++)
1178-
strvec_push(&cp.args, rs->raw[i]);
1177+
for (i = 0; i < rs->nr; i++)
1178+
strvec_push(&cp.args, rs->items[i].raw);
11791179
}
11801180

11811181
prepare_submodule_repo_env(&cp.env);
@@ -1209,8 +1209,8 @@ static void submodule_push_check(const char *path, const char *head,
12091209
strvec_push(&cp.args, head);
12101210
strvec_push(&cp.args, remote->name);
12111211

1212-
for (i = 0; i < rs->raw_nr; i++)
1213-
strvec_push(&cp.args, rs->raw[i]);
1212+
for (i = 0; i < rs->nr; i++)
1213+
strvec_push(&cp.args, rs->items[i].raw);
12141214

12151215
prepare_submodule_repo_env(&cp.env);
12161216
cp.git_cmd = 1;

t/t5582-fetch-negative-refspec.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,8 @@ test_expect_success '--prefetch succeeds when refspec becomes empty' '
283283
git -C one fetch --prefetch
284284
'
285285

286+
test_expect_success '--prefetch succeeds with empty command line refspec' '
287+
git -C one fetch --prefetch origin +refs/tags/extra
288+
'
289+
286290
test_done

0 commit comments

Comments
 (0)