summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2019-06-23 16:23:59 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2019-11-22 15:13:05 +1100
commitfb2198db6b48ce3c5e3cecaa03ecb179c5a02382 (patch)
tree29e62fd409b5e8fe7d0af4de98d187cfd8641af2
parent4334b1779f661bf9a77c68c928e970cf9d25b477 (diff)
downloadlibgit2-fb2198db6b48ce3c5e3cecaa03ecb179c5a02382.tar.gz
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.
-rw-r--r--src/diff_file.c6
-rw-r--r--src/futils.c16
-rw-r--r--src/futils.h2
-rw-r--r--src/odb.c22
-rw-r--r--src/repository.c7
5 files changed, 31 insertions, 22 deletions
diff --git a/src/diff_file.c b/src/diff_file.c
index 449683239..6c9a8e0ba 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 7454844e7..c508c7485 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 1e2d3f9d9..e6fd22bc1 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 2998a2d43..68d9a9a3f 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 5871e9567..14968d75d 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");