From 19af78bb36b144022d7dbe68605c8715cd6dc322 Mon Sep 17 00:00:00 2001 From: "Scott J. Goldman" Date: Sun, 18 Nov 2012 15:15:24 -0800 Subject: [PATCH 1/3] Prevent creating `..`, `.`, and `.git` with tree builder As per core git. --- src/tree.c | 4 +++- tests-clar/object/tree/write.c | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tree.c b/src/tree.c index 7b47af347..150f90c44 100644 --- a/src/tree.c +++ b/src/tree.c @@ -26,7 +26,9 @@ static bool valid_filemode(const int filemode) static int valid_entry_name(const char *filename) { - return *filename != '\0' && strchr(filename, '/') == NULL; + return *filename != '\0' && strchr(filename, '/') == NULL && + strcmp(filename, "..") != 0 && strcmp(filename, ".") != 0 && + strcmp(filename, ".git") != 0; } static int entry_sort_cmp(const void *a, const void *b) diff --git a/tests-clar/object/tree/write.c b/tests-clar/object/tree/write.c index 657bed289..cc5438b05 100644 --- a/tests-clar/object/tree/write.c +++ b/tests-clar/object/tree/write.c @@ -39,6 +39,12 @@ void test_object_tree_write__from_memory(void) &bid, GIT_FILEMODE_BLOB)); cl_git_fail(git_treebuilder_insert(NULL, builder, "/", &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, ".git", + &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, "..", + &bid, GIT_FILEMODE_BLOB)); + cl_git_fail(git_treebuilder_insert(NULL, builder, ".", + &bid, GIT_FILEMODE_BLOB)); cl_git_fail(git_treebuilder_insert(NULL, builder, "folder/new.txt", &bid, GIT_FILEMODE_BLOB)); From 0d778b1a892d53161b4392ed75adcb3dcfe1a3df Mon Sep 17 00:00:00 2001 From: "Scott J. Goldman" Date: Sun, 18 Nov 2012 16:52:04 -0800 Subject: [PATCH 2/3] Catch invalid filenames in append_entry() This prevents the index api from calling write_tree() with a bogus tree. --- src/tree.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tree.c b/src/tree.c index 150f90c44..6f9838880 100644 --- a/src/tree.c +++ b/src/tree.c @@ -374,6 +374,9 @@ static int append_entry( { git_tree_entry *entry; + if (!valid_entry_name(filename)) + return tree_error("Failed to insert entry. Invalid name for a tree entry"); + entry = alloc_entry(filename); GITERR_CHECK_ALLOC(entry); From 1876360f813da8e6aba763baded5dcb004d9999c Mon Sep 17 00:00:00 2001 From: "Scott J. Goldman" Date: Sun, 18 Nov 2012 16:59:42 -0800 Subject: [PATCH 3/3] Add a test for invalid filenames while writing tree from index --- tests-clar/index/tests.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests-clar/index/tests.c b/tests-clar/index/tests.c index d3f6f2582..3b71b704d 100644 --- a/tests-clar/index/tests.c +++ b/tests-clar/index/tests.c @@ -261,3 +261,30 @@ void test_index_tests__add_from_workdir_to_a_bare_repository_returns_EBAREPO(voi git_index_free(index); git_repository_free(bare_repo); } + +/* Test that writing an invalid filename fails */ +void test_index_tests__write_invalid_filename(void) +{ + git_repository *repo; + git_index *index; + git_oid expected; + + p_mkdir("read_tree", 0700); + + cl_git_pass(git_repository_init(&repo, "./read_tree", 0)); + cl_git_pass(git_repository_index(&index, repo)); + + cl_assert(git_index_entrycount(index) == 0); + + cl_git_mkfile("./read_tree/.git/hello", NULL); + + cl_git_pass(git_index_add_from_workdir(index, ".git/hello")); + + /* write-tree */ + cl_git_fail(git_index_write_tree(&expected, index)); + + git_index_free(index); + git_repository_free(repo); + + cl_fixture_cleanup("read_tree"); +}