From fde93250320f97cd6cf93be1e4ab09fd330e001f Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 7 Nov 2013 13:17:36 +0100 Subject: [PATCH 1/4] Correctly quote config values while saving If the value contains a command (; or #) char or starts or ends with space it needs to be quoted. Signed-off-by: Sven Strickroth --- src/config_file.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index c7fc32060..1e58e3a7a 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -1178,6 +1178,22 @@ static int write_section(git_filebuf *file, const char *key) return result; } +static int needsQuote(const char *value) +{ + const char *ptr = value; + if (*value == ' ') + return 1; + while (*ptr) { + if (*ptr == ';' || *ptr == '#') + return 1; + ++ptr; + } + if (ptr != value && *(--ptr) == ' ') + return 1; + + return 0; +} + /* * This is pretty much the parsing, except we write out anything we don't have */ @@ -1299,7 +1315,10 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p /* Then replace the variable. If the value is NULL, it * means we want to delete it, so don't write anything. */ if (value != NULL) { - git_filebuf_printf(&file, "\t%s = %s\n", name, value); + if (needsQuote(value)) + git_filebuf_printf(&file, "\t%s = \"%s\"\n", name, value); + else + git_filebuf_printf(&file, "\t%s = %s\n", name, value); } /* @@ -1359,7 +1378,10 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p if (reader->buffer.size > 0 && *(reader->buffer.ptr + reader->buffer.size - 1) != '\n') git_filebuf_write(&file, "\n", 1); - git_filebuf_printf(&file, "\t%s = %s\n", name, value); + if (needsQuote(value)) + git_filebuf_printf(&file, "\t%s = \"%s\"\n", name, value); + else + git_filebuf_printf(&file, "\t%s = %s\n", name, value); } } From a9f7236affefc9918a8d3f2511fc4e5345d69942 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 7 Nov 2013 13:38:04 +0100 Subject: [PATCH 2/4] Add a testcase for values which needs quotes Signed-off-by: Sven Strickroth --- tests-clar/config/write.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests-clar/config/write.c b/tests-clar/config/write.c index 57b02a7d9..c93c08a1a 100644 --- a/tests-clar/config/write.c +++ b/tests-clar/config/write.c @@ -229,6 +229,33 @@ void test_config_write__add_value_at_file_with_no_clrf_at_the_end(void) git_config_free(cfg); } +void test_config_write__add_value_which_needs_quotes(void) +{ + git_config *cfg; + const char* str1; + const char* str2; + const char* str3; + const char* str4; + + cl_git_pass(git_config_open_ondisk(&cfg, "config17")); + cl_git_pass(git_config_set_string(cfg, "core.startwithspace", " Something")); + cl_git_pass(git_config_set_string(cfg, "core.endwithspace", "Something ")); + cl_git_pass(git_config_set_string(cfg, "core.containscommentchar1", "some#thing")); + cl_git_pass(git_config_set_string(cfg, "core.containscommentchar2", "some;thing")); + git_config_free(cfg); + + cl_git_pass(git_config_open_ondisk(&cfg, "config17")); + cl_git_pass(git_config_get_string(&str1, cfg, "core.startwithspace")); + cl_assert_equal_s(" Something", str1); + cl_git_pass(git_config_get_string(&str2, cfg, "core.endwithspace")); + cl_assert_equal_s("Something ", str2); + cl_git_pass(git_config_get_string(&str3, cfg, "core.containscommentchar1")); + cl_assert_equal_s("some#thing", str3); + cl_git_pass(git_config_get_string(&str4, cfg, "core.containscommentchar2")); + cl_assert_equal_s("some;thing", str4); + git_config_free(cfg); +} + void test_config_write__can_set_a_value_to_NULL(void) { git_repository *repository; From 7dd28dde284276a09e74f66b22fe0173573d3ca7 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 7 Nov 2013 15:39:15 +0100 Subject: [PATCH 3/4] Add another testcase to make sure double quotes are correctly escaped Signed-off-by: Sven Strickroth --- tests-clar/config/write.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests-clar/config/write.c b/tests-clar/config/write.c index c93c08a1a..4b217c50b 100644 --- a/tests-clar/config/write.c +++ b/tests-clar/config/write.c @@ -236,12 +236,14 @@ void test_config_write__add_value_which_needs_quotes(void) const char* str2; const char* str3; const char* str4; + const char* str5; cl_git_pass(git_config_open_ondisk(&cfg, "config17")); cl_git_pass(git_config_set_string(cfg, "core.startwithspace", " Something")); cl_git_pass(git_config_set_string(cfg, "core.endwithspace", "Something ")); cl_git_pass(git_config_set_string(cfg, "core.containscommentchar1", "some#thing")); cl_git_pass(git_config_set_string(cfg, "core.containscommentchar2", "some;thing")); + cl_git_pass(git_config_set_string(cfg, "core.startwhithsapceandcontainsdoublequote", " some\"thing")); git_config_free(cfg); cl_git_pass(git_config_open_ondisk(&cfg, "config17")); @@ -253,6 +255,8 @@ void test_config_write__add_value_which_needs_quotes(void) cl_assert_equal_s("some#thing", str3); cl_git_pass(git_config_get_string(&str4, cfg, "core.containscommentchar2")); cl_assert_equal_s("some;thing", str4); + cl_git_pass(git_config_get_string(&str5, cfg, "core.startwhithsapceandcontainsdoublequote")); + cl_assert_equal_s(" some\"thing", str5); git_config_free(cfg); } From 590c5efb3bab80b3e52cf68b705ef461d7388874 Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Thu, 7 Nov 2013 17:51:43 +0100 Subject: [PATCH 4/4] Rename method Signed-off-by: Sven Strickroth --- src/config_file.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config_file.c b/src/config_file.c index 1e58e3a7a..66a8c155b 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -1178,7 +1178,7 @@ static int write_section(git_filebuf *file, const char *key) return result; } -static int needsQuote(const char *value) +static int value_needs_surrounding_quote(const char *value) { const char *ptr = value; if (*value == ' ') @@ -1315,7 +1315,7 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p /* Then replace the variable. If the value is NULL, it * means we want to delete it, so don't write anything. */ if (value != NULL) { - if (needsQuote(value)) + if (value_needs_surrounding_quote(value)) git_filebuf_printf(&file, "\t%s = \"%s\"\n", name, value); else git_filebuf_printf(&file, "\t%s = %s\n", name, value); @@ -1378,7 +1378,7 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p if (reader->buffer.size > 0 && *(reader->buffer.ptr + reader->buffer.size - 1) != '\n') git_filebuf_write(&file, "\n", 1); - if (needsQuote(value)) + if (value_needs_surrounding_quote(value)) git_filebuf_printf(&file, "\t%s = \"%s\"\n", name, value); else git_filebuf_printf(&file, "\t%s = %s\n", name, value);