Commit c4085fbf1d1a4ecd9b63d286364111450fa91ee1

Ben Straub 2013-05-23T07:31:05

Merge pull request #1601 from Merovius/bugfix_shorten Bugfix: Return NULL in push_leaf, when trie is full

diff --git a/src/oid.c b/src/oid.c
index e74640c..0b023dd 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -269,8 +269,10 @@ static trie_node *push_leaf(git_oid_shorten *os, node_index idx, int push_at, co
 
 	idx_leaf = (node_index)os->node_count++;
 
-	if (os->node_count == SHRT_MAX)
+	if (os->node_count == SHRT_MAX) {
 		os->full = 1;
+        return NULL;
+    }
 
 	node = &os->nodes[idx];
 	node->children[push_at] = -idx_leaf;
diff --git a/tests-clar/object/raw/short.c b/tests-clar/object/raw/short.c
index 93c79b6..b401993 100644
--- a/tests-clar/object/raw/short.c
+++ b/tests-clar/object/raw/short.c
@@ -92,3 +92,42 @@ void test_object_raw_short__oid_shortener_stresstest_git_oid_shorten(void)
 
 #undef MAX_OIDS
 }
+
+void test_object_raw_short__oid_shortener_too_much_oids(void) {
+    /* The magic number of oids at which an oid_shortener will fail.
+     * This was experimentally established. */
+#define MAX_OIDS 24556
+
+	git_oid_shorten *os;
+	char number_buffer[16];
+	git_oid oid;
+	size_t i;
+
+	int min_len = 0;
+
+	os = git_oid_shorten_new(0);
+	cl_assert(os != NULL);
+
+	for (i = 0; i < MAX_OIDS; ++i) {
+		char *oid_text;
+
+		p_snprintf(number_buffer, 16, "%u", (unsigned int)i);
+		git_hash_buf(&oid, number_buffer, strlen(number_buffer));
+
+		oid_text = git__malloc(GIT_OID_HEXSZ + 1);
+		git_oid_fmt(oid_text, &oid);
+		oid_text[GIT_OID_HEXSZ] = 0;
+
+		min_len = git_oid_shorten_add(os, oid_text);
+        /* All but the last oid should give a non-negative min_len. At the
+         * last oid, git_oid_shorten_add should fail, returning a negative
+         * value */
+        if (i < MAX_OIDS - 1)
+            cl_assert(min_len >= 0);
+        else
+            cl_assert(min_len < 0);
+	}
+
+	git_oid_shorten_free(os);
+
+}