Skip to content

Commit 0a4284b

Browse files
authored
Merge pull request libgit2#4819 from libgit2/cmn/config-nonewline
Configuration variables can appear on the same line as the section header
2 parents f010b66 + 1d718fa commit 0a4284b

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

src/config_parse.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static int parse_section_header_ext(git_config_parser *reader, const char *line,
6363
{
6464
int c, rpos;
6565
char *first_quote, *last_quote;
66+
const char *line_start = line;
6667
git_buf buf = GIT_BUF_INIT;
6768
size_t quoted_len, alloc_len, base_name_len = strlen(base_name);
6869

@@ -139,7 +140,7 @@ static int parse_section_header_ext(git_config_parser *reader, const char *line,
139140
}
140141

141142
*section_name = git_buf_detach(&buf);
142-
return 0;
143+
return &line[rpos + 2] - line_start; /* rpos is at the closing quote */
143144

144145
end_error:
145146
git_buf_dispose(&buf);
@@ -209,7 +210,7 @@ static int parse_section_header(git_config_parser *reader, char **section_out)
209210
name[name_length] = 0;
210211
*section_out = name;
211212

212-
return 0;
213+
return pos;
213214

214215
fail_parse:
215216
git__free(line);
@@ -481,10 +482,14 @@ int git_config_parse(
481482
skip_bom(ctx);
482483

483484
for (; ctx->remain_len > 0; git_parse_advance_line(ctx)) {
484-
const char *line_start = parser->ctx.line;
485-
size_t line_len = parser->ctx.line_len;
485+
const char *line_start;
486+
size_t line_len;
486487
char c;
487488

489+
restart:
490+
line_start = ctx->line;
491+
line_len = ctx->line_len;
492+
488493
/*
489494
* Get either first non-whitespace character or, if that does
490495
* not exist, the first whitespace character. This is required
@@ -499,9 +504,24 @@ int git_config_parse(
499504
git__free(current_section);
500505
current_section = NULL;
501506

502-
if ((result = parse_section_header(parser, &current_section)) == 0 && on_section) {
507+
result = parse_section_header(parser, &current_section);
508+
if (result < 0)
509+
break;
510+
511+
git_parse_advance_chars(ctx, result);
512+
513+
if (on_section)
503514
result = on_section(parser, current_section, line_start, line_len, data);
504-
}
515+
/*
516+
* After we've parsed the section header we may not be
517+
* done with the line. If there's still data in there,
518+
* run the next loop with the rest of the current line
519+
* instead of moving forward.
520+
*/
521+
522+
if (!git_parse_peek(&c, ctx, GIT_PARSE_PEEK_SKIP_WHITESPACE))
523+
goto restart;
524+
505525
break;
506526

507527
case '\n': /* comment or whitespace-only */

tests/config/read.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,36 @@ void test_config_read__bom(void)
759759
git_buf_dispose(&buf);
760760
}
761761

762+
void test_config_read__single_line(void)
763+
{
764+
git_buf buf = GIT_BUF_INIT;
765+
git_config *cfg;
766+
767+
cl_set_cleanup(&clean_test_config, NULL);
768+
cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"] var = value");
769+
cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
770+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var"));
771+
cl_assert_equal_s(buf.ptr, "value");
772+
773+
git_buf_clear(&buf);
774+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.OtheR.var"));
775+
cl_assert_equal_s(buf.ptr, "value");
776+
777+
git_config_free(cfg);
778+
cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"]var = value");
779+
cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
780+
git_buf_clear(&buf);
781+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.var"));
782+
cl_assert_equal_s(buf.ptr, "value");
783+
784+
git_buf_clear(&buf);
785+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "some.OtheR.var"));
786+
cl_assert_equal_s(buf.ptr, "value");
787+
788+
git_config_free(cfg);
789+
git_buf_dispose(&buf);
790+
}
791+
762792
static int read_nosection_cb(const git_config_entry *entry, void *payload) {
763793
int *seen = (int*)payload;
764794
if (strcmp(entry->name, "key") == 0) {

0 commit comments

Comments
 (0)