e9aa762cc7
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 <johannes.schindelin@gmx.de> Signed-off-by: Matt Cooper <vtbassmatt@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
60 lines
1.8 KiB
C
60 lines
1.8 KiB
C
#ifndef ENTRY_H
|
|
#define ENTRY_H
|
|
|
|
#include "cache.h"
|
|
#include "convert.h"
|
|
|
|
struct checkout {
|
|
struct index_state *istate;
|
|
const char *base_dir;
|
|
int base_dir_len;
|
|
struct delayed_checkout *delayed_checkout;
|
|
struct checkout_metadata meta;
|
|
unsigned force:1,
|
|
quiet:1,
|
|
not_new:1,
|
|
clone:1,
|
|
refresh_cache:1;
|
|
};
|
|
#define CHECKOUT_INIT { NULL, "" }
|
|
|
|
#define TEMPORARY_FILENAME_LENGTH 25
|
|
/*
|
|
* Write the contents from ce out to the working tree.
|
|
*
|
|
* When topath[] is not NULL, instead of writing to the working tree
|
|
* file named by ce, a temporary file is created by this function and
|
|
* its name is returned in topath[], which must be able to hold at
|
|
* least TEMPORARY_FILENAME_LENGTH bytes long.
|
|
*
|
|
* With checkout_entry_ca(), callers can optionally pass a preloaded
|
|
* conv_attrs struct (to avoid reloading it), when ce refers to a
|
|
* regular file. If ca is NULL, the attributes will be loaded
|
|
* internally when (and if) needed.
|
|
*/
|
|
int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca,
|
|
const struct checkout *state, char *topath,
|
|
int *nr_checkouts);
|
|
static inline int checkout_entry(struct cache_entry *ce,
|
|
const struct checkout *state, char *topath,
|
|
int *nr_checkouts)
|
|
{
|
|
return checkout_entry_ca(ce, NULL, state, topath, nr_checkouts);
|
|
}
|
|
|
|
void enable_delayed_checkout(struct checkout *state);
|
|
int finish_delayed_checkout(struct checkout *state, int *nr_checkouts);
|
|
|
|
/*
|
|
* Unlink the last component and schedule the leading directories for
|
|
* removal, such that empty directories get removed.
|
|
*/
|
|
void unlink_entry(const struct cache_entry *ce);
|
|
|
|
void *read_blob_entry(const struct cache_entry *ce, size_t *size);
|
|
int fstat_checkout_output(int fd, const struct checkout *state, struct stat *st);
|
|
void update_ce_after_write(const struct checkout *state, struct cache_entry *ce,
|
|
struct stat *st);
|
|
|
|
#endif /* ENTRY_H */
|