Commit e009a7059d69173113122eb2d28de8a03083b201

Edward Thomson 2015-04-20T00:22:20

config_file: comment char can be invalid escape Don't assume that comment chars are comment chars, they may be (an attempt to be escaped). If so, \; is not a valid escape sequence, complain.

diff --git a/src/config_file.c b/src/config_file.c
index 533a92b..3504734 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -1162,17 +1162,24 @@ static int skip_bom(struct reader *reader)
 
 static int strip_comments(char *line, int in_quotes)
 {
-	int quote_count = in_quotes;
+	int quote_count = in_quotes, backslash_count = 0;
 	char *ptr;
 
 	for (ptr = line; *ptr; ++ptr) {
 		if (ptr[0] == '"' && ptr > line && ptr[-1] != '\\')
 			quote_count++;
 
-		if ((ptr[0] == ';' || ptr[0] == '#') && (quote_count % 2) == 0) {
+		if ((ptr[0] == ';' || ptr[0] == '#') &&
+			(quote_count % 2) == 0 &&
+			(backslash_count % 2) == 0) {
 			ptr[0] = '\0';
 			break;
 		}
+
+		if (ptr[0] == '\\')
+			backslash_count++;
+		else
+			backslash_count = 0;
 	}
 
 	/* skip any space at the end */
@@ -1698,6 +1705,7 @@ static int parse_multiline_variable(struct reader *reader, git_buf *value, int i
 		return -1;
 	}
 	/* add this line to the multiline var */
+
 	git_buf_puts(value, proc_line);
 	git__free(line);
 	git__free(proc_line);
diff --git a/tests/config/read.c b/tests/config/read.c
index f20a376..a19bc7d 100644
--- a/tests/config/read.c
+++ b/tests/config/read.c
@@ -247,6 +247,17 @@ void test_config_read__escaping_quotes(void)
 	git_config_free(cfg);
 }
 
+void test_config_read__invalid_escape_sequence(void)
+{
+	git_config *cfg;
+
+	cl_set_cleanup(&clean_test_config, NULL);
+	cl_git_mkfile("./testconfig", "[header]\n  key1 = \\\\\\;\n  key2 = value2\n");
+	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));
+
+	git_config_free(cfg);
+}
+
 static int count_cfg_entries_and_compare_levels(
 	const git_config_entry *entry, void *payload)
 {