remote: make copy_ref() perform a deep copy
To ensure that copied refs can always be freed w/o causing a double-free, make copy_ref() perform a deep copy. Also have copy_ref() return NULL if asked to copy NULL to simplify things for the caller. Background: currently copy_ref() performs a shallow copy. This is fine for current callers who never free the result and/or only copy refs which contain NULL pointers. But copy_ref() is about to gain a new caller (guess_remote_head()) which copies refs where peer_ref is not NULL and the caller of guess_remote_head() will want to free the result. Signed-off-by: Jay Soffian <jaysoffian@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
6cb4e6cc0f
commit
7b3db095d5
18
remote.c
18
remote.c
@ -779,10 +779,18 @@ struct ref *alloc_ref(const char *name)
|
|||||||
|
|
||||||
static struct ref *copy_ref(const struct ref *ref)
|
static struct ref *copy_ref(const struct ref *ref)
|
||||||
{
|
{
|
||||||
struct ref *ret = xmalloc(sizeof(struct ref) + strlen(ref->name) + 1);
|
struct ref *cpy;
|
||||||
memcpy(ret, ref, sizeof(struct ref) + strlen(ref->name) + 1);
|
size_t len;
|
||||||
ret->next = NULL;
|
if (!ref)
|
||||||
return ret;
|
return NULL;
|
||||||
|
len = strlen(ref->name);
|
||||||
|
cpy = xmalloc(sizeof(struct ref) + len + 1);
|
||||||
|
memcpy(cpy, ref, sizeof(struct ref) + len + 1);
|
||||||
|
cpy->next = NULL;
|
||||||
|
cpy->symref = ref->symref ? xstrdup(ref->symref) : NULL;
|
||||||
|
cpy->remote_status = ref->remote_status ? xstrdup(ref->remote_status) : NULL;
|
||||||
|
cpy->peer_ref = copy_ref(ref->peer_ref);
|
||||||
|
return cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ref *copy_ref_list(const struct ref *ref)
|
struct ref *copy_ref_list(const struct ref *ref)
|
||||||
@ -801,6 +809,7 @@ static void free_ref(struct ref *ref)
|
|||||||
{
|
{
|
||||||
if (!ref)
|
if (!ref)
|
||||||
return;
|
return;
|
||||||
|
free_ref(ref->peer_ref);
|
||||||
free(ref->remote_status);
|
free(ref->remote_status);
|
||||||
free(ref->symref);
|
free(ref->symref);
|
||||||
free(ref);
|
free(ref);
|
||||||
@ -811,7 +820,6 @@ void free_refs(struct ref *ref)
|
|||||||
struct ref *next;
|
struct ref *next;
|
||||||
while (ref) {
|
while (ref) {
|
||||||
next = ref->next;
|
next = ref->next;
|
||||||
free(ref->peer_ref);
|
|
||||||
free_ref(ref);
|
free_ref(ref);
|
||||||
ref = next;
|
ref = next;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user