Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion git-zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This macro and comment makes me wonder if we're not using the ULONG_MAX_VALUE to check or gate something which now should be checking against SIZE_MAX?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this macro (and the surrounding uLong code) are about zlib's API using the unsigned long data type instead of the size_t one... So we have to work around that in Git's code. This macro is correct, and needed as-is, unfortunately.

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;
}
Expand Down
12 changes: 6 additions & 6 deletions object-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions object-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion odb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions odb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
8 changes: 4 additions & 4 deletions odb/source-loose.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion odb/source.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions t/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
36 changes: 36 additions & 0 deletions t/t3706-add-4gb-file.sh
Original file line number Diff line number Diff line change
@@ -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
Loading