]> git.ipfire.org Git - thirdparty/git.git/commitdiff
pack-objects: use size_t for in-core object sizes
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Mon, 15 Jun 2026 11:52:27 +0000 (11:52 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Jun 2026 14:45:41 +0000 (07:45 -0700)
`pack-objects` stores per-entry object sizes in either the 31-bit
`size_` member of the `struct object_entry` or, when the value does not
fit, the `pack->delta_size[]` spill array.  The accessors (`oe_size`,
`oe_delta_size`, `oe_get_size_slow`, `oe_size_*_than`) and the setters
(`oe_set_size`, `oe_set_delta_size`) used `unsigned long` for the spill
type, which on Windows means the spill silently caps at 4 GiB per entry.
That is what made `upload-pack` die with "object too large to read on
this platform" when serving the >4 GiB blob in `t5608` tests 5 and 6
when run with `GIT_TEST_CLONE_2GB`.

Widen them all to `size_t` (including `pack->delta_size`) and drop the
three `cast_size_t_to_ulong()` calls in `check_object()` that guarded
`in_pack_size`.  The two `SET_SIZE(entry, canonical_size)` calls in the
same function stay cast-free as before, since `canonical_size` is still
`unsigned long` until a later commit widens `object_info::sizep`.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/pack-objects.c
pack-objects.h

index 56d1bb498dac6a79070af9e6bc97fb2f23198fe7..961d547ef26965766a3a5ba4a8e59612036731a8 100644 (file)
@@ -66,8 +66,8 @@ static inline struct object_entry *oe_delta(
                return &pack->objects[e->delta_idx - 1];
 }
 
-static inline unsigned long oe_delta_size(struct packing_data *pack,
-                                         const struct object_entry *e)
+static inline size_t oe_delta_size(struct packing_data *pack,
+                                  const struct object_entry *e)
 {
        if (e->delta_size_valid)
                return e->delta_size_;
@@ -83,11 +83,11 @@ static inline unsigned long oe_delta_size(struct packing_data *pack,
        return pack->delta_size[e - pack->objects];
 }
 
-unsigned long oe_get_size_slow(struct packing_data *pack,
-                              const struct object_entry *e);
+size_t oe_get_size_slow(struct packing_data *pack,
+                       const struct object_entry *e);
 
-static inline unsigned long oe_size(struct packing_data *pack,
-                                   const struct object_entry *e)
+static inline size_t oe_size(struct packing_data *pack,
+                            const struct object_entry *e)
 {
        if (e->size_valid)
                return e->size_;
@@ -145,7 +145,7 @@ static inline void oe_set_delta_sibling(struct packing_data *pack,
 
 static inline void oe_set_size(struct packing_data *pack,
                               struct object_entry *e,
-                              unsigned long size)
+                              size_t size)
 {
        if (size < pack->oe_size_limit) {
                e->size_ = size;
@@ -159,7 +159,7 @@ static inline void oe_set_size(struct packing_data *pack,
 
 static inline void oe_set_delta_size(struct packing_data *pack,
                                     struct object_entry *e,
-                                    unsigned long size)
+                                    size_t size)
 {
        if (size < pack->oe_delta_size_limit) {
                e->delta_size_ = size;
@@ -496,7 +496,7 @@ static void copy_pack_data(struct hashfile *f,
 
 static inline int oe_size_greater_than(struct packing_data *pack,
                                       const struct object_entry *lhs,
-                                      unsigned long rhs)
+                                      size_t rhs)
 {
        if (lhs->size_valid)
                return lhs->size_ > rhs;
@@ -2279,7 +2279,7 @@ static void check_object(struct object_entry *entry, uint32_t object_index)
                default:
                        /* Not a delta hence we've already got all we need. */
                        oe_set_type(entry, entry->in_pack_type);
-                       SET_SIZE(entry, cast_size_t_to_ulong(in_pack_size));
+                       SET_SIZE(entry, in_pack_size);
                        entry->in_pack_header_size = used;
                        if (oe_type(entry) < OBJ_COMMIT || oe_type(entry) > OBJ_BLOB)
                                goto give_up;
@@ -2333,8 +2333,8 @@ static void check_object(struct object_entry *entry, uint32_t object_index)
                if (have_base &&
                    can_reuse_delta(&base_ref, entry, &base_entry)) {
                        oe_set_type(entry, entry->in_pack_type);
-                       SET_SIZE(entry, cast_size_t_to_ulong(in_pack_size)); /* delta size */
-                       SET_DELTA_SIZE(entry, cast_size_t_to_ulong(in_pack_size));
+                       SET_SIZE(entry, in_pack_size); /* delta size */
+                       SET_DELTA_SIZE(entry, in_pack_size);
 
                        if (base_entry) {
                                SET_DELTA(entry, base_entry);
@@ -2357,7 +2357,8 @@ static void check_object(struct object_entry *entry, uint32_t object_index)
                         * object size from the delta header.
                         */
                        delta_pos = entry->in_pack_offset + entry->in_pack_header_size;
-                       canonical_size = get_size_from_delta(p, &w_curs, delta_pos);
+                       canonical_size = get_size_from_delta(p, &w_curs,
+                                                            delta_pos);
                        if (canonical_size == 0)
                                goto give_up;
                        SET_SIZE(entry, canonical_size);
@@ -2713,7 +2714,7 @@ static pthread_mutex_t progress_mutex;
 
 static inline int oe_size_less_than(struct packing_data *pack,
                                    const struct object_entry *lhs,
-                                   unsigned long rhs)
+                                   size_t rhs)
 {
        if (lhs->size_valid)
                return lhs->size_ < rhs;
@@ -2736,8 +2737,8 @@ static inline void oe_set_tree_depth(struct packing_data *pack,
  * reconstruction (so non-deltas are true object sizes, but deltas
  * return the size of the delta data).
  */
-unsigned long oe_get_size_slow(struct packing_data *pack,
-                              const struct object_entry *e)
+size_t oe_get_size_slow(struct packing_data *pack,
+                       const struct object_entry *e)
 {
        struct packed_git *p;
        struct pack_window *w_curs;
@@ -2771,7 +2772,7 @@ unsigned long oe_get_size_slow(struct packing_data *pack,
 
        unuse_pack(&w_curs);
        packing_data_unlock(&to_pack);
-       return cast_size_t_to_ulong(size);
+       return size;
 }
 
 static int try_delta(struct unpacked *trg, struct unpacked *src,
index 83299d47324f1ed351db0f6f277b97811cb288a4..e97e84ddcb9d5b36441927b38b3cfa75a77f46f9 100644 (file)
@@ -141,7 +141,7 @@ struct packing_data {
        uint32_t index_size;
 
        unsigned int *in_pack_pos;
-       unsigned long *delta_size;
+       size_t *delta_size;
 
        /*
         * Only one of these can be non-NULL and they have different