[PATCH 2/4] fsck: use size_t for the size of objects to check
- From
Elia Pinto <gitter.spiros@gmail.com>
- Date
- Oct 31, 2026, 11:09 UTC
- Message-ID
- <7551e796e7d27fbe3a6710801adce788bdc17230.1793444420.git.gitter.spiros@gmail.com>
- In-Reply-To
- <cover.1793444420.git.gitter.spiros@gmail.com>
fsck functions such as fsck_object() and fsck_buffer() take the object size as an "unsigned long", while some callers pass a size_t. On platforms where "long" is 32 bits, this truncates the size for objects of 4GiB or more.
When checking large objects on those platforms, fsck inspects only a prefix of the buffer.
Use size_t for the size parameter across the fsck functions and internal helpers, including the loop index in verify_headers().
Some callers and pack verification paths still pass "unsigned long" to fsck_object(), and fsck_tree() passes the size to tree-walk routines; those will be updated separately.
Triggering this requires processing 4GiB or more of input on a platform where "long" is 32 bits, so no test is added.
Signed-off-by: Elia Pinto <gitter.spiros@gmail.com> --- fsck.c | 18 +++++++++--------- fsck.h | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/fsck.c b/fsck.c index 94c8651c7d..7b0e9a5892 100644 --- a/fsck.c +++ b/fsck.c @@ -614,7 +614,7 @@ static int verify_ordered(unsigned mode1, const char *name1, } static int fsck_tree(const struct object_id *tree_oid, - const char *buffer, unsigned long size, + const char *buffer, size_t size, struct fsck_options *options) { int retval = 0; @@ -826,12 +826,12 @@ static int fsck_tree(const struct object_id *tree_oid, * case hit the newline we found here as the end-of-header. This makes it * OK for them to use helpers like parse_oid_hex(), or even skip_prefix(). */ -static int verify_headers(const void *data, unsigned long size, +static int verify_headers(const void *data, size_t size, const struct object_id *oid, enum object_type type, struct fsck_options *options) { const char *buffer = (const char *)data; - unsigned long i; + size_t i; for (i = 0; i < size; i++) { switch (buffer[i]) { @@ -948,7 +948,7 @@ static int fsck_ident(const char **ident, const char *ident_end, } static int fsck_commit(const struct object_id *oid, - const char *buffer, unsigned long size, + const char *buffer, size_t size, struct fsck_options *options) { struct object_id tree_oid, parent_oid; @@ -1010,7 +1010,7 @@ static int fsck_commit(const struct object_id *oid, } static int fsck_tag(const struct object_id *oid, const char *buffer, - unsigned long size, struct fsck_options *options) + size_t size, struct fsck_options *options) { struct object_id tagged_oid; int tagged_type; @@ -1019,7 +1019,7 @@ static int fsck_tag(const struct object_id *oid, const char *buffer, } int fsck_tag_standalone(const struct object_id *oid, const char *buffer, - unsigned long size, struct fsck_options *options, + size_t size, struct fsck_options *options, struct object_id *tagged_oid, int *tagged_type) { @@ -1182,7 +1182,7 @@ static int fsck_gitmodules_fn(const char *var, const char *value, } static int fsck_blob(const struct object_id *oid, const char *buf, - unsigned long size, struct fsck_options *options) + size_t size, struct fsck_options *options) { int ret = 0; @@ -1251,7 +1251,7 @@ static int fsck_blob(const struct object_id *oid, const char *buf, return ret; } -int fsck_object(struct object *obj, void *data, unsigned long size, +int fsck_object(struct object *obj, void *data, size_t size, struct fsck_options *options) { if (!obj) @@ -1261,7 +1261,7 @@ int fsck_object(struct object *obj, void *data, unsigned long size, } int fsck_buffer(const struct object_id *oid, enum object_type type, - const void *data, unsigned long size, + const void *data, size_t size, struct fsck_options *options) { if (type == OBJ_BLOB) diff --git a/fsck.h b/fsck.h index e77935c8a9..2a075a5572 100644 --- a/fsck.h +++ b/fsck.h @@ -196,7 +196,7 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options); * Blob objects my pass a NULL data pointer, which indicates they are too large * to fit in memory. All other types must pass a real buffer. */ -int fsck_object(struct object *obj, void *data, unsigned long size, +int fsck_object(struct object *obj, void *data, size_t size, struct fsck_options *options); /* @@ -204,7 +204,7 @@ int fsck_object(struct object *obj, void *data, unsigned long size, * struct. */ int fsck_buffer(const struct object_id *oid, enum object_type, - const void *data, unsigned long size, + const void *data, size_t size, struct fsck_options *options); /* @@ -212,7 +212,7 @@ int fsck_buffer(const struct object_id *oid, enum object_type, * exposed fsck_object() internals for git-mktag(1). */ int fsck_tag_standalone(const struct object_id *oid, const char *buffer, - unsigned long size, struct fsck_options *options, + size_t size, struct fsck_options *options, struct object_id *tagged_oid, int *tag_type);
-- 2.53.0