Commit bdc82e1c00776229b19688abaf08d6701f2dc41f

Carlos Martín Nieto 2014-04-24T14:08:29

fetchhead: deal with quotes in branch names The current FETCH_HEAD parsing code assumes that a quote must end the branch name. Git however allows for quotes as part of a branch name, which causes us to consider the FETCH_HEAD file as invalid. Instead of searching for a single quote char, search for a quote char followed by SP, which is not a valid part of a ref name.

diff --git a/src/fetchhead.c b/src/fetchhead.c
index 4435454..a95ea4c 100644
--- a/src/fetchhead.c
+++ b/src/fetchhead.c
@@ -210,7 +210,7 @@ static int fetchhead_ref_parse(
 			name = desc + 1;
 
 		if (name) {
-			if ((desc = strchr(name, '\'')) == NULL ||
+			if ((desc = strstr(name, "' ")) == NULL ||
 				git__prefixcmp(desc, "' of ") != 0) {
 				giterr_set(GITERR_FETCHHEAD,
 					"Invalid description in FETCH_HEAD line %d", line_num);
diff --git a/tests/fetchhead/fetchhead_data.h b/tests/fetchhead/fetchhead_data.h
index 34adb3d..94402ab 100644
--- a/tests/fetchhead/fetchhead_data.h
+++ b/tests/fetchhead/fetchhead_data.h
@@ -28,3 +28,6 @@
 
 #define FETCH_HEAD_EXPLICIT_DATA \
 	"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first-merge' of git://github.com/libgit2/TestGitRepository\n"
+
+#define FETCH_HEAD_QUOTE_DATA \
+	"0966a434eb1a025db6b71485ab63a3bfbea520b6\t\tbranch 'first's-merge' of git://github.com/libgit2/TestGitRepository\n"
diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c
index d8c70e8..e7ff2ca 100644
--- a/tests/fetchhead/nonetwork.c
+++ b/tests/fetchhead/nonetwork.c
@@ -343,3 +343,12 @@ void test_fetchhead_nonetwork__unborn_with_upstream(void)
 	git_repository_free(repo);
 	cl_fixture_cleanup("./repowithunborn");
 }
+
+void test_fetchhead_nonetwork__quote_in_branch_name(void)
+{
+	cl_set_cleanup(&cleanup_repository, "./test1");
+	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));
+
+	cl_git_rewritefile("./test1/.git/FETCH_HEAD", FETCH_HEAD_QUOTE_DATA);
+	cl_git_pass(git_repository_fetchhead_foreach(g_repo, read_noop, NULL));
+}