Commit 3e6533ba12c1c567f91efe621bdd155ff801877c

Edward Thomson 2017-12-10T17:25:00

odb_loose: reject objects that cannot fit in memory Check the size of objects being read from the loose odb backend and reject those that would not fit in memory with an error message that reflects the actual problem, instead of error'ing later with an unintuitive error message regarding truncation or invalid hashes.

diff --git a/src/odb_loose.c b/src/odb_loose.c
index 2294931..9900aae 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -156,6 +156,11 @@ static int parse_header(
 		size < 0)
 		goto on_error;
 
+	if ((uint64_t)size > SIZE_MAX) {
+		giterr_set(GITERR_OBJECT, "object is larger than available memory");
+		return -1;
+	}
+
 	out->size = size;
 
 	if (GIT_ADD_SIZET_OVERFLOW(out_len, i, 1))
diff --git a/tests/odb/largefiles.c b/tests/odb/largefiles.c
index 9a91cf1..dc987c4 100644
--- a/tests/odb/largefiles.c
+++ b/tests/odb/largefiles.c
@@ -93,3 +93,24 @@ void test_odb_largefiles__read_into_memory(void)
 
 	git_odb_object_free(obj);
 }
+
+void test_odb_largefiles__read_into_memory_rejected_on_32bit(void)
+{
+	git_oid oid;
+	git_odb_object *obj = NULL;
+
+#ifdef GIT_ARCH_64
+	cl_skip();
+#endif
+
+	if (!cl_is_env_set("GITTEST_INVASIVE_FS_SIZE"))
+		cl_skip();
+
+	if (!cl_is_env_set("GITTEST_INVASIVE_MEMORY"))
+		cl_skip();
+
+	writefile(&oid);
+	cl_git_fail(git_odb_read(&obj, odb, &oid));
+
+	git_odb_object_free(obj);
+}