From: Victoria Dye <vdye@xxxxxxxxxx> Use 'verify_path' to validate the paths provided as tree entries, ensuring we do not create entries with paths not allowed in trees (e.g., .git). Also, remove trailing slashes on directories before validating, allowing users to provide 'folder-name/' as the path for a tree object entry. Signed-off-by: Victoria Dye <vdye@xxxxxxxxxx> --- builtin/mktree.c | 20 +++++++++++++++++--- t/t1010-mktree.sh | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/builtin/mktree.c b/builtin/mktree.c index 48019448c1f..29e9dc6ce69 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -8,6 +8,7 @@ #include "hex.h" #include "index-info.h" #include "quote.h" +#include "read-cache-ll.h" #include "strbuf.h" #include "tree.h" #include "parse-options.h" @@ -49,10 +50,23 @@ static void append_to_tree(unsigned mode, struct object_id *oid, const char *pat { struct tree_entry *ent; size_t len = strlen(path); - if (!literally && strchr(path, '/')) - die("path %s contains slash", path); - FLEX_ALLOC_MEM(ent, name, path, len); + if (literally) { + FLEX_ALLOC_MEM(ent, name, path, len); + } else { + /* Normalize and validate entry path */ + if (S_ISDIR(mode)) { + while(len > 0 && is_dir_sep(path[len - 1])) + len--; + } + FLEX_ALLOC_MEM(ent, name, path, len); + + if (!verify_path(ent->name, mode)) + die(_("invalid path '%s'"), path); + if (strchr(ent->name, '/')) + die("path %s contains slash", path); + } + ent->mode = mode; ent->len = len; oidcpy(&ent->oid, oid); diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh index e0687cb529f..e0263cb2bf8 100755 --- a/t/t1010-mktree.sh +++ b/t/t1010-mktree.sh @@ -173,4 +173,37 @@ test_expect_success '--literally can create invalid trees' ' grep "not properly sorted" err ' +test_expect_success 'mktree validates path' ' + tree_oid="$(cat tree)" && + blob_oid="$(git rev-parse $tree_oid:a/one)" && + head_oid="$(git rev-parse HEAD)" && + + # Valid: tree with or without trailing slash, blob without trailing slash + { + printf "040000 tree $tree_oid\tfolder1/\n" && + printf "040000 tree $tree_oid\tfolder2\n" && + printf "100644 blob $blob_oid\tfile.txt\n" + } | git mktree >actual && + + # Invalid: blob with trailing slash + printf "100644 blob $blob_oid\ttest/" | + test_must_fail git mktree 2>err && + grep "invalid path ${SQ}test/${SQ}" err && + + # Invalid: dotdot + printf "040000 tree $tree_oid\t../" | + test_must_fail git mktree 2>err && + grep "invalid path ${SQ}../${SQ}" err && + + # Invalid: dot + printf "040000 tree $tree_oid\t." | + test_must_fail git mktree 2>err && + grep "invalid path ${SQ}.${SQ}" err && + + # Invalid: .git + printf "040000 tree $tree_oid\t.git/" | + test_must_fail git mktree 2>err && + grep "invalid path ${SQ}.git/${SQ}" err +' + test_done -- gitgitgadget