diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2021-11-29 13:44:42 -0500 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2021-11-30 22:45:13 -0500 |
commit | 9f03ebd14b6beb00a9bed52c0568a13f8d5ebb08 (patch) | |
tree | dcec3efee630f9c38e15433302e5c6faec65e517 | |
parent | fc1a3f456540dfc4dc143b322b943a4264658d56 (diff) | |
download | libgit2-9f03ebd14b6beb00a9bed52c0568a13f8d5ebb08.tar.gz |
object: introduce a raw content validation functionethomson/object_validation
Users may want to validate raw object content; provide them a function
to do so.
-rw-r--r-- | include/git2/object.h | 22 | ||||
-rw-r--r-- | src/object.c | 32 | ||||
-rw-r--r-- | tests/object/validate.c | 50 |
3 files changed, 104 insertions, 0 deletions
diff --git a/include/git2/object.h b/include/git2/object.h index 984dbb7ac..dbf480ed6 100644 --- a/include/git2/object.h +++ b/include/git2/object.h @@ -224,6 +224,28 @@ GIT_EXTERN(int) git_object_peel( */ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source); +/** + * Analyzes a buffer of raw object content and determines its validity. + * Tree, commit, and tag objects will be parsed and ensured that they + * are valid, parseable content. (Blobs are always valid by definition.) + * An error message will be set with an informative message if the object + * is not valid. + * + * @warning This function is experimental and its signature may change in + * the future. + * + * @param valid Output pointer to set with validity of the object content + * @param buf The contents to validate + * @param len The length of the buffer + * @param type The type of the object in the buffer + * @return 0 on success or an error code + */ +GIT_EXTERN(int) git_object_rawcontent_is_valid( + int *valid, + const char *buf, + size_t len, + git_object_t type); + /** @} */ GIT_END_DECL diff --git a/src/object.c b/src/object.c index 7e6ad3aa2..7bc256fce 100644 --- a/src/object.c +++ b/src/object.c @@ -567,3 +567,35 @@ bool git_object__is_valid( return true; } + +int git_object_rawcontent_is_valid( + int *valid, + const char *buf, + size_t len, + git_object_t type) +{ + git_object *obj = NULL; + int error; + + GIT_ASSERT_ARG(valid); + GIT_ASSERT_ARG(buf); + + /* Blobs are always valid; don't bother parsing. */ + if (type == GIT_OBJECT_BLOB) { + *valid = 1; + return 0; + } + + error = git_object__from_raw(&obj, buf, len, type); + git_object_free(obj); + + if (error == 0) { + *valid = 1; + return 0; + } else if (error == GIT_EINVALID) { + *valid = 0; + return 0; + } + + return error; +} diff --git a/tests/object/validate.c b/tests/object/validate.c new file mode 100644 index 000000000..87193deb6 --- /dev/null +++ b/tests/object/validate.c @@ -0,0 +1,50 @@ +#include "clar_libgit2.h" + +#define VALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ + "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ + "author Edward Thomson <ethomson@edwardthomson.com> 1638286404 -0500\n" \ + "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" +#define VALID_TREE "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" + +#define INVALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \ + "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \ + "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \ + "\n" \ + "commit go here.\n" +#define INVALID_TREE "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42" + +void test_object_validate__valid(void) +{ + int valid; + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT, CONST_STRLEN(VALID_COMMIT), GIT_OBJECT_COMMIT)); + cl_assert_equal_i(1, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_TREE, CONST_STRLEN(VALID_TREE), GIT_OBJECT_TREE)); + cl_assert_equal_i(1, valid); +} + +void test_object_validate__invalid(void) +{ + int valid; + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_COMMIT, CONST_STRLEN(INVALID_COMMIT), GIT_OBJECT_COMMIT)); + cl_assert_equal_i(0, valid); + + cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE, CONST_STRLEN(INVALID_TREE), GIT_OBJECT_TREE)); + cl_assert_equal_i(0, valid); +} |