patch-delta: use size_t for sizes

`patch_delta()` takes the source and delta sizes by value and writes back the reconstructed target size through an `unsigned long *`. That datatype cannot represent a value that exceeds 4 GiB on systems where `unsigned long` is 32-bit (notably 64-bit Windows builds), though, even though the delta encoding itself, the on-disk layout, and the in-memory buffers happily carry such sizes. A `size_t` companion to `get_delta_hdr_size()`, `get_delta_hdr_size_sz()`, was introduced in 17fa077596 (delta, packfile: use size_t for delta header sizes, 2026-05-08) precisely so that `patch_delta()` could be widened without changing the on-the-wire decoding helper's signature. Widen `patch_delta()`'s three size parameters to `size_t` and switch its internal use of `get_delta_hdr_size()` to the `_sz` variant. Then propagate the wider type through the callers. Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jun 15, 2026 at 11:52 UTC 33afe873381b21db08fa65e0910fd3bb69fd739b
7 files changed +20 -20
apply.c
+1 -1
@@ -3232,7 +3232,7 @@ static int apply_binary_fragment(struct apply_state *state,
3232 struct patch *patch)
3233 {
3234 struct fragment *fragment = patch->fragments;
3235 - unsigned long len;
3235 + size_t len;
3236 void *dst;
3237
3238 if (!fragment)
builtin/index-pack.c
+2 -2
@@ -71,7 +71,7 @@ struct base_data {
71 /* Not initialized by make_base(). */
72 struct list_head list;
73 void *data;
74 - unsigned long size;
74 + size_t size;
75 };
76
77 /*
@@ -1048,7 +1048,7 @@ static struct base_data *resolve_delta(struct object_entry *delta_obj,
1048 {
1049 void *delta_data, *result_data;
1050 struct base_data *result;
1051 - unsigned long result_size;
1051 + size_t result_size;
1052
1053 if (show_stat) {
1054 int i = delta_obj - objects;
builtin/unpack-objects.c
+1 -1
@@ -314,7 +314,7 @@ static void resolve_delta(unsigned nr, enum object_type type,
314 void *delta, unsigned long delta_size)
315 {
316 void *result;
317 - unsigned long result_size;
317 + size_t result_size;
318
319 result = patch_delta(base, base_size,
320 delta, delta_size,
delta.h
+3 -3
@@ -75,9 +75,9 @@ diff_delta(const void *src_buf, unsigned long src_bufsize,
75 * *trg_bufsize is updated with its size. On failure a NULL pointer is
76 * returned. The returned buffer must be freed by the caller.
77 */
78 -void *patch_delta(const void *src_buf, unsigned long src_size,
79 - const void *delta_buf, unsigned long delta_size,
80 - unsigned long *dst_size);
78 +void *patch_delta(const void *src_buf, size_t src_size,
79 + const void *delta_buf, size_t delta_size,
80 + size_t *dst_size);
81
82 /* the smallest possible delta size is 4 bytes */
83 #define DELTA_SIZE_MIN 4
packfile.c
+1 -3
@@ -1964,10 +1964,8 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
1964 (uintmax_t)curpos, p->pack_name);
1965 data = NULL;
1966 } else {
1967 - unsigned long sz;
1967 data = patch_delta(base, base_size, delta_data,
1969 - delta_size, &sz);
1970 - size = sz;
1968 + delta_size, &size);
1969
1970 /*
1971 * We could not apply the delta; warn the user, but
patch-delta.c
+6 -6
@@ -12,13 +12,13 @@
12 #include "git-compat-util.h"
13 #include "delta.h"
14
15 -void *patch_delta(const void *src_buf, unsigned long src_size,
16 - const void *delta_buf, unsigned long delta_size,
17 - unsigned long *dst_size)
15 +void *patch_delta(const void *src_buf, size_t src_size,
16 + const void *delta_buf, size_t delta_size,
17 + size_t *dst_size)
18 {
19 const unsigned char *data, *top;
20 unsigned char *dst_buf, *out, cmd;
21 - unsigned long size;
21 + size_t size;
22
23 if (delta_size < DELTA_SIZE_MIN)
24 return NULL;
@@ -27,12 +27,12 @@ void *patch_delta(const void *src_buf, unsigned long src_size,
27 top = (const unsigned char *) delta_buf + delta_size;
28
29 /* make sure the orig file size matches what we expect */
30 - size = get_delta_hdr_size(&data, top);
30 + size = get_delta_hdr_size_sz(&data, top);
31 if (size != src_size)
32 return NULL;
33
34 /* now the result size */
35 - size = get_delta_hdr_size(&data, top);
35 + size = get_delta_hdr_size_sz(&data, top);
36 dst_buf = xmallocz(size);
37
38 out = dst_buf;
t/helper/test-delta.c
+6 -4
@@ -21,7 +21,7 @@ int cmd__delta(int argc, const char **argv)
21 int fd;
22 struct strbuf from = STRBUF_INIT, data = STRBUF_INIT;
23 char *out_buf;
24 - unsigned long out_size;
24 + size_t out_size;
25
26 if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p")))
27 usage(usage_str);
@@ -31,11 +31,13 @@ int cmd__delta(int argc, const char **argv)
31 if (strbuf_read_file(&data, argv[3], 0) < 0)
32 die_errno("unable to read '%s'", argv[3]);
33
34 - if (argv[1][1] == 'd')
34 + if (argv[1][1] == 'd') {
35 + unsigned long delta_size;
36 out_buf = diff_delta(from.buf, from.len,
37 data.buf, data.len,
37 - &out_size, 0);
38 - else
38 + &delta_size, 0);
39 + out_size = delta_size;
40 + } else
41 out_buf = patch_delta(from.buf, from.len,
42 data.buf, data.len,
43 &out_size);