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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 17, 2026 at 11:32 UTC 0e002f6dc74841324687284e6a3ae4a6061c0c73
1 file changed +18 -8
object-file.c
+18 -8
@@ -898,7 +898,7 @@ int force_object_loose(struct odb_source *source,
898 {
899 struct odb_source_files *files = odb_source_files_downcast(source);
900 const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo;
901 - void *buf;
901 + void *buf = NULL;
902 size_t len;
903 struct object_info oi = OBJECT_INFO_INIT;
904 struct object_id compat_oid;
@@ -916,19 +916,29 @@ int force_object_loose(struct odb_source *source,
916 oi.typep = &type;
917 oi.sizep = &len;
918 oi.contentp = &buf;
919 - if (odb_read_object_info_extended(source->odb, oid, &oi, 0))
920 - return error(_("cannot read object for %s"), oid_to_hex(oid));
919 + if (odb_read_object_info_extended(source->odb, oid, &oi, 0)) {
920 + ret = error(_("cannot read object for %s"), oid_to_hex(oid));
921 + goto out;
922 + }
923 +
924 if (compat) {
922 - if (repo_oid_to_algop(source->odb->repo, oid, compat, &compat_oid))
923 - return error(_("cannot map object %s to %s"),
924 - oid_to_hex(oid), compat->name);
925 + if (repo_oid_to_algop(source->odb->repo, oid, compat, &compat_oid)) {
926 + ret = error(_("cannot map object %s to %s"),
927 + oid_to_hex(oid), compat->name);
928 + goto out;
929 + }
930 }
931 +
932 hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
933 ret = write_loose_object(files->loose, oid, hdr, hdrlen, buf, len, mtime, 0);
928 - if (!ret && compat)
934 + if (ret)
935 + goto out;
936 +
937 + if (compat)
938 ret = repo_add_loose_object_map(files->loose, oid, &compat_oid);
930 - free(buf);
939
940 +out:
941 + free(buf);
942 return ret;
943 }
944