Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2bbc7d3

Browse files
author
Edward Thomson
committed
treebuilder: validate tree entries (optionally)
When `GIT_OPT_ENABLE_STRICT_OBJECT_CREATION` is turned on, validate the tree and parent ids given to treebuilder insertion.
1 parent ef63bab commit 2bbc7d3

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

src/tree.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,18 @@ int git_treebuilder_new(
726726
return -1;
727727
}
728728

729+
static git_otype otype_from_mode(git_filemode_t filemode)
730+
{
731+
switch (filemode) {
732+
case GIT_FILEMODE_TREE:
733+
return GIT_OBJ_TREE;
734+
case GIT_FILEMODE_COMMIT:
735+
return GIT_OBJ_COMMIT;
736+
default:
737+
return GIT_OBJ_BLOB;
738+
}
739+
}
740+
729741
int git_treebuilder_insert(
730742
const git_tree_entry **entry_out,
731743
git_treebuilder *bld,
@@ -745,6 +757,9 @@ int git_treebuilder_insert(
745757
if (!valid_entry_name(bld->repo, filename))
746758
return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
747759

760+
if (!git_object__is_valid(bld->repo, id, otype_from_mode(filemode)))
761+
return tree_error("Failed to insert entry; invalid object specified", filename);
762+
748763
pos = git_strmap_lookup_index(bld->map, filename);
749764
if (git_strmap_valid_index(bld->map, pos)) {
750765
entry = git_strmap_value_at(bld->map, pos);

tests/object/tree/write.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ void test_object_tree_write__initialize(void)
1818
void test_object_tree_write__cleanup(void)
1919
{
2020
cl_git_sandbox_cleanup();
21+
22+
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 0));
2123
}
2224

2325
void test_object_tree_write__from_memory(void)
@@ -440,3 +442,56 @@ void test_object_tree_write__protect_filesystems(void)
440442

441443
git_treebuilder_free(builder);
442444
}
445+
446+
static void test_invalid_objects(bool should_allow_invalid)
447+
{
448+
git_treebuilder *builder;
449+
git_oid valid_blob_id, invalid_blob_id, valid_tree_id, invalid_tree_id;
450+
451+
#define assert_allowed(expr) \
452+
clar__assert(!(expr) == should_allow_invalid, __FILE__, __LINE__, \
453+
(should_allow_invalid ? \
454+
"Expected function call to succeed: " #expr : \
455+
"Expected function call to fail: " #expr), \
456+
NULL, 1)
457+
458+
cl_git_pass(git_oid_fromstr(&valid_blob_id, blob_oid));
459+
cl_git_pass(git_oid_fromstr(&invalid_blob_id,
460+
"1234567890123456789012345678901234567890"));
461+
cl_git_pass(git_oid_fromstr(&valid_tree_id, first_tree));
462+
cl_git_pass(git_oid_fromstr(&invalid_tree_id,
463+
"0000000000111111111122222222223333333333"));
464+
465+
cl_git_pass(git_treebuilder_new(&builder, g_repo, NULL));
466+
467+
/* test valid blobs and trees (these should always pass) */
468+
cl_git_pass(git_treebuilder_insert(NULL, builder, "file.txt", &valid_blob_id, GIT_FILEMODE_BLOB));
469+
cl_git_pass(git_treebuilder_insert(NULL, builder, "folder", &valid_tree_id, GIT_FILEMODE_TREE));
470+
471+
/* replace valid files and folders with invalid ones */
472+
assert_allowed(git_treebuilder_insert(NULL, builder, "file.txt", &invalid_blob_id, GIT_FILEMODE_BLOB));
473+
assert_allowed(git_treebuilder_insert(NULL, builder, "folder", &invalid_blob_id, GIT_FILEMODE_BLOB));
474+
475+
/* insert new invalid files and folders */
476+
assert_allowed(git_treebuilder_insert(NULL, builder, "invalid_file.txt", &invalid_blob_id, GIT_FILEMODE_BLOB));
477+
assert_allowed(git_treebuilder_insert(NULL, builder, "invalid_folder", &invalid_blob_id, GIT_FILEMODE_BLOB));
478+
479+
/* insert valid blobs as trees and trees as blobs */
480+
assert_allowed(git_treebuilder_insert(NULL, builder, "file_as_folder", &valid_blob_id, GIT_FILEMODE_TREE));
481+
assert_allowed(git_treebuilder_insert(NULL, builder, "folder_as_file.txt", &valid_tree_id, GIT_FILEMODE_BLOB));
482+
483+
#undef assert_allowed
484+
485+
git_treebuilder_free(builder);
486+
}
487+
488+
void test_object_tree_write__object_validity(void)
489+
{
490+
/* Ensure that we can add invalid objects by default */
491+
test_invalid_objects(true);
492+
493+
/* Ensure that we can turn on validation */
494+
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, 1));
495+
test_invalid_objects(false);
496+
}
497+

0 commit comments

Comments
 (0)