Commit e1be10281647e9db93cc88c435c56abacdeb0af0

nulltoken 2011-02-13T20:18:35

Added some more tests to ensure the correct behavior of git_reference__normalize_name().

diff --git a/src/refs.c b/src/refs.c
index 46589e0..05c4e10 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -666,6 +666,7 @@ static int check_valid_ref_char(char ch)
 	case '\\':
 	case '?':
 	case '[':
+	case '*':
 		return GIT_ERROR;
 		break;
 
@@ -720,14 +721,8 @@ int git_reference__normalize_name(char *buffer_out, const char *name, git_rtype 
 			}
 		}
 
-		if (*current == '/') {
-			/* Slashes are not authorized in symbolic reference name */
-			if (type == GIT_REF_SYMBOLIC) {
-				return GIT_EINVALIDREFNAME;
-			}
-
+		if (*current == '/')
 			contains_a_slash = 1;
-		}
 
 		*buffer_out++ = *current++;
 	}
diff --git a/tests/t10-refs.c b/tests/t10-refs.c
index b53bcae..6dada0a 100644
--- a/tests/t10-refs.c
+++ b/tests/t10-refs.c
@@ -324,8 +324,8 @@ END_TEST
 
 BEGIN_TEST("normalizeref", normalize_symbolic_ref)
 	must_pass(ensure_refname_normalized(GIT_REF_SYMBOLIC, "a", "a"));
+	must_pass(ensure_refname_normalized(GIT_REF_SYMBOLIC, "a/b", "a/b"));
 	must_fail(ensure_refname_normalized(GIT_REF_SYMBOLIC, "", NULL));
-	must_fail(ensure_refname_normalized(GIT_REF_SYMBOLIC, "a/b", NULL));
 	must_fail(ensure_refname_normalized(GIT_REF_SYMBOLIC, "heads\foo", NULL));
 END_TEST
 
@@ -336,6 +336,131 @@ BEGIN_TEST("normalizeref", normalize_any_ref) /* Slash related rules do not appl
 	must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs///heads///a", "refs/heads/a"));
 END_TEST
 
+/* Ported from JGit, BSD licence. See https://github.com/spearce/JGit/commit/e4bf8f6957bbb29362575d641d1e77a02d906739 */
+BEGIN_TEST("normalizeref", jgit_tests)
+
+		/* EmptyString */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "/", NULL));
+
+		/* MustHaveTwoComponents */
+			must_fail(ensure_refname_normalized(GIT_REF_OID, "master", NULL));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "heads/master", "heads/master"));
+
+		/* ValidHead */
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master", "refs/heads/master"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/pu", "refs/heads/pu"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/z", "refs/heads/z"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/FoO", "refs/heads/FoO"));
+
+		/* ValidTag */
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/tags/v1.0", "refs/tags/v1.0"));
+
+		/* NoLockSuffix */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master.lock", NULL));
+
+		/* NoDirectorySuffix */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master/", NULL));
+
+		/* NoSpace */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/i haz space", NULL));
+
+		/* NoAsciiControlCharacters */
+			{
+				char c;
+				char buffer[MAX_GITDIR_TREE_STRUCTURE_PATH_LENGTH];
+				for (c = '\1'; c < ' '; c++) {
+					strncpy(buffer, "refs/heads/mast", 15);
+					strncpy(buffer + 15, (const char *)&c, 1);
+					strncpy(buffer + 16, "er", 2);
+					buffer[18 - 1] = '\0';
+					must_fail(ensure_refname_normalized(GIT_REF_ANY, buffer, NULL));
+				}
+			}
+
+		/* NoBareDot */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/.", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/..", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/./master", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/../master", NULL));
+
+		/* NoLeadingOrTrailingDot */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, ".", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/.bar", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/..bar", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/bar.", NULL));
+
+		/* ContainsDot */
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/m.a.s.t.e.r", "refs/heads/m.a.s.t.e.r"));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master..pu", NULL));
+
+		/* NoMagicRefCharacters */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master^", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/^master", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "^refs/heads/master", NULL));
+
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master~", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/~master", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "~refs/heads/master", NULL));
+
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master:", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/:master", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, ":refs/heads/master", NULL));
+
+		/* ShellGlob */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master?", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/?master", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "?refs/heads/master", NULL));
+
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master[", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/[master", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "[refs/heads/master", NULL));
+
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master*", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/*master", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "*refs/heads/master", NULL));
+
+		/* ValidSpecialCharacters */
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/!", "refs/heads/!"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/\"", "refs/heads/\""));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/#", "refs/heads/#"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/$", "refs/heads/$"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/%", "refs/heads/%"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/&", "refs/heads/&"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/'", "refs/heads/'"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/(", "refs/heads/("));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/)", "refs/heads/)"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/+", "refs/heads/+"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/,", "refs/heads/,"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/-", "refs/heads/-"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/;", "refs/heads/;"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/<", "refs/heads/<"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/=", "refs/heads/="));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/>", "refs/heads/>"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/@", "refs/heads/@"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/]", "refs/heads/]"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/_", "refs/heads/_"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/`", "refs/heads/`"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/{", "refs/heads/{"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/|", "refs/heads/|"));
+			must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/}", "refs/heads/}"));
+
+			// This is valid on UNIX, but not on Windows
+			// hence we make in invalid due to non-portability
+			//
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/\\", NULL));
+
+		/* UnicodeNames */
+			/*
+			 * Currently this fails.
+			 * must_pass(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/\u00e5ngstr\u00f6m", "refs/heads/\u00e5ngstr\u00f6m"));
+			 */
+
+		/* RefLogQueryIsValidRef */
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master@{1}", NULL));
+			must_fail(ensure_refname_normalized(GIT_REF_ANY, "refs/heads/master@{1.hour.ago}", NULL));
+END_TEST
+
 git_testsuite *libgit2_suite_refs(void)
 {
 	git_testsuite *suite = git_testsuite_new("References");
@@ -354,6 +479,7 @@ git_testsuite *libgit2_suite_refs(void)
 	ADD_TEST(suite, "normalizeref", normalize_object_id_ref);
 	ADD_TEST(suite, "normalizeref", normalize_symbolic_ref);
 	ADD_TEST(suite, "normalizeref", normalize_any_ref);
+	ADD_TEST(suite, "normalizeref", jgit_tests);
 
 	return suite;
 }