Commit dff05bc3 by Sven Strickroth

Multiline config values not preserved on saving

(fixes issue #6088)

Signed-off-by: Sven Strickroth <email@cs-ware.de>
parent 854164a5
...@@ -325,7 +325,7 @@ done: ...@@ -325,7 +325,7 @@ done:
return 0; return 0;
} }
static int parse_multiline_variable(git_config_parser *reader, git_str *value, int in_quotes) static int parse_multiline_variable(git_config_parser *reader, git_str *value, int in_quotes, size_t *line_len)
{ {
int quote_count; int quote_count;
bool multiline = true; bool multiline = true;
...@@ -338,6 +338,10 @@ static int parse_multiline_variable(git_config_parser *reader, git_str *value, i ...@@ -338,6 +338,10 @@ static int parse_multiline_variable(git_config_parser *reader, git_str *value, i
git_parse_advance_line(&reader->ctx); git_parse_advance_line(&reader->ctx);
line = git__strndup(reader->ctx.line, reader->ctx.line_len); line = git__strndup(reader->ctx.line, reader->ctx.line_len);
GIT_ERROR_CHECK_ALLOC(line); GIT_ERROR_CHECK_ALLOC(line);
if (GIT_ADD_SIZET_OVERFLOW(line_len, *line_len, reader->ctx.line_len)) {
error = -1;
goto out;
}
/* /*
* We've reached the end of the file, there is no continuation. * We've reached the end of the file, there is no continuation.
...@@ -415,7 +419,7 @@ static int parse_name( ...@@ -415,7 +419,7 @@ static int parse_name(
return 0; return 0;
} }
static int parse_variable(git_config_parser *reader, char **var_name, char **var_value) static int parse_variable(git_config_parser *reader, char **var_name, char **var_value, size_t *line_len)
{ {
const char *value_start = NULL; const char *value_start = NULL;
char *line = NULL, *name = NULL, *value = NULL; char *line = NULL, *name = NULL, *value = NULL;
...@@ -449,7 +453,7 @@ static int parse_variable(git_config_parser *reader, char **var_name, char **var ...@@ -449,7 +453,7 @@ static int parse_variable(git_config_parser *reader, char **var_name, char **var
git_str_attach(&multi_value, value, 0); git_str_attach(&multi_value, value, 0);
value = NULL; value = NULL;
if (parse_multiline_variable(reader, &multi_value, quote_count % 2) < 0 || if (parse_multiline_variable(reader, &multi_value, quote_count % 2, line_len) < 0 ||
git_str_oom(&multi_value)) { git_str_oom(&multi_value)) {
error = -1; error = -1;
git_str_dispose(&multi_value); git_str_dispose(&multi_value);
...@@ -554,7 +558,7 @@ int git_config_parse( ...@@ -554,7 +558,7 @@ int git_config_parse(
break; break;
default: /* assume variable declaration */ default: /* assume variable declaration */
if ((result = parse_variable(parser, &var_name, &var_value)) == 0 && on_variable) { if ((result = parse_variable(parser, &var_name, &var_value, &line_len)) == 0 && on_variable) {
result = on_variable(parser, current_section, var_name, var_value, line_start, line_len, payload); result = on_variable(parser, current_section, var_name, var_value, line_start, line_len, payload);
git__free(var_name); git__free(var_name);
git__free(var_value); git__free(var_value);
......
...@@ -8,6 +8,7 @@ void test_config_write__initialize(void) ...@@ -8,6 +8,7 @@ void test_config_write__initialize(void)
cl_fixture_sandbox("config/config9"); cl_fixture_sandbox("config/config9");
cl_fixture_sandbox("config/config15"); cl_fixture_sandbox("config/config15");
cl_fixture_sandbox("config/config17"); cl_fixture_sandbox("config/config17");
cl_fixture_sandbox("config/config22");
} }
void test_config_write__cleanup(void) void test_config_write__cleanup(void)
...@@ -15,6 +16,7 @@ void test_config_write__cleanup(void) ...@@ -15,6 +16,7 @@ void test_config_write__cleanup(void)
cl_fixture_cleanup("config9"); cl_fixture_cleanup("config9");
cl_fixture_cleanup("config15"); cl_fixture_cleanup("config15");
cl_fixture_cleanup("config17"); cl_fixture_cleanup("config17");
cl_fixture_cleanup("config22");
} }
void test_config_write__replace_value(void) void test_config_write__replace_value(void)
...@@ -743,3 +745,20 @@ void test_config_write__preserve_case(void) ...@@ -743,3 +745,20 @@ void test_config_write__preserve_case(void)
git_config_free(cfg); git_config_free(cfg);
} }
void test_config_write__write_config_file_with_multi_line_value(void)
{
git_config* cfg;
git_buf buf = GIT_BUF_INIT;
cl_git_pass(git_config_open_ondisk(&cfg, "config22"));
cl_git_pass(git_config_get_string_buf(&buf, cfg, "alias.m"));
cl_assert_equal_s("cmd ;; ;; bar", buf.ptr);
cl_git_pass(git_config_set_string(cfg, "sOMe.ThInG", "foo"));
git_buf_dispose(&buf);
cl_git_pass(git_config_get_string_buf(&buf, cfg, "alias.m"));
cl_assert_equal_s("cmd ;; ;; bar", buf.ptr);
git_buf_dispose(&buf);
git_config_free(cfg);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment