Commit bdf0e734 by Carlos Martín Nieto

Merge pull request #2932 from jeffhostetler/jeffhostetler/big_clone_crash

Fix crash in git_clone on extremely large repos
parents 107958d7 d8be5087
......@@ -41,7 +41,7 @@ extern int p_chdir(const char* path);
extern int p_chmod(const char* path, mode_t mode);
extern int p_rmdir(const char* path);
extern int p_access(const char* path, mode_t mode);
extern int p_ftruncate(int fd, long size);
extern int p_ftruncate(int fd, git_off_t size);
/* p_lstat is almost but not quite POSIX correct. Specifically, the use of
* ENOTDIR is wrong, in that it does not mean precisely that a non-directory
......
......@@ -42,12 +42,28 @@
/* GetFinalPathNameByHandleW signature */
typedef DWORD(WINAPI *PFGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD);
int p_ftruncate(int fd, long size)
/**
* Truncate or extend file.
*
* We now take a "git_off_t" rather than "long" because
* files may be longer than 2Gb.
*/
int p_ftruncate(int fd, git_off_t size)
{
#if defined(_MSC_VER) && _MSC_VER >= 1500
return _chsize_s(fd, size);
if (size < 0) {
errno = EINVAL;
return -1;
}
#if !defined(__MINGW32__)
return ((_chsize_s(fd, size) == 0) ? 0 : -1);
#else
return _chsize(fd, size);
/* TODO MINGW32 Find a replacement for _chsize() that handles big files. */
if (size > INT32_MAX) {
errno = EFBIG;
return -1;
}
return _chsize(fd, (long)size);
#endif
}
......
/**
* Some tests for p_ftruncate() to ensure that
* properly handles large (2Gb+) files.
*/
#include "clar_libgit2.h"
static const char *filename = "core_ftruncate.txt";
static int fd = -1;
void test_core_ftruncate__initialize(void)
{
if (!cl_getenv("GITTEST_INVASIVE_FS_SIZE"))
cl_skip();
cl_must_pass((fd = p_open(filename, O_CREAT | O_RDWR, 0644)));
}
void test_core_ftruncate__cleanup(void)
{
if (fd < 0)
return;
p_close(fd);
fd = 0;
p_unlink(filename);
}
static void _extend(git_off_t i64len)
{
struct stat st;
int error;
cl_assert((error = p_ftruncate(fd, i64len)) == 0);
cl_assert((error = p_fstat(fd, &st)) == 0);
cl_assert(st.st_size == i64len);
}
void test_core_ftruncate__2gb(void)
{
_extend(0x80000001);
}
void test_core_ftruncate__4gb(void)
{
_extend(0x100000001);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment