futils_filesize: use `uint64_t` for object size Instead of using a signed type (`off_t`) use `uint64_t` for the maximum size of files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
diff --git a/src/diff_file.c b/src/diff_file.c
index 4496832..6c9a8e0 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -330,8 +330,10 @@ static int diff_file_content_load_workdir_file(
if (fd < 0)
return fd;
- if (!fc->file->size &&
- !(fc->file->size = git_futils_filesize(fd)))
+ if (!fc->file->size)
+ error = git_futils_filesize(&fc->file->size, fd);
+
+ if (error < 0 || !fc->file->size)
goto cleanup;
if ((diff_opts->flags & GIT_DIFF_SHOW_BINARY) == 0 &&
diff --git a/src/futils.c b/src/futils.c
index 7454844..c508c74 100644
--- a/src/futils.c
+++ b/src/futils.c
@@ -112,7 +112,7 @@ int git_futils_truncate(const char *path, int mode)
return 0;
}
-git_off_t git_futils_filesize(git_file fd)
+int git_futils_filesize(uint64_t *out, git_file fd)
{
struct stat sb;
@@ -121,7 +121,13 @@ git_off_t git_futils_filesize(git_file fd)
return -1;
}
- return sb.st_size;
+ if (sb.st_size < 0) {
+ git_error_set(GIT_ERROR_INVALID, "invalid file size");
+ return -1;
+ }
+
+ *out = sb.st_size;
+ return 0;
}
mode_t git_futils_canonical_mode(mode_t raw_mode)
@@ -309,16 +315,14 @@ int git_futils_mmap_ro(git_map *out, git_file fd, git_off_t begin, size_t len)
int git_futils_mmap_ro_file(git_map *out, const char *path)
{
git_file fd = git_futils_open_ro(path);
- git_off_t len;
+ uint64_t len;
int result;
if (fd < 0)
return fd;
- if ((len = git_futils_filesize(fd)) < 0) {
- result = -1;
+ if ((result = git_futils_filesize(&len, fd)) < 0)
goto out;
- }
if (!git__is_sizet(len)) {
git_error_set(GIT_ERROR_OS, "file `%s` too large to mmap", path);
diff --git a/src/futils.h b/src/futils.h
index 1e2d3f9..e6fd22b 100644
--- a/src/futils.h
+++ b/src/futils.h
@@ -255,7 +255,7 @@ extern int git_futils_truncate(const char *path, int mode);
/**
* Get the filesize in bytes of a file
*/
-extern git_off_t git_futils_filesize(git_file fd);
+extern int git_futils_filesize(uint64_t *out, git_file fd);
#define GIT_PERMS_IS_EXEC(MODE) (((MODE) & 0111) != 0)
#define GIT_PERMS_CANONICAL(MODE) (GIT_PERMS_IS_EXEC(MODE) ? 0755 : 0644)
diff --git a/src/odb.c b/src/odb.c
index 2998a2d..68d9a9a 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -320,20 +320,26 @@ int git_odb__hashlink(git_oid *out, const char *path)
int git_odb_hashfile(git_oid *out, const char *path, git_object_t type)
{
- git_object_size_t size;
- int result, fd = git_futils_open_ro(path);
- if (fd < 0)
+ uint64_t size;
+ int fd, error = 0;
+
+ if ((fd = git_futils_open_ro(path)) < 0)
return fd;
- if ((size = git_futils_filesize(fd)) < 0 || !git__is_sizet(size)) {
+ if ((error = git_futils_filesize(&size, fd)) < 0)
+ goto done;
+
+ if (!git__is_sizet(size)) {
git_error_set(GIT_ERROR_OS, "file size overflow for 32-bit systems");
- p_close(fd);
- return -1;
+ error = -1;
+ goto done;
}
- result = git_odb__hashfd(out, fd, (size_t)size, type);
+ error = git_odb__hashfd(out, fd, (size_t)size, type);
+
+done:
p_close(fd);
- return result;
+ return error;
}
int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type)
diff --git a/src/repository.c b/src/repository.c
index 5871e95..14968d7 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -2545,7 +2545,7 @@ int git_repository_hashfile(
int error;
git_filter_list *fl = NULL;
git_file fd = -1;
- git_off_t len;
+ uint64_t len;
git_buf full_path = GIT_BUF_INIT;
assert(out && path && repo); /* as_path can be NULL */
@@ -2582,11 +2582,8 @@ int git_repository_hashfile(
goto cleanup;
}
- len = git_futils_filesize(fd);
- if (len < 0) {
- error = (int)len;
+ if ((error = git_futils_filesize(&len, fd)) < 0)
goto cleanup;
- }
if (!git__is_sizet(len)) {
git_error_set(GIT_ERROR_OS, "file size overflow for 32-bit systems");