Skip to content

Commit 9f03ebd

Browse files
committed
object: introduce a raw content validation function
Users may want to validate raw object content; provide them a function to do so.
1 parent fc1a3f4 commit 9f03ebd

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

include/git2/object.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,28 @@ GIT_EXTERN(int) git_object_peel(
224224
*/
225225
GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
226226

227+
/**
228+
* Analyzes a buffer of raw object content and determines its validity.
229+
* Tree, commit, and tag objects will be parsed and ensured that they
230+
* are valid, parseable content. (Blobs are always valid by definition.)
231+
* An error message will be set with an informative message if the object
232+
* is not valid.
233+
*
234+
* @warning This function is experimental and its signature may change in
235+
* the future.
236+
*
237+
* @param valid Output pointer to set with validity of the object content
238+
* @param buf The contents to validate
239+
* @param len The length of the buffer
240+
* @param type The type of the object in the buffer
241+
* @return 0 on success or an error code
242+
*/
243+
GIT_EXTERN(int) git_object_rawcontent_is_valid(
244+
int *valid,
245+
const char *buf,
246+
size_t len,
247+
git_object_t type);
248+
227249
/** @} */
228250
GIT_END_DECL
229251

src/object.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,3 +567,35 @@ bool git_object__is_valid(
567567

568568
return true;
569569
}
570+
571+
int git_object_rawcontent_is_valid(
572+
int *valid,
573+
const char *buf,
574+
size_t len,
575+
git_object_t type)
576+
{
577+
git_object *obj = NULL;
578+
int error;
579+
580+
GIT_ASSERT_ARG(valid);
581+
GIT_ASSERT_ARG(buf);
582+
583+
/* Blobs are always valid; don't bother parsing. */
584+
if (type == GIT_OBJECT_BLOB) {
585+
*valid = 1;
586+
return 0;
587+
}
588+
589+
error = git_object__from_raw(&obj, buf, len, type);
590+
git_object_free(obj);
591+
592+
if (error == 0) {
593+
*valid = 1;
594+
return 0;
595+
} else if (error == GIT_EINVALID) {
596+
*valid = 0;
597+
return 0;
598+
}
599+
600+
return error;
601+
}

tests/object/validate.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "clar_libgit2.h"
2+
3+
#define VALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \
4+
"parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \
5+
"author Edward Thomson <ethomson@edwardthomson.com> 1638286404 -0500\n" \
6+
"committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
7+
"\n" \
8+
"commit go here.\n"
9+
#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"
10+
11+
#define INVALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \
12+
"parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \
13+
"committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
14+
"\n" \
15+
"commit go here.\n"
16+
#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"
17+
18+
void test_object_validate__valid(void)
19+
{
20+
int valid;
21+
22+
cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB));
23+
cl_assert_equal_i(1, valid);
24+
25+
cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB));
26+
cl_assert_equal_i(1, valid);
27+
28+
cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT, CONST_STRLEN(VALID_COMMIT), GIT_OBJECT_COMMIT));
29+
cl_assert_equal_i(1, valid);
30+
31+
cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_TREE, CONST_STRLEN(VALID_TREE), GIT_OBJECT_TREE));
32+
cl_assert_equal_i(1, valid);
33+
}
34+
35+
void test_object_validate__invalid(void)
36+
{
37+
int valid;
38+
39+
cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT));
40+
cl_assert_equal_i(0, valid);
41+
42+
cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT));
43+
cl_assert_equal_i(0, valid);
44+
45+
cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_COMMIT, CONST_STRLEN(INVALID_COMMIT), GIT_OBJECT_COMMIT));
46+
cl_assert_equal_i(0, valid);
47+
48+
cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE, CONST_STRLEN(INVALID_TREE), GIT_OBJECT_TREE));
49+
cl_assert_equal_i(0, valid);
50+
}

0 commit comments

Comments
 (0)