Merge branch 'nd/stop-setenv-work-tree' into nd/clear-gitenv-upon-use-of-alias
[gitweb.git] / config.c
index 29fa0121d583d3a77fcc2e8319cc484c317dcca3..0e532b828735cd8086cd947c6ec207317875d7f6 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1848,7 +1848,7 @@ int git_config_set(const char *key, const char *value)
  * baselen - pointer to int which will hold the length of the
  *           section + subsection part, can be NULL
  */
-int git_config_parse_key(const char *key, char **store_key, int *baselen_)
+static int git_config_parse_key_1(const char *key, char **store_key, int *baselen_, int quiet)
 {
        int i, dot, baselen;
        const char *last_dot = strrchr(key, '.');
@@ -1859,12 +1859,14 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
         */
 
        if (last_dot == NULL || last_dot == key) {
-               error("key does not contain a section: %s", key);
+               if (!quiet)
+                       error("key does not contain a section: %s", key);
                return -CONFIG_NO_SECTION_OR_NAME;
        }
 
        if (!last_dot[1]) {
-               error("key does not contain variable name: %s", key);
+               if (!quiet)
+                       error("key does not contain variable name: %s", key);
                return -CONFIG_NO_SECTION_OR_NAME;
        }
 
@@ -1875,7 +1877,8 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
        /*
         * Validate the key and while at it, lower case it for matching.
         */
-       *store_key = xmalloc(strlen(key) + 1);
+       if (store_key)
+               *store_key = xmalloc(strlen(key) + 1);
 
        dot = 0;
        for (i = 0; key[i]; i++) {
@@ -1886,26 +1889,42 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
                if (!dot || i > baselen) {
                        if (!iskeychar(c) ||
                            (i == baselen + 1 && !isalpha(c))) {
-                               error("invalid key: %s", key);
+                               if (!quiet)
+                                       error("invalid key: %s", key);
                                goto out_free_ret_1;
                        }
                        c = tolower(c);
                } else if (c == '\n') {
-                       error("invalid key (newline): %s", key);
+                       if (!quiet)
+                               error("invalid key (newline): %s", key);
                        goto out_free_ret_1;
                }
-               (*store_key)[i] = c;
+               if (store_key)
+                       (*store_key)[i] = c;
        }
-       (*store_key)[i] = 0;
+       if (store_key)
+               (*store_key)[i] = 0;
 
        return 0;
 
 out_free_ret_1:
-       free(*store_key);
-       *store_key = NULL;
+       if (store_key) {
+               free(*store_key);
+               *store_key = NULL;
+       }
        return -CONFIG_INVALID_KEY;
 }
 
+int git_config_parse_key(const char *key, char **store_key, int *baselen)
+{
+       return git_config_parse_key_1(key, store_key, baselen, 0);
+}
+
+int git_config_key_is_valid(const char *key)
+{
+       return !git_config_parse_key_1(key, NULL, NULL, 1);
+}
+
 /*
  * If value==NULL, unset in (remove from) config,
  * if value_regex!=NULL, disregard key/value pairs where value does not match.
@@ -1935,7 +1954,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
                                const char *key, const char *value,
                                const char *value_regex, int multi_replace)
 {
-       int fd = -1, in_fd;
+       int fd = -1, in_fd = -1;
        int ret;
        struct lock_file *lock = NULL;
        char *filename_buf = NULL;
@@ -2065,6 +2084,7 @@ int git_config_set_multivar_in_file(const char *config_filename,
                        goto out_free;
                }
                close(in_fd);
+               in_fd = -1;
 
                if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
                        error("chmod on %s failed: %s",
@@ -2118,6 +2138,9 @@ int git_config_set_multivar_in_file(const char *config_filename,
                                          contents_sz - copy_begin) <
                            contents_sz - copy_begin)
                                goto write_err_out;
+
+               munmap(contents, contents_sz);
+               contents = NULL;
        }
 
        if (commit_lock_file(lock) < 0) {
@@ -2145,6 +2168,8 @@ int git_config_set_multivar_in_file(const char *config_filename,
        free(filename_buf);
        if (contents)
                munmap(contents, contents_sz);
+       if (in_fd >= 0)
+               close(in_fd);
        return ret;
 
 write_err_out: