From be343b88c724491bcb945cafec9f95370eb1088f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 May 2017 18:56:55 +0100 Subject: [PATCH 1/4] worktrees: cleanup some memory leaks Be sure to clean up looked up references. Free buffers instead of merely clearing them. Use `git__free` instead of `free`. --- src/branch.c | 10 ++++++---- src/refs.c | 4 ++-- src/repository.c | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/branch.c b/src/branch.c index 7a83b83af..fe4955ad6 100644 --- a/src/branch.c +++ b/src/branch.c @@ -130,14 +130,16 @@ int git_branch_create_from_annotated( static int branch_equals(git_repository *repo, const char *path, void *payload) { git_reference *branch = (git_reference *) payload; - git_reference *head; - int equal; + git_reference *head = NULL; + int equal = 0; if (git_reference__read_head(&head, repo, path) < 0 || - git_reference_type(head) != GIT_REF_SYMBOLIC) - return 0; + git_reference_type(head) != GIT_REF_SYMBOLIC) + goto done; equal = !git__strcmp(head->target.symbolic, branch->name); + +done: git_reference_free(head); return equal; } diff --git a/src/refs.c b/src/refs.c index 31410b75f..632a5299c 100644 --- a/src/refs.c +++ b/src/refs.c @@ -277,8 +277,8 @@ int git_reference__read_head( } out: - free(name); - git_buf_clear(&reference); + git__free(name); + git_buf_free(&reference); return error; } diff --git a/src/repository.c b/src/repository.c index 707b7b7bd..f8d19eb35 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2132,7 +2132,8 @@ int git_repository_head_for_worktree(git_reference **out, git_repository *repo, out: if (error) git_reference_free(head); - git_buf_clear(&path); + + git_buf_free(&path); return error; } From 4dbcf0e673b1761e536b9a5f385a771287f06232 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 May 2017 19:34:04 +0100 Subject: [PATCH 2/4] remote: free the config snapshot This reverts commit 5552237 and frees the snapshot properly. --- src/remote.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/remote.c b/src/remote.c index d090fda61..bd8b3cfbc 100644 --- a/src/remote.c +++ b/src/remote.c @@ -192,7 +192,7 @@ static int canonicalize_url(git_buf *out, const char *in) static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch) { git_remote *remote; - git_config *config = NULL; + git_config *config_ro = NULL, *config_rw; git_buf canonical_url = GIT_BUF_INIT; git_buf var = GIT_BUF_INIT; int error = -1; @@ -200,7 +200,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n /* name is optional */ assert(out && repo && url); - if ((error = git_repository_config__weakptr(&config, repo)) < 0) + if ((error = git_repository_config_snapshot(&config_ro, repo)) < 0) return error; remote = git__calloc(1, sizeof(git_remote)); @@ -212,7 +212,8 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n (error = canonicalize_url(&canonical_url, url)) < 0) goto on_error; - remote->url = apply_insteadof(repo->_config, canonical_url.ptr, GIT_DIRECTION_FETCH); + remote->url = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH); + GITERR_CHECK_ALLOC(remote->url); if (name != NULL) { remote->name = git__strdup(name); @@ -221,7 +222,8 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n if ((error = git_buf_printf(&var, CONFIG_URL_FMT, name)) < 0) goto on_error; - if ((error = git_config_set_string(config, var.ptr, canonical_url.ptr)) < 0) + if ((error = git_repository_config__weakptr(&config_rw, repo)) < 0 || + (error = git_config_set_string(config_rw, var.ptr, canonical_url.ptr)) < 0) goto on_error; } @@ -233,10 +235,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n if (name && (error = write_add_refspec(repo, name, fetch, true)) < 0) goto on_error; - if ((error = git_repository_config_snapshot(&config, repo)) < 0) - goto on_error; - - if ((error = lookup_remote_prune_config(remote, config, name)) < 0) + if ((error = lookup_remote_prune_config(remote, config_ro, name)) < 0) goto on_error; /* Move the data over to where the matching functions can find them */ @@ -260,6 +259,7 @@ on_error: if (error) git_remote_free(remote); + git_config_free(config_ro); git_buf_free(&canonical_url); git_buf_free(&var); return error; From 34c131062412480abd87ab825c2cd6c1b691e5f5 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 May 2017 21:32:24 +0100 Subject: [PATCH 3/4] signature: free dup'd buffers on parse error --- src/signature.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/signature.c b/src/signature.c index e792a52f8..a56b8a299 100644 --- a/src/signature.c +++ b/src/signature.c @@ -228,8 +228,11 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, const char *time_start = email_end + 2; const char *time_end; - if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0) + if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0) { + git__free(sig->name); + git__free(sig->email); return signature_error("invalid Unix timestamp"); + } /* do we have a timezone? */ if (time_end + 1 < buffer_end) { From 1dc89aab24ef157dff033a86b5d6c429df61f48d Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 1 May 2017 21:34:21 +0100 Subject: [PATCH 4/4] object validation: free some memleaks --- src/odb_loose.c | 6 ++++++ tests/object/lookup.c | 1 + 2 files changed, 7 insertions(+) diff --git a/src/odb_loose.c b/src/odb_loose.c index e14af4fab..a97ac25eb 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -205,6 +205,11 @@ static int start_inflate(z_stream *s, git_buf *obj, void *out, size_t len) return inflate(s, 0); } +static void abort_inflate(z_stream *s) +{ + inflateEnd(s); +} + static int finish_inflate(z_stream *s) { int status = Z_OK; @@ -367,6 +372,7 @@ static int inflate_disk_obj(git_rawobj *out, git_buf *obj) (used = get_object_header(&hdr, head)) == 0 || !git_object_typeisloose(hdr.type)) { + abort_inflate(&zs); giterr_set(GITERR_ODB, "failed to inflate disk object"); return -1; } diff --git a/tests/object/lookup.c b/tests/object/lookup.c index 277e2e0c0..544f32bc4 100644 --- a/tests/object/lookup.c +++ b/tests/object/lookup.c @@ -116,6 +116,7 @@ void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void) cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJ_COMMIT)); cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1)); + git_object_free(object); git_buf_free(&oldpath); git_buf_free(&newpath); }