Commit cce548e3e0c14b5d46c8d886c9954f4b66533ecd

Russell Belfer 2013-01-22T15:28:25

Fix case sensitivity bug with tree iterators With the new code to make tree iterators support ignore_case, there is a bug in setting the start entry for range bounded iterators where memcmp was being used instead of strncasecmp. This fixes that and expands the tree iterator test to cover the cases that were broken.

diff --git a/src/iterator.c b/src/iterator.c
index 56b2629..1c36cac 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -255,15 +255,17 @@ static int tree_iterator__icase_map_cmp(const void *a, const void *b, void *data
 	git_tree *tree = data;
 	const git_tree_entry *te1 = git_tree_entry_byindex(tree, (size_t)a);
 	const git_tree_entry *te2 = git_tree_entry_byindex(tree, (size_t)b);
+
 	return te1 ? (te2 ? git_tree_entry_icmp(te1, te2) : 1) : -1;
 }
 
-static int tree_iterator__frame_start_icmp(const void *key, const void *element)
+static int tree_iterator__frame_start_icmp(const void *key, const void *el)
 {
 	const tree_iterator_frame *tf = (const tree_iterator_frame *)key;
-	const git_tree_entry *te = git_tree_entry_byindex(tf->tree, (size_t)element);
+	const git_tree_entry *te = git_tree_entry_byindex(tf->tree, (size_t)el);
+	size_t minlen = min(tf->startlen, te->filename_len);
 
-	return memcmp(tf->start, te->filename, min(tf->startlen, te->filename_len));
+	return git__strncasecmp(tf->start, te->filename, minlen);
 }
 
 static void tree_iterator__frame_seek_start(tree_iterator_frame *tf)
diff --git a/tests-clar/diff/iterator.c b/tests-clar/diff/iterator.c
index 566503b..efdadbf 100644
--- a/tests-clar/diff/iterator.c
+++ b/tests-clar/diff/iterator.c
@@ -843,8 +843,22 @@ void test_diff_iterator__tree_handles_icase_range(void)
 
 	check_tree_range(repo, "B", "C", false, 0);
 	check_tree_range(repo, "B", "C", true, 1);
+	check_tree_range(repo, "b", "c", false, 1);
+	check_tree_range(repo, "b", "c", true, 1);
+
 	check_tree_range(repo, "a", "z", false, 3);
 	check_tree_range(repo, "a", "z", true, 4);
+	check_tree_range(repo, "A", "Z", false, 1);
+	check_tree_range(repo, "A", "Z", true, 4);
+	check_tree_range(repo, "a", "Z", false, 0);
+	check_tree_range(repo, "a", "Z", true, 4);
+	check_tree_range(repo, "A", "z", false, 4);
+	check_tree_range(repo, "A", "z", true, 4);
+
+	check_tree_range(repo, "new.txt", "new.txt", true, 1);
+	check_tree_range(repo, "new.txt", "new.txt", false, 1);
+	check_tree_range(repo, "README", "README", true, 1);
+	check_tree_range(repo, "README", "README", false, 1);
 }
 
 static void check_index_range(