diff options
| author | Edward Thomson <ethomson@github.com> | 2016-06-29 09:35:56 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-06-29 09:35:56 -0400 |
| commit | d88e500133aefcf144fef7c4bcd6f073b2d50cf4 (patch) | |
| tree | 7e3916a8af105f709a7c3d1863641eda10001158 | |
| parent | 20302aa43738a972e0bd2e2ee6ae479208427b31 (diff) | |
| parent | 217667028918d1993d22508881e5df8fa2755e6a (diff) | |
| download | libgit2-d88e500133aefcf144fef7c4bcd6f073b2d50cf4.tar.gz | |
Merge pull request #3842 from pks-t/pks/double-free
blame: increment reference count for origin's commit
| -rw-r--r-- | src/blame_git.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/blame_git.c b/src/blame_git.c index 700207edb..96785c75b 100644 --- a/src/blame_git.c +++ b/src/blame_git.c @@ -37,25 +37,27 @@ static void origin_decref(git_blame__origin *o) static int make_origin(git_blame__origin **out, git_commit *commit, const char *path) { git_blame__origin *o; + git_object *blob; size_t path_len = strlen(path), alloc_len; int error = 0; + if ((error = git_object_lookup_bypath(&blob, (git_object*)commit, + path, GIT_OBJ_BLOB)) < 0) + return error; + GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*o), path_len); GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1); o = git__calloc(1, alloc_len); GITERR_CHECK_ALLOC(o); o->commit = commit; + o->blob = (git_blob *) blob; o->refcnt = 1; strcpy(o->path, path); - if (!(error = git_object_lookup_bypath((git_object**)&o->blob, (git_object*)commit, - path, GIT_OBJ_BLOB))) { - *out = o; - } else { - origin_decref(o); - } - return error; + *out = o; + + return 0; } /* Locate an existing origin or create a new one. */ @@ -529,8 +531,16 @@ static int pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt) goto finish; porigin = find_origin(blame, p, origin); - if (!porigin) + if (!porigin) { + /* + * We only have to decrement the parent's + * reference count when no porigin has + * been created, as otherwise the commit + * is assigned to the created object. + */ + git_commit_free(p); continue; + } if (porigin->blob && origin->blob && !git_oid_cmp(git_blob_id(porigin->blob), git_blob_id(origin->blob))) { pass_whole_blame(blame, origin, porigin); |
