From: Patrick Steinhardt Date: Fri, 17 Jul 2026 09:32:14 GMT Subject: [PATCH 6/9] object-file: fix memory leak in `force_object_loose()` Message-ID: <20260717-pks-odb-move-loose-object-writing-v1-6-46446a3cb5b7@pks.im> In-Reply-To: <20260717-pks-odb-move-loose-object-writing-v1-0-46446a3cb5b7@pks.im> We return an error when converting the given object to the compatibility hash algorithm fails. This early return causes a memory leak though, because we don't free the content buffer that we've already read before via `odb_read_object_info_extended()`. Plug the memory leak by creating a common exit path where the buffer gets free'd. Signed-off-by: Patrick Steinhardt --- object-file.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/object-file.c b/object-file.c index 5b07530950..067a63a4f1 100644 --- a/object-file.c +++ b/object-file.c @@ -898,7 +898,7 @@ int force_object_loose(struct odb_source *source, { struct odb_source_files *files = odb_source_files_downcast(source); const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; - void *buf; + void *buf = NULL; size_t len; struct object_info oi = OBJECT_INFO_INIT; struct object_id compat_oid; @@ -916,19 +916,29 @@ int force_object_loose(struct odb_source *source, oi.typep = &type; oi.sizep = &len; oi.contentp = &buf; - if (odb_read_object_info_extended(source->odb, oid, &oi, 0)) - return error(_("cannot read object for %s"), oid_to_hex(oid)); + if (odb_read_object_info_extended(source->odb, oid, &oi, 0)) { + ret = error(_("cannot read object for %s"), oid_to_hex(oid)); + goto out; + } + if (compat) { - if (repo_oid_to_algop(source->odb->repo, oid, compat, &compat_oid)) - return error(_("cannot map object %s to %s"), - oid_to_hex(oid), compat->name); + if (repo_oid_to_algop(source->odb->repo, oid, compat, &compat_oid)) { + ret = error(_("cannot map object %s to %s"), + oid_to_hex(oid), compat->name); + goto out; + } } + hdrlen = format_object_header(hdr, sizeof(hdr), type, len); ret = write_loose_object(files->loose, oid, hdr, hdrlen, buf, len, mtime, 0); - if (!ret && compat) + if (ret) + goto out; + + if (compat) ret = repo_add_loose_object_map(files->loose, oid, &compat_oid); - free(buf); +out: + free(buf); return ret; } -- 2.55.0.407.g700c83d4f3.dirty