]> git.proxmox.com Git - libgit2.git/commitdiff
config: handle realloc issues from larger depths
authorCarlos Martín Nieto <cmn@dwim.me>
Sat, 7 Sep 2013 17:07:39 +0000 (19:07 +0200)
committerCarlos Martín Nieto <cmn@dwim.me>
Sat, 7 Sep 2013 18:51:26 +0000 (20:51 +0200)
As the include depth increases, the chance of a realloc
increases. This means that whenever we run git_array_alloc() or call
config_parse(), we need to remember what our reader's index is so we
can look it up again.

src/config_file.c
tests-clar/config/include.c

index 034d1d7b1c57dd206f46a3a47f9cc8bb4953cb3b..bd4fa74712d0cb1e57b74ffec85d7531b4c66653 100644 (file)
@@ -191,6 +191,7 @@ static int config_open(git_config_backend *cfg, git_config_level_t level)
                b->values = NULL;
        }
 
+       reader = git_array_get(b->readers, 0);
        git_buf_free(&reader->buffer);
        return res;
 }
@@ -948,12 +949,14 @@ static int config_parse(diskfile_backend *cfg_file, struct reader *reader, git_c
        git_buf buf = GIT_BUF_INIT;
        int result = 0;
        khiter_t pos;
+       uint32_t reader_idx;
 
        if (depth >= MAX_INCLUDE_DEPTH) {
                giterr_set(GITERR_CONFIG, "Maximum config include depth reached");
                return -1;
        }
 
+       reader_idx = git_array_size(cfg_file->readers) - 1;
        /* Initialize the reading position */
        reader->read_ptr = reader->buffer.ptr;
        reader->eof = 0;
@@ -1027,12 +1030,17 @@ static int config_parse(diskfile_backend *cfg_file, struct reader *reader, git_c
                                struct reader *r;
                                git_buf path = GIT_BUF_INIT;
                                char *dir;
+                               uint32_t index;
 
                                r = git_array_alloc(cfg_file->readers);
+                               /* The reader may have been reallocated */
+                               reader = git_array_get(cfg_file->readers, reader_idx);
                                memset(r, 0, sizeof(struct reader));
                                if ((result = git_path_dirname_r(&path, reader->file_path)) < 0)
                                        break;
 
+                               /* We need to know out index in the array, as the next config_parse call may realloc */
+                               index = git_array_size(cfg_file->readers) - 1;
                                dir = git_buf_detach(&path);
                                result = included_path(&path, dir, var->entry->value);
                                git__free(dir);
@@ -1047,6 +1055,7 @@ static int config_parse(diskfile_backend *cfg_file, struct reader *reader, git_c
                                        break;
 
                                result = config_parse(cfg_file, r, level, depth+1);
+                               r = git_array_get(cfg_file->readers, index);
                                git_buf_free(&r->buffer);
 
                                if (result < 0)
index f1019a9dcf234de9b17ff7dc729b24f8ca4fc06d..5355738083cae50ef53932059f2fad28169caac9 100644 (file)
@@ -93,3 +93,17 @@ void test_config_include__ordering(void)
 
        git_config_free(cfg);
 }
+
+/* We need to pretend that the variables were defined where the file was included */
+void test_config_include__depth(void)
+{
+       git_config *cfg;
+
+       cl_git_mkfile("a", "[include]\npath = b");
+       cl_git_mkfile("b", "[include]\npath = a");
+
+       cl_git_fail(git_config_open_ondisk(&cfg, "a"));
+
+       unlink("a");
+       unlink("b");
+}