make config --add behave correctly for empty and NULL values
authorTanay Abhra <tanayabh@gmail.com>
Mon, 18 Aug 2014 10:17:57 +0000 (03:17 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 18 Aug 2014 17:45:59 +0000 (10:45 -0700)
Currently if we have a config file like,
[foo]
baz
bar =

and we try something like, "git config --add foo.baz roll", Git will
segfault. Moreover, for "git config --add foo.bar roll", it will
overwrite the original value instead of appending after the existing
empty value.

The problem lies with the regexp used for simulating --add in
`git_config_set_multivar_in_file()`, "^$", which in ideal case should
not match with any string but is true for empty strings. Instead use a
regexp like "a^" which can not be true for any string, empty or not.

For removing the segfault add a check for NULL values in `matches()` in
config.c.

Signed-off-by: Tanay Abhra <tanayabh@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/config.c
config.c
t/t1303-wacky-config.sh
index 5677c942b6936f3332b1b4ed12541f45c4228dfb..8224699663bf91e8b7c8732b41a6a939a21669c4 100644 (file)
@@ -599,7 +599,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                check_argc(argc, 2, 2);
                value = normalize_value(argv[0], argv[1]);
                return git_config_set_multivar_in_file(given_config_source.file,
-                                                      argv[0], value, "^$", 0);
+                                                      argv[0], value, "a^", 0);
        }
        else if (actions == ACTION_REPLACE_ALL) {
                check_write();
index 2634457f6b07ca55b69f3b4a22b8a9e4339fd121..ffe010423d6a44bb12218ded95c4e86dfed8848d 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1233,7 +1233,7 @@ static int matches(const char *key, const char *value)
        return !strcmp(key, store.key) &&
                (store.value_regex == NULL ||
                 (store.do_not_match ^
-                 !regexec(store.value_regex, value, 0, NULL, 0)));
+                 (value && !regexec(store.value_regex, value, 0, NULL, 0))));
 }
 
 static int store_aux(const char *key, const char *value, void *cb)
index 3a2c81968cf7d539410358de1c8af6cf1d2500c9..3b92083e19d09bad951519201f9605a17b168c1a 100755 (executable)
@@ -111,4 +111,24 @@ test_expect_success 'unset many entries' '
        test_must_fail git config section.key
 '
 
+test_expect_success '--add appends new value after existing empty value' '
+       cat >expect <<-\EOF &&
+
+
+       fool
+       roll
+       EOF
+       cp .git/config .git/config.old &&
+       test_when_finished "mv .git/config.old .git/config" &&
+       cat >.git/config <<-\EOF &&
+       [foo]
+               baz
+               baz =
+               baz = fool
+       EOF
+       git config --add foo.baz roll &&
+       git config --get-all foo.baz >output &&
+       test_cmp expect output
+'
+
 test_done