From: Patrick Steinhardt Date: Fri, 17 Jul 2026 09:32:14 +0000 (+0200) Subject: object-file: fix memory leak in `force_object_loose()` X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0e002f6dc74841324687284e6a3ae4a6061c0c73;p=thirdparty%2Fgit.git object-file: fix memory leak in `force_object_loose()` 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 Signed-off-by: Junio C Hamano --- 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; }