From 0f8a1a91db0825daa0d25549f15791bcee0f9a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Sun, 24 Mar 2024 09:09:36 +0100 Subject: [PATCH] Fix leaks in fetch_refspecs and push_refspecs Also use git_strarray_dispose instead of deprecated git_strarray_free. And fix a couple of build warnings in git_commit_create. (cherry picked from commit c7c65cf12547eeadb46cfb30531285e1afcbd708) --- pygit2/decl/strarray.h | 2 +- pygit2/remotes.py | 16 +++------------- pygit2/utils.py | 15 ++++++++++----- src/repository.c | 10 ++++------ 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/pygit2/decl/strarray.h b/pygit2/decl/strarray.h index a9b249f..fdbf2aa 100644 --- a/pygit2/decl/strarray.h +++ b/pygit2/decl/strarray.h @@ -3,4 +3,4 @@ typedef struct git_strarray { size_t count; } git_strarray; -void git_strarray_free(git_strarray *array); +void git_strarray_dispose(git_strarray *array); diff --git a/pygit2/remotes.py b/pygit2/remotes.py index 3c4748c..37a6ca3 100644 --- a/pygit2/remotes.py +++ b/pygit2/remotes.py @@ -222,7 +222,6 @@ class Remote: specs = ffi.new('git_strarray *') err = C.git_remote_get_fetch_refspecs(specs, self._remote) check_error(err) - return strarray_to_strings(specs) @property @@ -232,7 +231,6 @@ class Remote: specs = ffi.new('git_strarray *') err = C.git_remote_get_push_refspecs(specs, self._remote) check_error(err) - return strarray_to_strings(specs) def push(self, specs, callbacks=None, proxy=None): @@ -294,14 +292,12 @@ class RemoteCollection: def __len__(self): names = ffi.new('git_strarray *') - try: err = C.git_remote_list(names, self._repo._repo) check_error(err) - return names.count finally: - C.git_strarray_free(names) + C.git_strarray_dispose(names) def __iter__(self): cremote = ffi.new('git_remote **') @@ -323,15 +319,13 @@ class RemoteCollection: def _ffi_names(self): names = ffi.new('git_strarray *') - try: err = C.git_remote_list(names, self._repo._repo) check_error(err) - for i in range(names.count): yield names.strings[i] finally: - C.git_strarray_free(names) + C.git_strarray_dispose(names) def names(self): """An iterator over the names of the available remotes.""" @@ -386,11 +380,7 @@ class RemoteCollection: problems = ffi.new('git_strarray *') err = C.git_remote_rename(problems, self._repo._repo, to_bytes(name), to_bytes(new_name)) check_error(err) - - ret = strarray_to_strings(problems) - C.git_strarray_free(problems) - - return ret + return strarray_to_strings(problems) def delete(self, name): """Remove a remote from the configuration diff --git a/pygit2/utils.py b/pygit2/utils.py index 638c199..f4e3fc8 100644 --- a/pygit2/utils.py +++ b/pygit2/utils.py @@ -26,7 +26,7 @@ import os # Import from pygit2 -from .ffi import ffi +from .ffi import ffi, C def maybe_string(ptr): @@ -73,11 +73,16 @@ def ptr_to_bytes(ptr_cdata): def strarray_to_strings(arr): - l = [None] * arr.count - for i in range(arr.count): - l[i] = ffi.string(arr.strings[i]).decode('utf-8') + """ + Return a list of strings from a git_strarray pointer. - return l + Free the strings contained in the git_strarry, this means it won't be usable after + calling this function. + """ + try: + return [ffi.string(arr.strings[i]).decode('utf-8') for i in range(arr.count)] + finally: + C.git_strarray_dispose(arr) class StrArray: diff --git a/src/repository.c b/src/repository.c index cf7597c..1f6db24 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1069,8 +1069,7 @@ Repository_create_commit(Repository *self, PyObject *args) err = git_commit_create(&oid, self->repo, update_ref, py_author->signature, py_committer->signature, - encoding, message, tree, parent_count, - (const git_commit**)parents); + encoding, message, tree, parent_count, parents); if (err < 0) { Error_set(err); goto out; @@ -1152,8 +1151,7 @@ Repository_create_commit_string(Repository *self, PyObject *args) err = git_commit_create_buffer(&buf, self->repo, py_author->signature, py_committer->signature, - encoding, message, tree, parent_count, - (const git_commit**)parents); + encoding, message, tree, parent_count, parents); if (err < 0) { Error_set(err); goto out; @@ -1313,7 +1311,7 @@ Repository_raw_listall_references(Repository *self, PyObject *args) } out: - git_strarray_free(&c_result); + git_strarray_dispose(&c_result); return py_result; } @@ -2182,7 +2180,7 @@ Repository_list_worktrees(Repository *self, PyObject *args) } out: - git_strarray_free(&c_result); + git_strarray_dispose(&c_result); return py_result; } -- 2.44.0