Merge branch 'ma/config-store-data-clear'
authorJunio C Hamano <gitster@pobox.com>
Wed, 30 May 2018 12:51:28 +0000 (21:51 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 May 2018 12:51:28 +0000 (21:51 +0900)
Leak plugging.

* ma/config-store-data-clear:
config: let `config_store_data_clear()` handle `key`
config: let `config_store_data_clear()` handle `value_regex`
config: free resources of `struct config_store_data`

1  2 
config.c
diff --combined config.c
index 2c573ad3dd275faa4264b8429b275bb9670d5e04,339a92235deace1a67a53b332294e1993e535592..fbbf0f8e9f2b2ae0a96769108d8a2773f071aec1
+++ b/config.c
@@@ -103,7 -103,7 +103,7 @@@ static int config_buf_ungetc(int c, str
        if (conf->u.buf.pos > 0) {
                conf->u.buf.pos--;
                if (conf->u.buf.buf[conf->u.buf.pos] != c)
 -                      die("BUG: config_buf can only ungetc the same character");
 +                      BUG("config_buf can only ungetc the same character");
                return c;
        }
  
@@@ -190,7 -190,7 +190,7 @@@ static int prepare_include_condition_pa
                strbuf_realpath(&path, cf->path, 1);
                slash = find_last_dir_sep(path.buf);
                if (!slash)
 -                      die("BUG: how is this possible?");
 +                      BUG("how is this possible?");
                strbuf_splice(pat, 0, 1, path.buf, slash - path.buf);
                prefix = slash - path.buf + 1 /* slash */;
        } else if (!is_absolute_path(pat->buf))
@@@ -1814,7 -1814,7 +1814,7 @@@ static int configset_add_value(struct c
        l_item->value_index = e->value_list.nr - 1;
  
        if (!cf)
 -              die("BUG: configset_add_value has no source");
 +              BUG("configset_add_value has no source");
        if (cf->name) {
                kv_info->filename = strintern(cf->name);
                kv_info->linenr = cf->linenr;
@@@ -2333,6 -2333,19 +2333,19 @@@ struct config_store_data 
        unsigned int key_seen:1, section_seen:1, is_keys_section:1;
  };
  
+ static void config_store_data_clear(struct config_store_data *store)
+ {
+       free(store->key);
+       if (store->value_regex != NULL &&
+           store->value_regex != CONFIG_REGEX_NONE) {
+               regfree(store->value_regex);
+               free(store->value_regex);
+       }
+       free(store->parsed);
+       free(store->seen);
+       memset(store, 0, sizeof(*store));
+ }
  static int matches(const char *key, const char *value,
                   const struct config_store_data *store)
  {
@@@ -2359,7 -2372,7 +2372,7 @@@ static int store_aux_event(enum config_
  
        if (type == CONFIG_EVENT_SECTION) {
                if (cf->var.len < 2 || cf->var.buf[cf->var.len - 1] != '.')
 -                      BUG("Invalid section name '%s'", cf->var.buf);
 +                      return error("invalid section name '%s'", cf->var.buf);
  
                /* Is this the section we were looking for? */
                store->is_keys_section =
@@@ -2667,7 -2680,6 +2680,6 @@@ int git_config_set_multivar_in_file_gen
        fd = hold_lock_file_for_update(&lock, config_filename, 0);
        if (fd < 0) {
                error_errno("could not lock config file %s", config_filename);
-               free(store.key);
                ret = CONFIG_NO_LOCK;
                goto out_free;
        }
         */
        in_fd = open(config_filename, O_RDONLY);
        if ( in_fd < 0 ) {
-               free(store.key);
                if ( ENOENT != errno ) {
                        error_errno("opening %s", config_filename);
                        ret = CONFIG_INVALID_FILE; /* same as "invalid config file" */
                        goto out_free;
                }
  
-               store.key = (char *)key;
+               free(store.key);
+               store.key = xstrdup(key);
                if (write_section(fd, key, &store) < 0 ||
                    write_pair(fd, key, value, &store) < 0)
                        goto write_err_out;
                        if (regcomp(store.value_regex, value_regex,
                                        REG_EXTENDED)) {
                                error("invalid pattern: %s", value_regex);
-                               free(store.value_regex);
+                               FREE_AND_NULL(store.value_regex);
                                ret = CONFIG_INVALID_PATTERN;
                                goto out_free;
                        }
                                                      config_filename,
                                                      &store, &opts)) {
                        error("invalid config file %s", config_filename);
-                       free(store.key);
-                       if (store.value_regex != NULL &&
-                           store.value_regex != CONFIG_REGEX_NONE) {
-                               regfree(store.value_regex);
-                               free(store.value_regex);
-                       }
                        ret = CONFIG_INVALID_FILE;
                        goto out_free;
                }
  
-               free(store.key);
-               if (store.value_regex != NULL &&
-                   store.value_regex != CONFIG_REGEX_NONE) {
-                       regfree(store.value_regex);
-                       free(store.value_regex);
-               }
                /* if nothing to unset, or too many matches, error out */
                if ((store.seen_nr == 0 && value == NULL) ||
                    (store.seen_nr > 1 && multi_replace == 0)) {
@@@ -2887,6 -2885,7 +2885,7 @@@ out_free
                munmap(contents, contents_sz);
        if (in_fd >= 0)
                close(in_fd);
+       config_store_data_clear(&store);
        return ret;
  
  write_err_out:
@@@ -3127,6 -3126,7 +3126,7 @@@ out
        rollback_lock_file(&lock);
  out_no_rollback:
        free(filename_buf);
+       config_store_data_clear(&store);
        return ret;
  }
  
@@@ -3208,7 -3208,7 +3208,7 @@@ const char *current_config_origin_type(
        else if(cf)
                type = cf->origin_type;
        else
 -              die("BUG: current_config_origin_type called outside config callback");
 +              BUG("current_config_origin_type called outside config callback");
  
        switch (type) {
        case CONFIG_ORIGIN_BLOB:
        case CONFIG_ORIGIN_CMDLINE:
                return "command line";
        default:
 -              die("BUG: unknown config origin type");
 +              BUG("unknown config origin type");
        }
  }
  
@@@ -3234,7 -3234,7 +3234,7 @@@ const char *current_config_name(void
        else if (cf)
                name = cf->name;
        else
 -              die("BUG: current_config_name called outside config callback");
 +              BUG("current_config_name called outside config callback");
        return name ? name : "";
  }