* git config problem with strange config files
@ 2007-12-31 17:47 Peter Oberndorfer
2008-01-01 6:17 ` Jeff King
0 siblings, 1 reply; 5+ messages in thread
From: Peter Oberndorfer @ 2007-12-31 17:47 UTC (permalink / raw)
To: Git Mailing List
[-- Attachment #1: Type: text/plain, Size: 947 bytes --]
Hi,
In case of a strange .git/config file "git config key value" can create a
bogus config entry, where one old value is wrong and the new value resides in
the wrong section until the config file is fixed up by hand
The attached test config has a trailing tab in the last line
and no newline after that.
When git config is run the new section name is placed directly after the
trailing tab, which corrupts the old value.
To reproduce the error do the following:
mkdir git_test_config && cd git_test_config
git init
<copy the attached config file to .git/config>
git config section2.key bar
git config --get section2.key
-> returns nothing
git config --get section.key
-> foo [section2]
-> error: More than one value for the key section.key: bar
i tried to make a test out of this but i failed to create a config file
without a trailing newline using here documents :-(
Tested using v1.5.4.rc2 and v1.5.4-rc2-6-gab11903
Greetings Peter
[-- Attachment #2: config --]
[-- Type: text/plain, Size: 21 bytes --]
[section]
key = foo
[-- Attachment #3: config_bogus --]
[-- Type: text/plain, Size: 43 bytes --]
[section]
key = foo [section2]
key = bar
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: git config problem with strange config files
2007-12-31 17:47 git config problem with strange config files Peter Oberndorfer
@ 2008-01-01 6:17 ` Jeff King
2008-01-01 6:23 ` Jeff King
2008-01-01 14:25 ` Peter Oberndorfer
0 siblings, 2 replies; 5+ messages in thread
From: Jeff King @ 2008-01-01 6:17 UTC (permalink / raw)
To: Peter Oberndorfer; +Cc: Junio C Hamano, Git Mailing List
On Mon, Dec 31, 2007 at 06:47:41PM +0100, Peter Oberndorfer wrote:
> In case of a strange .git/config file "git config key value" can
> create a bogus config entry, where one old value is wrong and the new
> value resides in the wrong section until the config file is fixed up
> by hand
This patch fixes the test case you gave.
Junio, even though such a config file should be rare, I think this is
v1.5.4 material. But there is one tricky thing which I will point out in
a followup mail.
-- >8 --
config: handle lack of newline at end of file better
The config parsing routines use the static global
'config_file' to store the FILE* pointing to the current
config file being parsed. The function get_next_char()
automatically converts an EOF on this file to a newline for
the convenience of its callers, and it sets config_file to
NULL to indicate that EOF was reached.
This throws away useful information, though, since some
routines want to call ftell on 'config_file' to find out
exactly _where_ the routine ended. In the case of a key
ending at EOF boundary, we ended up segfaulting in some
cases (changing that key or adding another key in its
section), or failing to provide the necessary newline
(adding a new section).
This patch adds a new flag to indicate EOF and uses that
instead of setting config_file to NULL. It also makes sure
to add newlines where necessary for truncated input. All
three included tests fail without the patch.
---
config.c | 14 +++++++++-----
t/t1303-wacky-config.sh | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 5 deletions(-)
create mode 100755 t/t1303-wacky-config.sh
diff --git a/config.c b/config.c
index fa56c70..7ef8b75 100644
--- a/config.c
+++ b/config.c
@@ -13,6 +13,7 @@
static FILE *config_file;
static const char *config_file_name;
static int config_linenr;
+static int config_file_eof;
static int zlib_compression_seen;
static int get_next_char(void)
@@ -34,7 +35,7 @@ static int get_next_char(void)
if (c == '\n')
config_linenr++;
if (c == EOF) {
- config_file = NULL;
+ config_file_eof = 1;
c = '\n';
}
}
@@ -118,7 +119,7 @@ static int get_value(config_fn_t fn, char *name, unsigned int len)
/* Get the full name */
for (;;) {
c = get_next_char();
- if (c == EOF)
+ if (config_file_eof)
break;
if (!iskeychar(c))
break;
@@ -182,7 +183,7 @@ static int get_base_var(char *name)
for (;;) {
int c = get_next_char();
- if (c == EOF)
+ if (config_file_eof)
return -1;
if (c == ']')
return baselen;
@@ -205,8 +206,7 @@ static int git_parse_file(config_fn_t fn)
for (;;) {
int c = get_next_char();
if (c == '\n') {
- /* EOF? */
- if (!config_file)
+ if (config_file_eof)
return 0;
comment = 0;
continue;
@@ -469,6 +469,7 @@ int git_config_from_file(config_fn_t fn, const char *filename)
config_file = f;
config_file_name = filename;
config_linenr = 1;
+ config_file_eof = 0;
ret = git_parse_file(fn);
fclose(f);
config_file_name = NULL;
@@ -918,6 +919,9 @@ int git_config_set_multivar(const char* key, const char* value,
contents, contents_sz,
store.offset[i]-2, &new_line);
+ if (copy_end > 0 && contents[copy_end-1] != '\n')
+ new_line = 1;
+
/* write the first part of the config */
if (copy_end > copy_begin) {
if (write_in_full(fd, contents + copy_begin,
diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh
new file mode 100755
index 0000000..99985dc
--- /dev/null
+++ b/t/t1303-wacky-config.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+test_description='Test wacky input to git config'
+. ./test-lib.sh
+
+setup() {
+ (printf "[section]\n" &&
+ printf " key = foo") >.git/config
+}
+
+check() {
+ echo "$2" >expected
+ git config --get "$1" >actual
+ git diff actual expected
+}
+
+test_expect_success 'modify same key' '
+ setup &&
+ git config section.key bar &&
+ check section.key bar
+'
+
+test_expect_success 'add key in same section' '
+ setup &&
+ git config section.other bar &&
+ check section.key foo &&
+ check section.other bar
+'
+
+test_expect_success 'add key in different section' '
+ setup &&
+ git config section2.key bar &&
+ check section.key foo &&
+ check section2.key bar
+'
+
+test_done
--
1.5.4.rc2.1103.g1042-dirty
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: git config problem with strange config files
2008-01-01 6:17 ` Jeff King
@ 2008-01-01 6:23 ` Jeff King
2008-01-01 19:57 ` Junio C Hamano
2008-01-01 14:25 ` Peter Oberndorfer
1 sibling, 1 reply; 5+ messages in thread
From: Jeff King @ 2008-01-01 6:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Peter Oberndorfer, Git Mailing List
On Tue, Jan 01, 2008 at 01:17:34AM -0500, Jeff King wrote:
> @@ -118,7 +119,7 @@ static int get_value(config_fn_t fn, char *name, unsigned int len)
> /* Get the full name */
> for (;;) {
> c = get_next_char();
> - if (c == EOF)
> + if (config_file_eof)
> break;
> if (!iskeychar(c))
> break;
> @@ -182,7 +183,7 @@ static int get_base_var(char *name)
>
> for (;;) {
> int c = get_next_char();
> - if (c == EOF)
> + if (config_file_eof)
> return -1;
> if (c == ']')
> return baselen;
In these two hunks, we now check the eof flag correctly, which follows
through on the intent of the original code. But if you look carefully at
get_next_char(), it _never_ returns EOF in the first place; it replaces
it with '\n' and sets an external flag. So this 'if' branch was never
reached, but happened to work because the returned newline triggers a
similar effect.
By actually looking at the flag, I am implementing the original intent,
but it is a potential behavior change (I don't _think_ it should matter,
and it passes all of the config tests, but I haven't looked carefully at
all the ramifications). So it might be simpler yet to just eliminate
that conditional return.
-Peff
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: git config problem with strange config files
2008-01-01 6:17 ` Jeff King
2008-01-01 6:23 ` Jeff King
@ 2008-01-01 14:25 ` Peter Oberndorfer
1 sibling, 0 replies; 5+ messages in thread
From: Peter Oberndorfer @ 2008-01-01 14:25 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, Git Mailing List
On Dienstag 01 Januar 2008, Jeff King wrote:
> On Mon, Dec 31, 2007 at 06:47:41PM +0100, Peter Oberndorfer wrote:
>
> > In case of a strange .git/config file "git config key value" can
> > create a bogus config entry, where one old value is wrong and the new
> > value resides in the wrong section until the config file is fixed up
> > by hand
>
> This patch fixes the test case you gave.
>
> Junio, even though such a config file should be rare, I think this is
> v1.5.4 material. But there is one tricky thing which I will point out in
> a followup mail.
>
Thank you for the patch
I would also guess this is relative rare, but IIRC somebody posted a patch to
handle a bogus config with a better message,
and the breakage example in the mail looked similar to mine.
How i came up with this bogus config is relative simple.
I wanted to add a new remote so i copied the already existing remote and
branch sections down to the last line and somehow also added a trailing tab.
Then i did a stg init which uses git repo-config to add its
stackformatversion = 2 setting
Greetings Peter
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: git config problem with strange config files
2008-01-01 6:23 ` Jeff King
@ 2008-01-01 19:57 ` Junio C Hamano
0 siblings, 0 replies; 5+ messages in thread
From: Junio C Hamano @ 2008-01-01 19:57 UTC (permalink / raw)
To: Jeff King; +Cc: Peter Oberndorfer, Git Mailing List
I agree with your analysis, and thanks for the patch.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-01-01 19:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-31 17:47 git config problem with strange config files Peter Oberndorfer
2008-01-01 6:17 ` Jeff King
2008-01-01 6:23 ` Jeff King
2008-01-01 19:57 ` Junio C Hamano
2008-01-01 14:25 ` Peter Oberndorfer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox