diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/refdb_fs.c | 4 | ||||
| -rw-r--r-- | src/refs.c | 15 | ||||
| -rw-r--r-- | src/refs.h | 9 |
3 files changed, 20 insertions, 8 deletions
diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 77b72dc2a..a721f9841 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -1502,7 +1502,7 @@ static int refdb_fs_backend__rename( const char *message) { refdb_fs_backend *backend = GIT_CONTAINER_OF(_backend, refdb_fs_backend, parent); - git_reference *old, *new; + git_reference *old, *new = NULL; git_filebuf file = GIT_FILEBUF_INIT; int error; @@ -1518,7 +1518,7 @@ static int refdb_fs_backend__rename( return error; } - new = git_reference__set_name(old, new_name); + new = git_reference__realloc(&old, new_name); if (!new) { git_reference_free(old); return -1; diff --git a/src/refs.c b/src/refs.c index 07784302b..29dd1bdeb 100644 --- a/src/refs.c +++ b/src/refs.c @@ -91,18 +91,23 @@ git_reference *git_reference__alloc( return ref; } -git_reference *git_reference__set_name( - git_reference *ref, const char *name) +git_reference *git_reference__realloc( + git_reference **ptr_to_ref, const char *name) { - size_t namelen = strlen(name); - size_t reflen; + size_t namelen, reflen; git_reference *rewrite = NULL; + assert(ptr_to_ref && name); + + namelen = strlen(name); + if (!GIT_ADD_SIZET_OVERFLOW(&reflen, sizeof(git_reference), namelen) && !GIT_ADD_SIZET_OVERFLOW(&reflen, reflen, 1) && - (rewrite = git__realloc(ref, reflen)) != NULL) + (rewrite = git__realloc(*ptr_to_ref, reflen)) != NULL) memcpy(rewrite->name, name, namelen + 1); + *ptr_to_ref = NULL; + return rewrite; } diff --git a/src/refs.h b/src/refs.h index 46df95eba..adc345a12 100644 --- a/src/refs.h +++ b/src/refs.h @@ -75,7 +75,14 @@ struct git_reference { char name[GIT_FLEX_ARRAY]; }; -git_reference *git_reference__set_name(git_reference *ref, const char *name); +/** + * Reallocate the reference with a new name + * + * Note that this is a dangerous operation, as on success, all existing + * pointers to the old reference will now be dangling. Only call this on objects + * you control, possibly using `git_reference_dup`. + */ +git_reference *git_reference__realloc(git_reference **ptr_to_ref, const char *name); int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int flags); int git_reference__update_terminal(git_repository *repo, const char *ref_name, const git_oid *oid, const git_signature *sig, const char *log_message); |
