diff --git a/src/config_file.c b/src/config_file.c index 0bd4e4ece..25ebd1c97 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 value_needs_surrounding_quote(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 */ @@ -1302,7 +1318,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 (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); } /* @@ -1362,7 +1381,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 (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); } } diff --git a/tests-clar/config/write.c b/tests-clar/config/write.c index 309fef65a..15f750dc0 100644 --- a/tests-clar/config/write.c +++ b/tests-clar/config/write.c @@ -229,6 +229,37 @@ 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; + 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")); + 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); + cl_git_pass(git_config_get_string(&str5, cfg, "core.startwhithsapceandcontainsdoublequote")); + cl_assert_equal_s(" some\"thing", str5); + git_config_free(cfg); +} + void test_config_write__can_set_a_value_to_NULL(void) { git_repository *repository;