From 566dd8cec06e511490c6473d2440c39ff1b2851c Mon Sep 17 00:00:00 2001 From: Linquize Date: Mon, 30 Sep 2013 23:38:22 +0800 Subject: [PATCH 1/3] Config subsection name should allow to have ']' and '\\' should allow to escape any characters --- src/config_file.c | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index 1a845d8ba..8fb43b990 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -712,7 +712,6 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con int c, rpos; char *first_quote, *last_quote; git_buf buf = GIT_BUF_INIT; - int quote_marks; /* * base_name is what came before the space. We should be at the * first quotation mark, except for now, line isn't being kept in @@ -731,21 +730,15 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con git_buf_printf(&buf, "%s.", base_name); rpos = 0; - quote_marks = 0; line = first_quote; - c = line[rpos++]; + c = line[++rpos]; /* * At the end of each iteration, whatever is stored in c will be * added to the string. In case of error, jump to out */ do { - if (quote_marks == 2) { - set_parse_error(reader, rpos, "Unexpected text after closing quotes"); - git_buf_free(&buf); - return -1; - } switch (c) { case 0: @@ -754,25 +747,13 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con return -1; case '"': - ++quote_marks; - continue; + goto end_parse; case '\\': - c = line[rpos++]; + c = line[++rpos]; - switch (c) { - case '"': - if (&line[rpos-1] == last_quote) { - set_parse_error(reader, 0, "Missing closing quotation mark in section header"); - git_buf_free(&buf); - return -1; - } - - case '\\': - break; - - default: - set_parse_error(reader, rpos, "Unsupported escape sequence"); + if (c == 0) { + set_parse_error(reader, rpos, "Unexpected end-of-line in section header"); git_buf_free(&buf); return -1; } @@ -782,7 +763,15 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con } git_buf_putc(&buf, (char)c); - } while ((c = line[rpos++]) != ']'); + c = line[++rpos]; + } while (line + rpos < last_quote); + +end_parse: + if (line[rpos] != '"' || line[rpos + 1] != ']') { + set_parse_error(reader, rpos, "Unexpected text after closing quotes"); + git_buf_free(&buf); + return -1; + } *section_name = git_buf_detach(&buf); return 0; @@ -800,7 +789,7 @@ static int parse_section_header(struct reader *reader, char **section_out) return -1; /* find the end of the variable's name */ - name_end = strchr(line, ']'); + name_end = strrchr(line, ']'); if (name_end == NULL) { git__free(line); set_parse_error(reader, 0, "Missing ']' in section header"); From d52a93fab330dbbe1271c10b527d333261638fe3 Mon Sep 17 00:00:00 2001 From: Linquize Date: Mon, 30 Sep 2013 23:58:58 +0800 Subject: [PATCH 2/3] Add test case to test ']' and '\\' characters in config subsection --- tests-clar/config/read.c | 7 +++++++ tests-clar/resources/config/config20 | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests-clar/resources/config/config20 diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c index 722a15a71..ab068eaa7 100644 --- a/tests-clar/config/read.c +++ b/tests-clar/config/read.c @@ -164,6 +164,13 @@ void test_config_read__empty_files(void) git_config_free(cfg); } +void test_config_read__symbol_headers(void) +{ + git_config *cfg; + cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config20"))); + git_config_free(cfg); +} + void test_config_read__header_in_last_line(void) { git_config *cfg; diff --git a/tests-clar/resources/config/config20 b/tests-clar/resources/config/config20 new file mode 100644 index 000000000..8f0f12c4c --- /dev/null +++ b/tests-clar/resources/config/config20 @@ -0,0 +1,11 @@ +[valid "[subsection]"] + something = a +; we don't allow anything after closing " +[sec "[subsec]/child"] + parent = grand +[sec2 "[subsec2]/child2"] + type = dvcs +[sec3 "escape\"quote"] + vcs = git +[sec4 "escaping\\slash"] + lib = git2 From 8d741253849c5e377e50490818326adc56be9fce Mon Sep 17 00:00:00 2001 From: Linquize Date: Tue, 1 Oct 2013 09:46:56 +0800 Subject: [PATCH 3/3] Add negative test cases for config header with invalid characters --- tests-clar/config/read.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests-clar/config/read.c b/tests-clar/config/read.c index ab068eaa7..abc088d59 100644 --- a/tests-clar/config/read.c +++ b/tests-clar/config/read.c @@ -531,6 +531,28 @@ void test_config_read__corrupt_header(void) git_config_free(cfg); } +void test_config_read__corrupt_header2(void) +{ + git_config *cfg; + + cl_set_cleanup(&clean_test_config, NULL); + cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n lib = git2\n"); + cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig")); + + git_config_free(cfg); +} + +void test_config_read__corrupt_header3(void) +{ + git_config *cfg; + + cl_set_cleanup(&clean_test_config, NULL); + cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n lib = git2\n"); + cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig")); + + git_config_free(cfg); +} + void test_config_read__override_variable(void) { git_config *cfg;