Merge pull request #1084 from libgit2/filename-validation Filename validation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
diff --git a/src/tree.c b/src/tree.c
index 7b47af3..6f98388 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)
@@ -372,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);
diff --git a/tests-clar/index/tests.c b/tests-clar/index/tests.c
index d3f6f25..3b71b70 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");
+}
diff --git a/tests-clar/object/tree/write.c b/tests-clar/object/tree/write.c
index 657bed2..cc5438b 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));