Merge branch 'ss/fix-config-fd-leak' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 4 Sep 2015 02:17:59 +0000 (19:17 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 4 Sep 2015 02:17:59 +0000 (19:17 -0700)
* ss/fix-config-fd-leak:
config: close config file handle in case of error

1  2 
config.c
diff --combined config.c
index 8adc15a4479c9828063858928149f9734d951e5a,83caa2546ee2e93bfb5cb1269bde4ea4e983a9f3..0e532b828735cd8086cd947c6ec207317875d7f6
+++ b/config.c
@@@ -1848,7 -1848,7 +1848,7 @@@ int git_config_set(const char *key, con
   * 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, '.');
         */
  
        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;
        }
  
        /*
         * 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++) {
                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.
@@@ -1954,7 -1935,7 +1954,7 @@@ int git_config_set_multivar_in_file(con
                                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;
                        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",
@@@ -2167,6 -2149,8 +2168,8 @@@ out_free
        free(filename_buf);
        if (contents)
                munmap(contents, contents_sz);
+       if (in_fd >= 0)
+               close(in_fd);
        return ret;
  
  write_err_out: