summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6cb4e6c)
raw | patch | inline | side by side (parent: 6cb4e6c)
author | Jay Soffian <jaysoffian@gmail.com> | |
Fri, 27 Feb 2009 19:10:04 +0000 (14:10 -0500) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Fri, 27 Feb 2009 23:08:08 +0000 (15:08 -0800) |
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>
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>
remote.c | patch | blob | history |
diff --git a/remote.c b/remote.c
index aed760ee3aca4df344646db698b5bec5ec83ef8b..22203ea8e2d00f6f3cfe3c883256685df0a01359 100644 (file)
--- a/remote.c
+++ b/remote.c
static struct ref *copy_ref(const struct ref *ref)
{
- struct ref *ret = xmalloc(sizeof(struct ref) + strlen(ref->name) + 1);
- memcpy(ret, ref, sizeof(struct ref) + strlen(ref->name) + 1);
- ret->next = NULL;
- return ret;
+ struct ref *cpy;
+ size_t len;
+ if (!ref)
+ 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)
{
if (!ref)
return;
+ free_ref(ref->peer_ref);
free(ref->remote_status);
free(ref->symref);
free(ref);
struct ref *next;
while (ref) {
next = ref->next;
- free(ref->peer_ref);
free_ref(ref);
ref = next;
}