treebuilder: take a repository for path validation

Path validation may be influenced by `core.protectHFS` and
`core.protectNTFS` configuration settings, thus treebuilders
can take a repository to influence their configuration.
This commit is contained in:
Edward Thomson 2014-12-16 19:24:04 -06:00 committed by Edward Thomson
parent ec74b40cee
commit dce7b1a4e7
10 changed files with 123 additions and 53 deletions

View File

@ -136,3 +136,7 @@ v0.21 + 1
* git_libgit2_init() and git_libgit2_shutdown() now return the number of * git_libgit2_init() and git_libgit2_shutdown() now return the number of
initializations of the library, so consumers may schedule work on the initializations of the library, so consumers may schedule work on the
first initialization. first initialization.
* git_treebuilder_create now takes a repository so that it can query
repository configuration. Subsequently, git_treebuilder_write no
longer takes a repository.

View File

@ -247,11 +247,12 @@ GIT_EXTERN(int) git_tree_entry_to_object(
* entries and will have to be filled manually. * entries and will have to be filled manually.
* *
* @param out Pointer where to store the tree builder * @param out Pointer where to store the tree builder
* @param repo Repository in which to store the object
* @param source Source tree to initialize the builder (optional) * @param source Source tree to initialize the builder (optional)
* @return 0 on success; error code otherwise * @return 0 on success; error code otherwise
*/ */
GIT_EXTERN(int) git_treebuilder_create( GIT_EXTERN(int) git_treebuilder_create(
git_treebuilder **out, const git_tree *source); git_treebuilder **out, git_repository *repo, const git_tree *source);
/** /**
* Clear all the entires in the builder * Clear all the entires in the builder
@ -368,12 +369,11 @@ GIT_EXTERN(void) git_treebuilder_filter(
* identifying SHA1 hash will be stored in the `id` pointer. * identifying SHA1 hash will be stored in the `id` pointer.
* *
* @param id Pointer to store the OID of the newly written tree * @param id Pointer to store the OID of the newly written tree
* @param repo Repository in which to store the object
* @param bld Tree builder to write * @param bld Tree builder to write
* @return 0 or an error code * @return 0 or an error code
*/ */
GIT_EXTERN(int) git_treebuilder_write( GIT_EXTERN(int) git_treebuilder_write(
git_oid *id, git_repository *repo, git_treebuilder *bld); git_oid *id, git_treebuilder *bld);
/** Callback for the tree traversal method */ /** Callback for the tree traversal method */

View File

@ -107,7 +107,7 @@ static int tree_write(
const git_tree_entry *entry; const git_tree_entry *entry;
git_oid tree_oid; git_oid tree_oid;
if ((error = git_treebuilder_create(&tb, source_tree)) < 0) if ((error = git_treebuilder_create(&tb, repo, source_tree)) < 0)
goto cleanup; goto cleanup;
if (object_oid) { if (object_oid) {
@ -119,7 +119,7 @@ static int tree_write(
goto cleanup; goto cleanup;
} }
if ((error = git_treebuilder_write(&tree_oid, repo, tb)) < 0) if ((error = git_treebuilder_write(&tree_oid, tb)) < 0)
goto cleanup; goto cleanup;
error = git_tree_lookup(out, repo, &tree_oid); error = git_tree_lookup(out, repo, &tree_oid);

View File

@ -50,14 +50,11 @@ GIT_INLINE(git_filemode_t) normalize_filemode(git_filemode_t filemode)
return GIT_FILEMODE_BLOB; return GIT_FILEMODE_BLOB;
} }
static int valid_entry_name(const char *filename) static int valid_entry_name(git_repository *repo, const char *filename)
{ {
return *filename != '\0' && return *filename != '\0' &&
strchr(filename, '/') == NULL && git_path_isvalid(repo, filename,
(*filename != '.' || GIT_PATH_REJECT_TRAVERSAL | GIT_PATH_REJECT_DOT_GIT | GIT_PATH_REJECT_SLASH);
(strcmp(filename, ".") != 0 &&
strcmp(filename, "..") != 0 &&
strcasecmp(filename, DOT_GIT) != 0));
} }
static int entry_sort_cmp(const void *a, const void *b) static int entry_sort_cmp(const void *a, const void *b)
@ -455,7 +452,7 @@ static int append_entry(
git_tree_entry *entry; git_tree_entry *entry;
int error = 0; int error = 0;
if (!valid_entry_name(filename)) if (!valid_entry_name(bld->repo, filename))
return tree_error("Failed to insert entry. Invalid name for a tree entry", filename); return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
entry = alloc_entry(filename); entry = alloc_entry(filename);
@ -493,7 +490,7 @@ static int write_tree(
return (int)find_next_dir(dirname, index, start); return (int)find_next_dir(dirname, index, start);
} }
if ((error = git_treebuilder_create(&bld, NULL)) < 0 || bld == NULL) if ((error = git_treebuilder_create(&bld, repo, NULL)) < 0 || bld == NULL)
return -1; return -1;
/* /*
@ -564,7 +561,7 @@ static int write_tree(
} }
} }
if (git_treebuilder_write(oid, repo, bld) < 0) if (git_treebuilder_write(oid, bld) < 0)
goto on_error; goto on_error;
git_treebuilder_free(bld); git_treebuilder_free(bld);
@ -627,16 +624,21 @@ int git_tree__write_index(
return ret; return ret;
} }
int git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source) int git_treebuilder_create(
git_treebuilder **builder_p,
git_repository *repo,
const git_tree *source)
{ {
git_treebuilder *bld; git_treebuilder *bld;
size_t i; size_t i;
assert(builder_p); assert(builder_p && repo);
bld = git__calloc(1, sizeof(git_treebuilder)); bld = git__calloc(1, sizeof(git_treebuilder));
GITERR_CHECK_ALLOC(bld); GITERR_CHECK_ALLOC(bld);
bld->repo = repo;
if (git_strmap_alloc(&bld->map) < 0) { if (git_strmap_alloc(&bld->map) < 0) {
git__free(bld); git__free(bld);
return -1; return -1;
@ -678,7 +680,7 @@ int git_treebuilder_insert(
if (!valid_filemode(filemode)) if (!valid_filemode(filemode))
return tree_error("Failed to insert entry. Invalid filemode for file", filename); return tree_error("Failed to insert entry. Invalid filemode for file", filename);
if (!valid_entry_name(filename)) if (!valid_entry_name(bld->repo, filename))
return tree_error("Failed to insert entry. Invalid name for a tree entry", filename); return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
pos = git_strmap_lookup_index(bld->map, filename); pos = git_strmap_lookup_index(bld->map, filename);
@ -738,7 +740,7 @@ int git_treebuilder_remove(git_treebuilder *bld, const char *filename)
return 0; return 0;
} }
int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld) int git_treebuilder_write(git_oid *oid, git_treebuilder *bld)
{ {
int error = 0; int error = 0;
size_t i, entrycount; size_t i, entrycount;
@ -777,7 +779,7 @@ int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *b
git_vector_free(&entries); git_vector_free(&entries);
if (!error && if (!error &&
!(error = git_repository_odb__weakptr(&odb, repo))) !(error = git_repository_odb__weakptr(&odb, bld->repo)))
error = git_odb_write(oid, odb, tree.ptr, tree.size, GIT_OBJ_TREE); error = git_odb_write(oid, odb, tree.ptr, tree.size, GIT_OBJ_TREE);
git_buf_free(&tree); git_buf_free(&tree);

View File

@ -26,6 +26,7 @@ struct git_tree {
}; };
struct git_treebuilder { struct git_treebuilder {
git_repository *repo;
git_strmap *map; git_strmap *map;
}; };

View File

@ -421,6 +421,27 @@ void test_index_tests__write_invalid_filename(void)
cl_fixture_cleanup("invalid"); cl_fixture_cleanup("invalid");
} }
void test_index_tests__honors_protect_filesystems(void)
{
git_repository *repo;
p_mkdir("invalid", 0700);
cl_git_pass(git_repository_init(&repo, "./invalid", 0));
cl_repo_set_bool(repo, "core.protectHFS", true);
cl_repo_set_bool(repo, "core.protectNTFS", true);
write_invalid_filename(repo, ".git./hello");
write_invalid_filename(repo, ".git\xe2\x80\xad/hello");
write_invalid_filename(repo, "git~1/hello");
write_invalid_filename(repo, ".git\xe2\x81\xaf/hello");
git_repository_free(repo);
cl_fixture_cleanup("invalid");
}
void test_index_tests__remove_entry(void) void test_index_tests__remove_entry(void)
{ {
git_repository *repo; git_repository *repo;

View File

@ -1,9 +1,21 @@
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "tree.h" #include "tree.h"
static git_repository *repo;
static const char *blob_oid = "3d0970ec547fc41ef8a5882dde99c6adce65b021"; static const char *blob_oid = "3d0970ec547fc41ef8a5882dde99c6adce65b021";
static const char *tree_oid = "1b05fdaa881ee45b48cbaa5e9b037d667a47745e"; static const char *tree_oid = "1b05fdaa881ee45b48cbaa5e9b037d667a47745e";
void test_object_tree_attributes__initialize(void)
{
repo = cl_git_sandbox_init("deprecated-mode.git");
}
void test_object_tree_attributes__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion(void) void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion(void)
{ {
git_treebuilder *builder; git_treebuilder *builder;
@ -11,7 +23,7 @@ void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion(
cl_git_pass(git_oid_fromstr(&oid, blob_oid)); cl_git_pass(git_oid_fromstr(&oid, blob_oid));
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, repo, NULL));
cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0777777)); cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0777777));
cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0100666)); cl_git_fail(git_treebuilder_insert(NULL, builder, "one.txt", &oid, (git_filemode_t)0100666));
@ -22,7 +34,6 @@ void test_object_tree_attributes__ensure_correctness_of_attributes_on_insertion(
void test_object_tree_attributes__group_writable_tree_entries_created_with_an_antique_git_version_can_still_be_accessed(void) void test_object_tree_attributes__group_writable_tree_entries_created_with_an_antique_git_version_can_still_be_accessed(void)
{ {
git_repository *repo;
git_oid tid; git_oid tid;
git_tree *tree; git_tree *tree;
const git_tree_entry *entry; const git_tree_entry *entry;
@ -38,7 +49,6 @@ void test_object_tree_attributes__group_writable_tree_entries_created_with_an_an
git_tree_entry_filemode(entry)); git_tree_entry_filemode(entry));
git_tree_free(tree); git_tree_free(tree);
git_repository_free(repo);
} }
void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void) void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void)
@ -48,7 +58,7 @@ void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void)
const git_tree_entry *entry; const git_tree_entry *entry;
cl_git_pass(git_oid_fromstr(&bid, blob_oid)); cl_git_pass(git_oid_fromstr(&bid, blob_oid));
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, repo, NULL));
cl_git_fail(git_treebuilder_insert( cl_git_fail(git_treebuilder_insert(
&entry, &entry,
@ -62,25 +72,22 @@ void test_object_tree_attributes__treebuilder_reject_invalid_filemode(void)
void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from_an_existing_one(void) void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from_an_existing_one(void)
{ {
git_repository *repo;
git_treebuilder *builder; git_treebuilder *builder;
git_oid tid, tid2; git_oid tid, tid2;
git_tree *tree; git_tree *tree;
const git_tree_entry *entry; const git_tree_entry *entry;
repo = cl_git_sandbox_init("deprecated-mode.git");
cl_git_pass(git_oid_fromstr(&tid, tree_oid)); cl_git_pass(git_oid_fromstr(&tid, tree_oid));
cl_git_pass(git_tree_lookup(&tree, repo, &tid)); cl_git_pass(git_tree_lookup(&tree, repo, &tid));
cl_git_pass(git_treebuilder_create(&builder, tree)); cl_git_pass(git_treebuilder_create(&builder, repo, tree));
entry = git_treebuilder_get(builder, "old_mode.txt"); entry = git_treebuilder_get(builder, "old_mode.txt");
cl_assert_equal_i( cl_assert_equal_i(
GIT_FILEMODE_BLOB, GIT_FILEMODE_BLOB,
git_tree_entry_filemode(entry)); git_tree_entry_filemode(entry));
cl_git_pass(git_treebuilder_write(&tid2, repo, builder)); cl_git_pass(git_treebuilder_write(&tid2, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
git_tree_free(tree); git_tree_free(tree);
@ -91,18 +98,14 @@ void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from
git_tree_entry_filemode(entry)); git_tree_entry_filemode(entry));
git_tree_free(tree); git_tree_free(tree);
cl_git_sandbox_cleanup();
} }
void test_object_tree_attributes__normalize_600(void) void test_object_tree_attributes__normalize_600(void)
{ {
git_oid id; git_oid id;
git_tree *tree; git_tree *tree;
git_repository *repo;
const git_tree_entry *entry; const git_tree_entry *entry;
repo = cl_git_sandbox_init("deprecated-mode.git");
git_oid_fromstr(&id, "0810fb7818088ff5ac41ee49199b51473b1bd6c7"); git_oid_fromstr(&id, "0810fb7818088ff5ac41ee49199b51473b1bd6c7");
cl_git_pass(git_tree_lookup(&tree, repo, &id)); cl_git_pass(git_tree_lookup(&tree, repo, &id));
@ -111,5 +114,4 @@ void test_object_tree_attributes__normalize_600(void)
cl_assert_equal_i(git_tree_entry_filemode_raw(entry), 0100600); cl_assert_equal_i(git_tree_entry_filemode_raw(entry), 0100600);
git_tree_free(tree); git_tree_free(tree);
cl_git_sandbox_cleanup();
} }

View File

@ -57,11 +57,11 @@ static void tree_creator(git_oid *out, void (*fn)(git_treebuilder *))
{ {
git_treebuilder *builder; git_treebuilder *builder;
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, _repo, NULL));
fn(builder); fn(builder);
cl_git_pass(git_treebuilder_write(out, _repo, builder)); cl_git_pass(git_treebuilder_write(out, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
} }

View File

@ -35,7 +35,7 @@ void test_object_tree_write__from_memory(void)
* on REPOSITORY_FOLDER. * on REPOSITORY_FOLDER.
*/ */
cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
cl_git_pass(git_treebuilder_create(&builder, tree)); cl_git_pass(git_treebuilder_create(&builder, g_repo, tree));
cl_git_fail(git_treebuilder_insert(NULL, builder, "", cl_git_fail(git_treebuilder_insert(NULL, builder, "",
&bid, GIT_FILEMODE_BLOB)); &bid, GIT_FILEMODE_BLOB));
@ -53,7 +53,7 @@ void test_object_tree_write__from_memory(void)
cl_git_pass(git_treebuilder_insert( cl_git_pass(git_treebuilder_insert(
NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_write(&rid, g_repo, builder)); cl_git_pass(git_treebuilder_write(&rid, builder));
cl_assert(git_oid_cmp(&rid, &id2) == 0); cl_assert(git_oid_cmp(&rid, &id2) == 0);
@ -75,18 +75,18 @@ void test_object_tree_write__subtree(void)
git_oid_fromstr(&bid, blob_oid); git_oid_fromstr(&bid, blob_oid);
/* create subtree */ /* create subtree */
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
cl_git_pass(git_treebuilder_insert( cl_git_pass(git_treebuilder_insert(
NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); /* -V536 */ NULL, builder, "new.txt", &bid, GIT_FILEMODE_BLOB)); /* -V536 */
cl_git_pass(git_treebuilder_write(&subtree_id, g_repo, builder)); cl_git_pass(git_treebuilder_write(&subtree_id, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
/* create parent tree */ /* create parent tree */
cl_git_pass(git_tree_lookup(&tree, g_repo, &id)); cl_git_pass(git_tree_lookup(&tree, g_repo, &id));
cl_git_pass(git_treebuilder_create(&builder, tree)); cl_git_pass(git_treebuilder_create(&builder, g_repo, tree));
cl_git_pass(git_treebuilder_insert( cl_git_pass(git_treebuilder_insert(
NULL, builder, "new", &subtree_id, GIT_FILEMODE_TREE)); /* -V536 */ NULL, builder, "new", &subtree_id, GIT_FILEMODE_TREE)); /* -V536 */
cl_git_pass(git_treebuilder_write(&id_hiearar, g_repo, builder)); cl_git_pass(git_treebuilder_write(&id_hiearar, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
git_tree_free(tree); git_tree_free(tree);
@ -135,14 +135,14 @@ void test_object_tree_write__sorted_subtrees(void)
memset(&blank_oid, 0x0, sizeof(blank_oid)); memset(&blank_oid, 0x0, sizeof(blank_oid));
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
for (i = 0; i < ARRAY_SIZE(entries); ++i) { for (i = 0; i < ARRAY_SIZE(entries); ++i) {
cl_git_pass(git_treebuilder_insert(NULL, cl_git_pass(git_treebuilder_insert(NULL,
builder, entries[i].filename, &blank_oid, entries[i].attr)); builder, entries[i].filename, &blank_oid, entries[i].attr));
} }
cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, builder)); cl_git_pass(git_treebuilder_write(&tree_oid, builder));
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid)); cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_oid));
for (i = 0; i < git_tree_entrycount(tree); i++) { for (i = 0; i < git_tree_entrycount(tree); i++) {
@ -192,7 +192,7 @@ void test_object_tree_write__removing_and_re_adding_in_treebuilder(void)
memset(&blank_oid, 0x0, sizeof(blank_oid)); memset(&blank_oid, 0x0, sizeof(blank_oid));
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
cl_assert_equal_i(0, (int)git_treebuilder_entrycount(builder)); cl_assert_equal_i(0, (int)git_treebuilder_entrycount(builder));
@ -229,7 +229,7 @@ void test_object_tree_write__removing_and_re_adding_in_treebuilder(void)
NULL, builder, "apple_extra", &blank_oid, GIT_FILEMODE_BLOB)); NULL, builder, "apple_extra", &blank_oid, GIT_FILEMODE_BLOB));
cl_assert_equal_i(7, (int)git_treebuilder_entrycount(builder)); cl_assert_equal_i(7, (int)git_treebuilder_entrycount(builder));
cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, builder)); cl_git_pass(git_treebuilder_write(&tree_oid, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
@ -283,7 +283,7 @@ void test_object_tree_write__filtering(void)
memset(&blank_oid, 0x0, sizeof(blank_oid)); memset(&blank_oid, 0x0, sizeof(blank_oid));
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
for (i = 0; _entries[i].filename; ++i) for (i = 0; _entries[i].filename; ++i)
cl_git_pass(git_treebuilder_insert(NULL, cl_git_pass(git_treebuilder_insert(NULL,
@ -310,7 +310,7 @@ void test_object_tree_write__filtering(void)
cl_assert(git_treebuilder_get(builder, "aardvark") == NULL); cl_assert(git_treebuilder_get(builder, "aardvark") == NULL);
cl_assert(git_treebuilder_get(builder, "last") != NULL); cl_assert(git_treebuilder_get(builder, "last") != NULL);
cl_git_pass(git_treebuilder_write(&tree_oid, g_repo, builder)); cl_git_pass(git_treebuilder_write(&tree_oid, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
@ -346,13 +346,13 @@ void test_object_tree_write__cruel_paths(void)
git_oid_fromstr(&bid, blob_oid); git_oid_fromstr(&bid, blob_oid);
/* create tree */ /* create tree */
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
for (scan = the_paths; *scan; ++scan) { for (scan = the_paths; *scan; ++scan) {
cl_git_pass(git_treebuilder_insert( cl_git_pass(git_treebuilder_insert(
NULL, builder, *scan, &bid, GIT_FILEMODE_BLOB)); NULL, builder, *scan, &bid, GIT_FILEMODE_BLOB));
count++; count++;
} }
cl_git_pass(git_treebuilder_write(&id, g_repo, builder)); cl_git_pass(git_treebuilder_write(&id, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
/* check data is correct */ /* check data is correct */
@ -374,12 +374,12 @@ void test_object_tree_write__cruel_paths(void)
git_tree_free(tree); git_tree_free(tree);
/* let's try longer paths */ /* let's try longer paths */
cl_git_pass(git_treebuilder_create(&builder, NULL)); cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
for (scan = the_paths; *scan; ++scan) { for (scan = the_paths; *scan; ++scan) {
cl_git_pass(git_treebuilder_insert( cl_git_pass(git_treebuilder_insert(
NULL, builder, *scan, &id, GIT_FILEMODE_TREE)); NULL, builder, *scan, &id, GIT_FILEMODE_TREE));
} }
cl_git_pass(git_treebuilder_write(&subid, g_repo, builder)); cl_git_pass(git_treebuilder_write(&subid, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
/* check data is correct */ /* check data is correct */
@ -400,3 +400,43 @@ void test_object_tree_write__cruel_paths(void)
git_tree_free(tree); git_tree_free(tree);
} }
void test_object_tree_write__protect_filesystems(void)
{
git_treebuilder *builder;
git_oid bid;
/* Ensure that (by default) we can write objects with funny names on
* platforms that are not affected.
*/
cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
#ifndef GIT_WIN32
cl_git_pass(git_treebuilder_insert(NULL, builder, ".git.", &bid, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_insert(NULL, builder, "git~1", &bid, GIT_FILEMODE_BLOB));
#endif
#ifndef __APPLE__
cl_git_pass(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", &bid, GIT_FILEMODE_BLOB));
cl_git_pass(git_treebuilder_insert(NULL, builder, ".git\xe2\x80\xad", &bid, GIT_FILEMODE_BLOB));
#endif
git_treebuilder_free(builder);
/* Now turn on core.protectHFS and core.protectNTFS and validate that these
* paths are rejected.
*/
cl_repo_set_bool(g_repo, "core.protectHFS", true);
cl_repo_set_bool(g_repo, "core.protectNTFS", true);
cl_git_pass(git_treebuilder_create(&builder, g_repo, NULL));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git.", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, "git~1", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xef\xbb\xbf", &bid, GIT_FILEMODE_BLOB));
cl_git_fail(git_treebuilder_insert(NULL, builder, ".git\xe2\x80\xad", &bid, GIT_FILEMODE_BLOB));
git_treebuilder_free(builder);
}

View File

@ -427,7 +427,7 @@ static void build_test_tree(
git_buf name = GIT_BUF_INIT; git_buf name = GIT_BUF_INIT;
va_list arglist; va_list arglist;
cl_git_pass(git_treebuilder_create(&builder, NULL)); /* start builder */ cl_git_pass(git_treebuilder_create(&builder, repo, NULL)); /* start builder */
va_start(arglist, fmt); va_start(arglist, fmt);
while (*scan) { while (*scan) {
@ -451,7 +451,7 @@ static void build_test_tree(
} }
va_end(arglist); va_end(arglist);
cl_git_pass(git_treebuilder_write(out, repo, builder)); cl_git_pass(git_treebuilder_write(out, builder));
git_treebuilder_free(builder); git_treebuilder_free(builder);
git_buf_free(&name); git_buf_free(&name);