Merge branch 'cn/config-missing-path'
authorJunio C Hamano <gitster@pobox.com>
Tue, 20 Nov 2012 18:40:46 +0000 (10:40 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Nov 2012 18:40:46 +0000 (10:40 -0800)
"git config --path $key" segfaulted on "[section] key" (a boolean
"true" spelled without "=", not "[section] key = true").

* cn/config-missing-path:
config: don't segfault when given --path with a missing value

1  2 
builtin/config.c
t/t1300-repo-config.sh
diff --combined builtin/config.c
index e1c33e0691796601ac869278c155194d33ee8332,a8cf1af88841b2c52cf4f84b0d7c67a17dc1fe85..505bbc7dddc2d080fcaa9acf93ed5c1379fbe75f
@@@ -4,7 -4,7 +4,7 @@@
  #include "parse-options.h"
  
  static const char *const builtin_config_usage[] = {
 -      "git config [options]",
 +      N_("git config [options]"),
        NULL
  };
  
@@@ -49,33 -49,33 +49,33 @@@ static int respect_includes = -1
  #define TYPE_PATH (1<<3)
  
  static struct option builtin_config_options[] = {
 -      OPT_GROUP("Config file location"),
 -      OPT_BOOLEAN(0, "global", &use_global_config, "use global config file"),
 -      OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
 -      OPT_BOOLEAN(0, "local", &use_local_config, "use repository config file"),
 -      OPT_STRING('f', "file", &given_config_file, "file", "use given config file"),
 -      OPT_GROUP("Action"),
 -      OPT_BIT(0, "get", &actions, "get value: name [value-regex]", ACTION_GET),
 -      OPT_BIT(0, "get-all", &actions, "get all values: key [value-regex]", ACTION_GET_ALL),
 -      OPT_BIT(0, "get-regexp", &actions, "get values for regexp: name-regex [value-regex]", ACTION_GET_REGEXP),
 -      OPT_BIT(0, "replace-all", &actions, "replace all matching variables: name value [value_regex]", ACTION_REPLACE_ALL),
 -      OPT_BIT(0, "add", &actions, "adds a new variable: name value", ACTION_ADD),
 -      OPT_BIT(0, "unset", &actions, "removes a variable: name [value-regex]", ACTION_UNSET),
 -      OPT_BIT(0, "unset-all", &actions, "removes all matches: name [value-regex]", ACTION_UNSET_ALL),
 -      OPT_BIT(0, "rename-section", &actions, "rename section: old-name new-name", ACTION_RENAME_SECTION),
 -      OPT_BIT(0, "remove-section", &actions, "remove a section: name", ACTION_REMOVE_SECTION),
 -      OPT_BIT('l', "list", &actions, "list all", ACTION_LIST),
 -      OPT_BIT('e', "edit", &actions, "opens an editor", ACTION_EDIT),
 -      OPT_STRING(0, "get-color", &get_color_slot, "slot", "find the color configured: [default]"),
 -      OPT_STRING(0, "get-colorbool", &get_colorbool_slot, "slot", "find the color setting: [stdout-is-tty]"),
 -      OPT_GROUP("Type"),
 -      OPT_BIT(0, "bool", &types, "value is \"true\" or \"false\"", TYPE_BOOL),
 -      OPT_BIT(0, "int", &types, "value is decimal number", TYPE_INT),
 -      OPT_BIT(0, "bool-or-int", &types, "value is --bool or --int", TYPE_BOOL_OR_INT),
 -      OPT_BIT(0, "path", &types, "value is a path (file or directory name)", TYPE_PATH),
 -      OPT_GROUP("Other"),
 -      OPT_BOOLEAN('z', "null", &end_null, "terminate values with NUL byte"),
 -      OPT_BOOL(0, "includes", &respect_includes, "respect include directives on lookup"),
 +      OPT_GROUP(N_("Config file location")),
 +      OPT_BOOLEAN(0, "global", &use_global_config, N_("use global config file")),
 +      OPT_BOOLEAN(0, "system", &use_system_config, N_("use system config file")),
 +      OPT_BOOLEAN(0, "local", &use_local_config, N_("use repository config file")),
 +      OPT_STRING('f', "file", &given_config_file, N_("file"), N_("use given config file")),
 +      OPT_GROUP(N_("Action")),
 +      OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
 +      OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
 +      OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP),
 +      OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL),
 +      OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
 +      OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET),
 +      OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-regex]"), ACTION_UNSET_ALL),
 +      OPT_BIT(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION),
 +      OPT_BIT(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION),
 +      OPT_BIT('l', "list", &actions, N_("list all"), ACTION_LIST),
 +      OPT_BIT('e', "edit", &actions, N_("open an editor"), ACTION_EDIT),
 +      OPT_STRING(0, "get-color", &get_color_slot, N_("slot"), N_("find the color configured: [default]")),
 +      OPT_STRING(0, "get-colorbool", &get_colorbool_slot, N_("slot"), N_("find the color setting: [stdout-is-tty]")),
 +      OPT_GROUP(N_("Type")),
 +      OPT_BIT(0, "bool", &types, N_("value is \"true\" or \"false\""), TYPE_BOOL),
 +      OPT_BIT(0, "int", &types, N_("value is decimal number"), TYPE_INT),
 +      OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
 +      OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
 +      OPT_GROUP(N_("Other")),
 +      OPT_BOOLEAN('z', "null", &end_null, N_("terminate values with NUL byte")),
 +      OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")),
        OPT_END(),
  };
  
@@@ -129,7 -129,8 +129,8 @@@ static int show_config(const char *key_
                else
                        sprintf(value, "%d", v);
        } else if (types == TYPE_PATH) {
-               git_config_pathname(&vptr, key_, value_);
+               if (git_config_pathname(&vptr, key_, value_) < 0)
+                       return -1;
                must_free_vptr = 1;
        } else if (value_) {
                vptr = value_;
  
  static int get_value(const char *key_, const char *regex_)
  {
 -      int ret = -1;
 +      int ret = CONFIG_GENERIC_ERROR;
        char *global = NULL, *xdg = NULL, *repo_config = NULL;
        const char *system_wide = NULL, *local;
        struct config_include_data inc = CONFIG_INCLUDE_INIT;
                if (regcomp(key_regexp, key, REG_EXTENDED)) {
                        fprintf(stderr, "Invalid key pattern: %s\n", key_);
                        free(key);
 +                      ret = CONFIG_INVALID_PATTERN;
                        goto free_strings;
                }
        } else {
 -              if (git_config_parse_key(key_, &key, NULL))
 +              if (git_config_parse_key(key_, &key, NULL)) {
 +                      ret = CONFIG_INVALID_KEY;
                        goto free_strings;
 +              }
        }
  
        if (regex_) {
                regexp = (regex_t*)xmalloc(sizeof(regex_t));
                if (regcomp(regexp, regex_, REG_EXTENDED)) {
                        fprintf(stderr, "Invalid pattern: %s\n", regex_);
 +                      ret = CONFIG_INVALID_PATTERN;
                        goto free_strings;
                }
        }
@@@ -400,8 -397,8 +401,8 @@@ int cmd_config(int argc, const char **a
                         */
                        die("$HOME not set");
  
 -              if (access(user_config, R_OK) &&
 -                  xdg_config && !access(xdg_config, R_OK))
 +              if (access_or_warn(user_config, R_OK) &&
 +                  xdg_config && !access_or_warn(xdg_config, R_OK))
                        given_config_file = xdg_config;
                else
                        given_config_file = user_config;
diff --combined t/t1300-repo-config.sh
index e127f35db9d12dba84cbf0503628ab5d9a3fc24f,17272e04295c7edf242a68bfb5942b478604ef6e..7c4c372e374b66844b83ac9343c6c71b362380e2
@@@ -391,7 -391,7 +391,7 @@@ test_expect_success 'get bool variable 
  
  test_expect_success 'no arguments, but no crash' '
        test_must_fail git config >output 2>&1 &&
 -      grep usage output
 +      test_i18ngrep usage output
  '
  
  cat > .git/config << EOF
@@@ -803,6 -803,11 +803,11 @@@ test_expect_success NOT_MINGW 'get --pa
        test_cmp expect result
  '
  
+ test_expect_success 'get --path barfs on boolean variable' '
+       echo "[path]bool" >.git/config &&
+       test_must_fail git config --get --path path.bool
+ '
  cat > expect << EOF
  [quote]
        leading = " test"