diff --git a/src/config_file.c b/src/config_file.c index 533a92bdd..350473434 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 f20a3769f..a19bc7dcb 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) {