Commit 4334b1779f661bf9a77c68c928e970cf9d25b477

Edward Thomson 2019-06-23T15:43:38

blob: use `git_object_size_t` for object size Instead of using a signed type (`off_t`) use a new `git_object_size_t` for the sizes of objects.

diff --git a/include/git2/blob.h b/include/git2/blob.h
index 40f922b..7e2a745 100644
--- a/include/git2/blob.h
+++ b/include/git2/blob.h
@@ -94,7 +94,7 @@ GIT_EXTERN(const void *) git_blob_rawcontent(const git_blob *blob);
  * @param blob pointer to the blob
  * @return size on bytes
  */
-GIT_EXTERN(git_off_t) git_blob_rawsize(const git_blob *blob);
+GIT_EXTERN(git_object_size_t) git_blob_rawsize(const git_blob *blob);
 
 /**
  * Flags to control the functionality of `git_blob_filter`.
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 73c5e55..490b406 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -258,12 +258,12 @@ typedef enum {
  * abbreviated to something reasonable, like 7 characters.
  */
 typedef struct {
-	git_oid     id;
-	const char *path;
-	git_off_t   size;
-	uint32_t    flags;
-	uint16_t    mode;
-	uint16_t    id_abbrev;
+	git_oid            id;
+	const char        *path;
+	git_object_size_t  size;
+	uint32_t           flags;
+	uint16_t           mode;
+	uint16_t           id_abbrev;
 } git_diff_file;
 
 /**
diff --git a/src/attr_file.c b/src/attr_file.c
index a1b4c73..82da526 100644
--- a/src/attr_file.c
+++ b/src/attr_file.c
@@ -120,7 +120,7 @@ int git_attr_file__load(
 	int bom_offset;
 	git_bom_t bom;
 	git_oid id;
-	git_off_t blobsize;
+	git_object_size_t blobsize;
 
 	*out = NULL;
 
diff --git a/src/blob.c b/src/blob.c
index 487e608..5e734e2 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -25,18 +25,18 @@ const void *git_blob_rawcontent(const git_blob *blob)
 		return git_odb_object_data(blob->data.odb);
 }
 
-git_off_t git_blob_rawsize(const git_blob *blob)
+git_object_size_t git_blob_rawsize(const git_blob *blob)
 {
 	assert(blob);
 	if (blob->raw)
 		return blob->data.raw.size;
 	else
-		return (git_off_t)git_odb_object_size(blob->data.odb);
+		return (git_object_size_t)git_odb_object_size(blob->data.odb);
 }
 
 int git_blob__getbuf(git_buf *buffer, git_blob *blob)
 {
-	git_off_t size = git_blob_rawsize(blob);
+	git_object_size_t size = git_blob_rawsize(blob);
 
 	GIT_ERROR_CHECK_BLOBSIZE(size);
 	return git_buf_set(buffer, git_blob_rawcontent(blob), (size_t)size);
@@ -91,13 +91,13 @@ int git_blob_create_from_buffer(
 }
 
 static int write_file_stream(
-	git_oid *id, git_odb *odb, const char *path, git_off_t file_size)
+	git_oid *id, git_odb *odb, const char *path, git_object_size_t file_size)
 {
 	int fd, error;
 	char buffer[FILEIO_BUFSIZE];
 	git_odb_stream *stream = NULL;
 	ssize_t read_len = -1;
-	git_off_t written = 0;
+	git_object_size_t written = 0;
 
 	if ((error = git_odb_open_wstream(
 			&stream, odb, file_size, GIT_OBJECT_BLOB)) < 0)
@@ -129,7 +129,7 @@ static int write_file_stream(
 
 static int write_file_filtered(
 	git_oid *id,
-	git_off_t *size,
+	git_object_size_t *size,
 	git_odb *odb,
 	const char *full_path,
 	git_filter_list *fl)
@@ -184,7 +184,7 @@ int git_blob__create_from_paths(
 	int error;
 	struct stat st;
 	git_odb *odb = NULL;
-	git_off_t size;
+	git_object_size_t size;
 	mode_t mode;
 	git_buf path = GIT_BUF_INIT;
 
@@ -389,7 +389,7 @@ cleanup:
 int git_blob_is_binary(const git_blob *blob)
 {
 	git_buf content = GIT_BUF_INIT;
-	git_off_t size;
+	git_object_size_t size;
 
 	assert(blob);
 
diff --git a/src/blob.h b/src/blob.h
index 0d743ec..e577099 100644
--- a/src/blob.h
+++ b/src/blob.h
@@ -21,7 +21,7 @@ struct git_blob {
 		git_odb_object *odb;
 		struct {
 			const char *data;
-			git_off_t size;
+			git_object_size_t size;
 		} raw;
 	} data;
 	unsigned int raw:1;
diff --git a/src/crlf.c b/src/crlf.c
index edccc0a..81b5216 100644
--- a/src/crlf.c
+++ b/src/crlf.c
@@ -78,7 +78,7 @@ static int has_cr_in_index(const git_filter_source *src)
 	const git_index_entry *entry;
 	git_blob *blob;
 	const void *blobcontent;
-	git_off_t blobsize;
+	git_object_size_t blobsize;
 	bool found_cr;
 
 	if (!path)
diff --git a/src/diff_file.c b/src/diff_file.c
index 978d7ea..4496832 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -62,7 +62,7 @@ static int diff_file_content_init_common(
 	git_diff_driver_update_options(&fc->opts_flags, fc->driver);
 
 	/* make sure file is conceivable mmap-able */
-	if ((git_off_t)((size_t)fc->file->size) != fc->file->size)
+	if ((size_t)fc->file->size != fc->file->size)
 		fc->file->flags |= GIT_DIFF_FLAG_BINARY;
 	/* check if user is forcing text diff the file */
 	else if (fc->opts_flags & GIT_DIFF_FORCE_TEXT) {
diff --git a/src/diff_file.h b/src/diff_file.h
index 5da7a7b..9354912 100644
--- a/src/diff_file.h
+++ b/src/diff_file.h
@@ -20,7 +20,7 @@ typedef struct {
 	git_diff_driver *driver;
 	uint32_t flags;
 	uint32_t opts_flags;
-	git_off_t opts_max_size;
+	git_object_size_t opts_max_size;
 	git_iterator_type_t src;
 	const git_blob *blob;
 	git_map map;
diff --git a/src/diff_generate.c b/src/diff_generate.c
index 7ec24d5..bd0b71c 100644
--- a/src/diff_generate.c
+++ b/src/diff_generate.c
@@ -560,11 +560,11 @@ int git_diff__oid_for_file(
 	git_diff *diff,
 	const char *path,
 	uint16_t mode,
-	git_off_t size)
+	git_object_size_t size)
 {
 	git_index_entry entry;
 
-	if (size < 0 || size > UINT32_MAX) {
+	if (size > UINT32_MAX) {
 		git_error_set(GIT_ERROR_NOMEMORY, "file size overflow (for 32-bits) on '%s'", path);
 		return -1;
 	}
diff --git a/src/diff_generate.h b/src/diff_generate.h
index 6e669a3..5186d55 100644
--- a/src/diff_generate.h
+++ b/src/diff_generate.h
@@ -88,7 +88,7 @@ extern int git_diff__oid_for_file(
 	git_diff *diff,
 	const char *path,
 	uint16_t mode,
-	git_off_t size);
+	git_object_size_t size);
 
 extern int git_diff__oid_for_entry(
 	git_oid *out,
@@ -120,7 +120,7 @@ GIT_INLINE(int) git_diff_file__resolve_zero_size(
 	git_odb_free(odb);
 
 	if (!error)
-		file->size = (git_off_t)len;
+		file->size = (git_object_size_t)len;
 
 	return error;
 }
diff --git a/src/diff_stats.c b/src/diff_stats.c
index a068171..19c9da0 100644
--- a/src/diff_stats.c
+++ b/src/diff_stats.c
@@ -55,7 +55,7 @@ int git_diff_file_stats__full_to_buf(
 {
 	const char *old_path = NULL, *new_path = NULL;
 	size_t padding;
-	git_off_t old_size, new_size;
+	git_object_size_t old_size, new_size;
 
 	old_path = delta->old_file.path;
 	new_path = delta->new_file.path;
diff --git a/src/diff_tform.c b/src/diff_tform.c
index fc60121..70bbb00 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -510,7 +510,7 @@ static int similarity_sig(
 			if (file->size != git_blob_rawsize(info->blob))
 				file->size = git_blob_rawsize(info->blob);
 
-			sz = (size_t)(git__is_sizet(file->size) ? file->size : -1);
+			sz = git__is_sizet(file->size) ? (size_t)file->size : (size_t)-1;
 
 			error = opts->metric->buffer_signature(
 				&cache[info->idx], info->file,
diff --git a/src/filter.c b/src/filter.c
index 7b7e7f1..bb9d66a 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -764,7 +764,7 @@ int git_filter_list_apply_to_file(
 
 static int buf_from_blob(git_buf *out, git_blob *blob)
 {
-	git_off_t rawsize = git_blob_rawsize(blob);
+	git_object_size_t rawsize = git_blob_rawsize(blob);
 
 	if (!git__is_sizet(rawsize)) {
 		git_error_set(GIT_ERROR_OS, "blob is too large to filter");
diff --git a/src/merge.c b/src/merge.c
index b72b384..05a776e 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -1024,7 +1024,7 @@ static int index_entry_similarity_calc(
 {
 	git_blob *blob;
 	git_diff_file diff_file = {{{0}}};
-	git_off_t blobsize;
+	git_object_size_t blobsize;
 	int error;
 
 	*out = NULL;
diff --git a/src/notes.c b/src/notes.c
index 5028107..4633a16 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -320,7 +320,7 @@ static int note_new(
 	git_blob *blob)
 {
 	git_note *note = NULL;
-	git_off_t blobsize;
+	git_object_size_t blobsize;
 
 	note = git__malloc(sizeof(git_note));
 	GIT_ERROR_CHECK_ALLOC(note);
diff --git a/src/object.h b/src/object.h
index 227a6fd..4b67936 100644
--- a/src/object.h
+++ b/src/object.h
@@ -11,6 +11,8 @@
 
 #include "repository.h"
 
+#define GIT_OBJECT_SIZE_MAX UINT64_MAX
+
 extern bool git_object__strict_input_validation;
 
 /** Base git object for inheritance */
diff --git a/src/reader.c b/src/reader.c
index 2d87251..90f700a 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -32,7 +32,7 @@ static int tree_reader_read(
 	tree_reader *reader = (tree_reader *)_reader;
 	git_tree_entry *tree_entry = NULL;
 	git_blob *blob = NULL;
-	git_off_t blobsize;
+	git_object_size_t blobsize;
 	int error;
 
 	if ((error = git_tree_entry_bypath(&tree_entry, reader->tree, filename)) < 0 ||