diff --git a/git-zlib.c b/git-zlib.c index ebbbcc6d1a5077..1c94f90497ee47 100644 --- a/git-zlib.c +++ b/git-zlib.c @@ -33,7 +33,7 @@ static const char *zerr_to_string(int status) /* uLong is 32-bit on Windows, even on 64-bit systems */ #define ULONG_MAX_VALUE maximum_unsigned_value_of_type(uLong) -static inline uInt zlib_buf_cap(unsigned long len) +static inline uInt zlib_buf_cap(size_t len) { return (ZLIB_BUF_MAX < len) ? ZLIB_BUF_MAX : len; } diff --git a/object-file.c b/object-file.c index 6453b1d6fa7d1b..002c08b970ccee 100644 --- a/object-file.c +++ b/object-file.c @@ -146,7 +146,7 @@ int stream_object_signature(struct repository *r, * Map and close the given loose object fd. The path argument is used for * error reporting. */ -static void *map_fd(int fd, const char *path, unsigned long *size) +static void *map_fd(int fd, const char *path, size_t *size) { void *map = NULL; struct stat st; @@ -167,9 +167,9 @@ static void *map_fd(int fd, const char *path, unsigned long *size) enum unpack_loose_header_result unpack_loose_header(git_zstream *stream, unsigned char *map, - unsigned long mapsize, + size_t mapsize, void *buffer, - unsigned long bufsiz) + size_t bufsiz) { int status; @@ -200,7 +200,7 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream, } void *unpack_loose_rest(git_zstream *stream, - void *buffer, unsigned long size, + void *buffer, size_t size, const struct object_id *oid) { size_t bytes = strlen(buffer) + 1, n; @@ -749,7 +749,7 @@ static int end_loose_object_common(struct odb_source_loose *loose, int write_loose_object(struct odb_source_loose *loose, const struct object_id *oid, char *hdr, - int hdrlen, const void *buf, unsigned long len, + int hdrlen, const void *buf, size_t len, time_t mtime, unsigned flags) { int fd, ret; @@ -1613,7 +1613,7 @@ int read_loose_object(struct repository *repo, int ret = -1; int fd; void *map = NULL; - unsigned long mapsize; + size_t mapsize; git_zstream stream; char hdr[MAX_HEADER_LEN]; size_t *size = oi->sizep; diff --git a/object-file.h b/object-file.h index 4c87cd160bb58a..1470469d28ba2c 100644 --- a/object-file.h +++ b/object-file.h @@ -139,7 +139,7 @@ void write_object_file_prepare(const struct git_hash_algo *algo, char *hdr, size_t *hdrlen); int write_loose_object(struct odb_source_loose *loose, const struct object_id *oid, char *hdr, - int hdrlen, const void *buf, unsigned long len, + int hdrlen, const void *buf, size_t len, time_t mtime, unsigned flags); /* Helper to check and "touch" a file */ @@ -180,11 +180,11 @@ enum unpack_loose_header_result { */ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream, unsigned char *map, - unsigned long mapsize, + size_t mapsize, void *buffer, - unsigned long bufsiz); + size_t bufsiz); void *unpack_loose_rest(git_zstream *stream, - void *buffer, unsigned long size, + void *buffer, size_t size, const struct object_id *oid); int parse_loose_header(const char *hdr, struct object_info *oi); diff --git a/odb.c b/odb.c index 7d555be09feaea..fd9b87e99a245f 100644 --- a/odb.c +++ b/odb.c @@ -986,7 +986,7 @@ void odb_assert_oid_type(struct object_database *odb, } int odb_write_object_ext(struct object_database *odb, - const void *buf, unsigned long len, + const void *buf, size_t len, enum object_type type, struct object_id *oid, struct object_id *compat_oid, diff --git a/odb.h b/odb.h index 3834a0dcbf033b..06af0b847d13d4 100644 --- a/odb.h +++ b/odb.h @@ -548,14 +548,14 @@ enum odb_write_object_flags { * Returns 0 on success, a negative error code otherwise. */ int odb_write_object_ext(struct object_database *odb, - const void *buf, unsigned long len, + const void *buf, size_t len, enum object_type type, struct object_id *oid, struct object_id *compat_oid, enum odb_write_object_flags flags); static inline int odb_write_object(struct object_database *odb, - const void *buf, unsigned long len, + const void *buf, size_t len, enum object_type type, struct object_id *oid) { diff --git a/odb/source-loose.c b/odb/source-loose.c index 6211348a4d3561..51bcb0b2e05845 100644 --- a/odb/source-loose.c +++ b/odb/source-loose.c @@ -68,7 +68,7 @@ static int read_object_info_from_path(struct odb_source_loose *loose, { int ret; int fd; - unsigned long mapsize; + size_t mapsize; void *map = NULL; git_zstream stream, *stream_to_end = NULL; char hdr[MAX_HEADER_LEN]; @@ -248,7 +248,7 @@ static int open_loose_object(struct odb_source_loose *loose, static void *odb_source_loose_map_object(struct odb_source_loose *loose, const struct object_id *oid, - unsigned long *size) + size_t *size) { const char *p; int fd = open_loose_object(loose, oid, &p); @@ -283,7 +283,7 @@ struct odb_loose_read_stream { ODB_LOOSE_READ_STREAM_ERROR, } z_state; void *mapped; - unsigned long mapsize; + size_t mapsize; char hdr[32]; int hdr_avail; int hdr_used; @@ -354,7 +354,7 @@ static int odb_source_loose_read_object_stream(struct odb_read_stream **out, struct odb_source_loose *loose = odb_source_loose_downcast(source); struct object_info oi = OBJECT_INFO_INIT; struct odb_loose_read_stream *st; - unsigned long mapsize; + size_t mapsize; void *mapped; mapped = odb_source_loose_map_object(loose, oid, &mapsize); diff --git a/odb/source.h b/odb/source.h index 1c65a05e2c4c6b..3ba75ec4ee1e85 100644 --- a/odb/source.h +++ b/odb/source.h @@ -407,7 +407,7 @@ static inline int odb_source_freshen_object(struct odb_source *source, * object ID and the compatibility object ID, if non-NULL. */ static inline int odb_source_write_object(struct odb_source *source, - const void *buf, unsigned long len, + const void *buf, size_t len, enum object_type type, struct object_id *oid, struct object_id *compat_oid, diff --git a/t/meson.build b/t/meson.build index 85cb439bdda599..c86bf0de910cda 100644 --- a/t/meson.build +++ b/t/meson.build @@ -427,6 +427,7 @@ integration_tests = [ 't3703-add-magic-pathspec.sh', 't3704-add-pathspec-file.sh', 't3705-add-sparse-checkout.sh', + 't3706-add-4gb-file.sh', 't3800-mktag.sh', 't3900-i18n-commit.sh', 't3901-i18n-patch.sh', diff --git a/t/t3706-add-4gb-file.sh b/t/t3706-add-4gb-file.sh new file mode 100755 index 00000000000000..5978ca3ee24c8a --- /dev/null +++ b/t/t3706-add-4gb-file.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Copyright (c) 2026 Johannes Schindelin +# + +test_description='add 4GB+ objects' + +. ./test-lib.sh + +if ! test_have_prereq EXPENSIVE,SIZE_T_IS_64BIT +then + skip_all='expensive 4GB blob test; enable on 64-bit with GIT_TEST_LONG=true' + test_done +fi + +size_4gb=4294967296 + +test_expect_success 'set up a 4GB file' ' + test_atexit "rm -f large" && + # genrandom takes only an unsigned long... + test-tool genrandom 123 $(($size_4gb-1)) >large && + printf 1 >>large +' + +test_expect_success 'add 4GB file' ' + git add large && + git cat-file -s :large >size-staged && + test $size_4gb = $(cat size-staged) +' +test_expect_success 'read 4GB loose object' ' + git -P show :large >read && + test_file_size read >size-read && + test $size_4gb = $(cat size-read) +' + +test_done