Commit 2d9f5b9f13107a4f59ea1c055620efeb603f2bab

Edward Thomson 2013-08-07T11:11:55

Parse config headers with quoted quotes Parse config headers that have the last quote on the line quoted instead of walking off the end.

diff --git a/src/config_file.c b/src/config_file.c
index 2b0732a..570f286 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -792,6 +792,11 @@ static int parse_section_header_ext(diskfile_backend *cfg, const char *line, con
 		}
 
 		switch (c) {
+		case 0:
+			set_parse_error(cfg, 0, "Unexpected end-of-line in section header");
+			git_buf_free(&buf);
+			return -1;
+
 		case '"':
 			++quote_marks;
 			continue;
@@ -801,6 +806,12 @@ static int parse_section_header_ext(diskfile_backend *cfg, const char *line, con
 
 			switch (c) {
 			case '"':
+				if (&line[rpos-1] == last_quote) {
+					set_parse_error(cfg, 0, "Missing closing quotation mark in section header");
+					git_buf_free(&buf);
+					return -1;
+				}
+
 			case '\\':
 				break;
 
diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c
index 9f943d0..a18dca8 100644
--- a/tests-clar/config/read.c
+++ b/tests-clar/config/read.c
@@ -431,10 +431,10 @@ void test_config_read__simple_read_from_specific_level(void)
 	git_config_free(cfg);
 }
 
-static void clean_empty_config(void *unused)
+static void clean_test_config(void *unused)
 {
 	GIT_UNUSED(unused);
-	cl_fixture_cleanup("./empty");
+	cl_fixture_cleanup("./testconfig");
 }
 
 void test_config_read__can_load_and_parse_an_empty_config_file(void)
@@ -442,10 +442,21 @@ void test_config_read__can_load_and_parse_an_empty_config_file(void)
 	git_config *cfg;
 	int i;
 
-	cl_set_cleanup(&clean_empty_config, NULL);
-	cl_git_mkfile("./empty", "");
-	cl_git_pass(git_config_open_ondisk(&cfg, "./empty"));
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "");
+	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
 	cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither"));
 
 	git_config_free(cfg);
 }
+
+void test_config_read__corrupt_header(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	git_config_free(cfg);
+}