Skip to content

Commit e9aa762

Browse files
vtbassmattgitster
authored andcommitted
odb: teach read_blob_entry to use size_t
There is mixed use of size_t and unsigned long to deal with sizes in the codebase. Recall that Windows defines unsigned long as 32 bits even on 64-bit platforms, meaning that converting size_t to unsigned long narrows the range. This mostly doesn't cause a problem since Git rarely deals with files larger than 2^32 bytes. But adjunct systems such as Git LFS, which use smudge/clean filters to keep huge files out of the repository, may have huge file contents passed through some of the functions in entry.c and convert.c. On Windows, this results in a truncated file being written to the workdir. I traced this to one specific use of unsigned long in write_entry (and a similar instance in write_pc_item_to_fd for parallel checkout). That appeared to be for the call to read_blob_entry, which expects a pointer to unsigned long. By altering the signature of read_blob_entry to expect a size_t, write_entry can be switched to use size_t internally (which all of its callers and most of its callees already used). To avoid touching dozens of additional files, read_blob_entry uses a local unsigned long to call a chain of functions which aren't prepared to accept size_t. Helped-by: Johannes Schindelin <[email protected]> Signed-off-by: Matt Cooper <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b79541a commit e9aa762

File tree

4 files changed

+8
-6
lines changed

4 files changed

+8
-6
lines changed

entry.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,13 @@ static int create_file(const char *path, unsigned int mode)
8282
return open(path, O_WRONLY | O_CREAT | O_EXCL, mode);
8383
}
8484

85-
void *read_blob_entry(const struct cache_entry *ce, unsigned long *size)
85+
void *read_blob_entry(const struct cache_entry *ce, size_t *size)
8686
{
8787
enum object_type type;
88-
void *blob_data = read_object_file(&ce->oid, &type, size);
88+
unsigned long ul;
89+
void *blob_data = read_object_file(&ce->oid, &type, &ul);
8990

91+
*size = ul;
9092
if (blob_data) {
9193
if (type == OBJ_BLOB)
9294
return blob_data;
@@ -270,7 +272,7 @@ static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca
270272
int fd, ret, fstat_done = 0;
271273
char *new_blob;
272274
struct strbuf buf = STRBUF_INIT;
273-
unsigned long size;
275+
size_t size;
274276
ssize_t wrote;
275277
size_t newsize = 0;
276278
struct stat st;

entry.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ int finish_delayed_checkout(struct checkout *state, int *nr_checkouts);
5151
*/
5252
void unlink_entry(const struct cache_entry *ce);
5353

54-
void *read_blob_entry(const struct cache_entry *ce, unsigned long *size);
54+
void *read_blob_entry(const struct cache_entry *ce, size_t *size);
5555
int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st);
5656
void update_ce_after_write(const struct checkout *state, struct cache_entry *ce,
5757
struct stat *st);

parallel-checkout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ static int write_pc_item_to_fd(struct parallel_checkout_item *pc_item, int fd,
261261
struct stream_filter *filter;
262262
struct strbuf buf = STRBUF_INIT;
263263
char *blob;
264-
unsigned long size;
264+
size_t size;
265265
ssize_t wrote;
266266

267267
/* Sanity check */

t/t1051-large-conversion.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ test_expect_success 'ident converts on output' '
8585

8686
# This smudge filter prepends 5GB of zeros to the file it checks out. This
8787
# ensures that smudging doesn't mangle large files on 64-bit Windows.
88-
test_expect_failure EXPENSIVE,SIZE_T_IS_64BIT,!LONG_IS_64BIT \
88+
test_expect_success EXPENSIVE,SIZE_T_IS_64BIT,!LONG_IS_64BIT \
8989
'files over 4GB convert on output' '
9090
test_commit test small "a small file" &&
9191
small_size=$(test_file_size small) &&

0 commit comments

Comments
 (0)