/* * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * as published by the Free Software Foundation. * * In addition to the permissions in the GNU General Public License, * the authors give you unlimited permission to link the compiled * version of this file into combinations with other programs, * and to distribute those combinations without any restriction * coming from the use of this file. (The General Public License * restrictions do apply in other respects; for example, they cover * modification of the file, and distribution when not linked into * a combined executable.) * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "test_lib.h" #include "t01-data.h" #include "hash.h" BEGIN_TEST("oid", oid_szs) git_oid out; must_be_true(20 == GIT_OID_RAWSZ); must_be_true(40 == GIT_OID_HEXSZ); must_be_true(sizeof(out) == GIT_OID_RAWSZ); must_be_true(sizeof(out.id) == GIT_OID_RAWSZ); END_TEST BEGIN_TEST("oid", empty_string) git_oid out; must_fail(git_oid_mkstr(&out, "")); END_TEST BEGIN_TEST("oid", invalid_string_moo) git_oid out; must_fail(git_oid_mkstr(&out, "moo")); END_TEST static int from_hex(unsigned int i) { if (i >= '0' && i <= '9') return i - '0'; if (i >= 'a' && i <= 'f') return 10 + (i - 'a'); if (i >= 'A' && i <= 'F') return 10 + (i - 'A'); return -1; } BEGIN_TEST("oid", invalid_string_all_chars) git_oid out; unsigned char exp[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; char in[41] = "16a67770b7d8d72317c4b775213c23a8bd74f5e0"; unsigned int i; for (i = 0; i < 256; i++) { in[38] = (char)i; if (from_hex(i) >= 0) { exp[19] = (unsigned char)(from_hex(i) << 4); must_pass(git_oid_mkstr(&out, in)); must_be_true(memcmp(out.id, exp, sizeof(out.id)) == 0); } else { must_fail(git_oid_mkstr(&out, in)); } } END_TEST BEGIN_TEST("oid", invalid_string_16a67770b7d8d72317c4b775213c23a8bd74f5ez) git_oid out; must_fail(git_oid_mkstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5ez")); END_TEST BEGIN_TEST("oid", valid_string_16a67770b7d8d72317c4b775213c23a8bd74f5e0) git_oid out; unsigned char exp[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; must_pass(git_oid_mkstr(&out, "16a67770b7d8d72317c4b775213c23a8bd74f5e0")); must_pass(memcmp(out.id, exp, sizeof(out.id))); must_pass(git_oid_mkstr(&out, "16A67770B7D8D72317C4b775213C23A8BD74F5E0")); must_pass(memcmp(out.id, exp, sizeof(out.id))); END_TEST BEGIN_TEST("oid", valid_raw) git_oid out; unsigned char exp[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; git_oid_mkraw(&out, exp); must_pass(memcmp(out.id, exp, sizeof(out.id))); END_TEST BEGIN_TEST("oid", copy_oid) git_oid a, b; unsigned char exp[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; memset(&b, 0, sizeof(b)); git_oid_mkraw(&a, exp); git_oid_cpy(&b, &a); must_pass(memcmp(a.id, exp, sizeof(a.id))); END_TEST BEGIN_TEST("oid", cmp_oid_lt) git_oid a, b; unsigned char a_in[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; unsigned char b_in[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xf0, }; git_oid_mkraw(&a, a_in); git_oid_mkraw(&b, b_in); must_be_true(git_oid_cmp(&a, &b) < 0); END_TEST BEGIN_TEST("oid", cmp_oid_eq) git_oid a, b; unsigned char a_in[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; git_oid_mkraw(&a, a_in); git_oid_mkraw(&b, a_in); must_be_true(git_oid_cmp(&a, &b) == 0); END_TEST BEGIN_TEST("oid", cmp_oid_gt) git_oid a, b; unsigned char a_in[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xe0, }; unsigned char b_in[] = { 0x16, 0xa6, 0x77, 0x70, 0xb7, 0xd8, 0xd7, 0x23, 0x17, 0xc4, 0xb7, 0x75, 0x21, 0x3c, 0x23, 0xa8, 0xbd, 0x74, 0xf5, 0xd0, }; git_oid_mkraw(&a, a_in); git_oid_mkraw(&b, b_in); must_be_true(git_oid_cmp(&a, &b) > 0); END_TEST BEGIN_TEST("oid", cmp_oid_fmt) const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; char out[GIT_OID_HEXSZ + 1]; must_pass(git_oid_mkstr(&in, exp)); /* Format doesn't touch the last byte */ out[GIT_OID_HEXSZ] = 'Z'; git_oid_fmt(out, &in); must_be_true(out[GIT_OID_HEXSZ] == 'Z'); /* Format produced the right result */ out[GIT_OID_HEXSZ] = '\0'; must_pass(strcmp(exp, out)); END_TEST BEGIN_TEST("oid", cmp_oid_allocfmt) const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; char *out; must_pass(git_oid_mkstr(&in, exp)); out = git_oid_allocfmt(&in); must_be_true(out); must_pass(strcmp(exp, out)); free(out); END_TEST BEGIN_TEST("oid", cmp_oid_pathfmt) const char *exp1 = "16a0123456789abcdef4b775213c23a8bd74f5e0"; const char *exp2 = "16/a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; char out[GIT_OID_HEXSZ + 2]; must_pass(git_oid_mkstr(&in, exp1)); /* Format doesn't touch the last byte */ out[GIT_OID_HEXSZ + 1] = 'Z'; git_oid_pathfmt(out, &in); must_be_true(out[GIT_OID_HEXSZ + 1] == 'Z'); /* Format produced the right result */ out[GIT_OID_HEXSZ + 1] = '\0'; must_pass(strcmp(exp2, out)); END_TEST BEGIN_TEST("oid", oid_to_string) const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; char out[GIT_OID_HEXSZ + 1]; char *str; int i; must_pass(git_oid_mkstr(&in, exp)); /* NULL buffer pointer, returns static empty string */ str = git_oid_to_string(NULL, sizeof(out), &in); must_be_true(str && *str == '\0' && str != out); /* zero buffer size, returns static empty string */ str = git_oid_to_string(out, 0, &in); must_be_true(str && *str == '\0' && str != out); /* NULL oid pointer, returns static empty string */ str = git_oid_to_string(out, sizeof(out), NULL); must_be_true(str && *str == '\0' && str != out); /* n == 1, returns out as an empty string */ str = git_oid_to_string(out, 1, &in); must_be_true(str && *str == '\0' && str == out); for (i = 1; i < GIT_OID_HEXSZ; i++) { out[i+1] = 'Z'; str = git_oid_to_string(out, i+1, &in); /* returns out containing c-string */ must_be_true(str && str == out); /* must be '\0' terminated */ must_be_true(*(str+i) == '\0'); /* must not touch bytes past end of string */ must_be_true(*(str+(i+1)) == 'Z'); /* i == n-1 charaters of string */ must_pass(strncmp(exp, out, i)); } /* returns out as hex formatted c-string */ str = git_oid_to_string(out, sizeof(out), &in); must_be_true(str && str == out && *(str+GIT_OID_HEXSZ) == '\0'); must_pass(strcmp(exp, out)); END_TEST BEGIN_TEST("oid", oid_to_string_big) const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0"; git_oid in; char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */ char *str; must_pass(git_oid_mkstr(&in, exp)); /* place some tail material */ big[GIT_OID_HEXSZ+0] = 'W'; /* should be '\0' afterwards */ big[GIT_OID_HEXSZ+1] = 'X'; /* should remain untouched */ big[GIT_OID_HEXSZ+2] = 'Y'; /* ditto */ big[GIT_OID_HEXSZ+3] = 'Z'; /* ditto */ /* returns big as hex formatted c-string */ str = git_oid_to_string(big, sizeof(big), &in); must_be_true(str && str == big && *(str+GIT_OID_HEXSZ) == '\0'); must_pass(strcmp(exp, big)); /* check tail material is untouched */ must_be_true(str && str == big && *(str+GIT_OID_HEXSZ+1) == 'X'); must_be_true(str && str == big && *(str+GIT_OID_HEXSZ+2) == 'Y'); must_be_true(str && str == big && *(str+GIT_OID_HEXSZ+3) == 'Z'); END_TEST static char *hello_id = "22596363b3de40b06f981fb85d82312e8c0ed511"; static char *hello_text = "hello world\n"; static char *bye_id = "ce08fe4884650f067bd5703b6a59a8b3b3c99a09"; static char *bye_text = "bye world\n"; BEGIN_TEST("hash", hash_iuf) git_hash_ctx *ctx; git_oid id1, id2; must_be_true((ctx = git_hash_new_ctx()) != NULL); /* should already be init'd */ git_hash_update(ctx, hello_text, strlen(hello_text)); git_hash_final(&id2, ctx); must_pass(git_oid_mkstr(&id1, hello_id)); must_be_true(git_oid_cmp(&id1, &id2) == 0); /* reinit should permit reuse */ git_hash_init(ctx); git_hash_update(ctx, bye_text, strlen(bye_text)); git_hash_final(&id2, ctx); must_pass(git_oid_mkstr(&id1, bye_id)); must_be_true(git_oid_cmp(&id1, &id2) == 0); git_hash_free_ctx(ctx); END_TEST BEGIN_TEST("hash", hash_buf) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, hello_id)); git_hash_buf(&id2, hello_text, strlen(hello_text)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("hash", hash_vec) git_oid id1, id2; git_buf_vec vec[2]; must_pass(git_oid_mkstr(&id1, hello_id)); vec[0].data = hello_text; vec[0].len = 4; vec[1].data = hello_text+4; vec[1].len = strlen(hello_text)-4; git_hash_vec(&id2, vec, 2); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("objtype", type_to_string) must_be_true(!strcmp(git_object_type2string(GIT_OBJ_BAD), "")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ__EXT1), "")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ_COMMIT), "commit")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ_TREE), "tree")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ_BLOB), "blob")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ_TAG), "tag")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ__EXT2), "")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ_OFS_DELTA), "OFS_DELTA")); must_be_true(!strcmp(git_object_type2string(GIT_OBJ_REF_DELTA), "REF_DELTA")); must_be_true(!strcmp(git_object_type2string(-2), "")); must_be_true(!strcmp(git_object_type2string(8), "")); must_be_true(!strcmp(git_object_type2string(1234), "")); END_TEST BEGIN_TEST("objtype", string_to_type) must_be_true(git_object_string2type(NULL) == GIT_OBJ_BAD); must_be_true(git_object_string2type("") == GIT_OBJ_BAD); must_be_true(git_object_string2type("commit") == GIT_OBJ_COMMIT); must_be_true(git_object_string2type("tree") == GIT_OBJ_TREE); must_be_true(git_object_string2type("blob") == GIT_OBJ_BLOB); must_be_true(git_object_string2type("tag") == GIT_OBJ_TAG); must_be_true(git_object_string2type("OFS_DELTA") == GIT_OBJ_OFS_DELTA); must_be_true(git_object_string2type("REF_DELTA") == GIT_OBJ_REF_DELTA); must_be_true(git_object_string2type("CoMmIt") == GIT_OBJ_BAD); must_be_true(git_object_string2type("hohoho") == GIT_OBJ_BAD); END_TEST BEGIN_TEST("objtype", loose_object) must_be_true(git_object_typeisloose(GIT_OBJ_BAD) == 0); must_be_true(git_object_typeisloose(GIT_OBJ__EXT1) == 0); must_be_true(git_object_typeisloose(GIT_OBJ_COMMIT) == 1); must_be_true(git_object_typeisloose(GIT_OBJ_TREE) == 1); must_be_true(git_object_typeisloose(GIT_OBJ_BLOB) == 1); must_be_true(git_object_typeisloose(GIT_OBJ_TAG) == 1); must_be_true(git_object_typeisloose(GIT_OBJ__EXT2) == 0); must_be_true(git_object_typeisloose(GIT_OBJ_OFS_DELTA) == 0); must_be_true(git_object_typeisloose(GIT_OBJ_REF_DELTA) == 0); must_be_true(git_object_typeisloose(-2) == 0); must_be_true(git_object_typeisloose(8) == 0); must_be_true(git_object_typeisloose(1234) == 0); END_TEST BEGIN_TEST("objhash", hash_junk) git_oid id, id_zero; must_pass(git_oid_mkstr(&id_zero, zero_id)); /* invalid types: */ junk_obj.data = some_data; must_fail(git_rawobj_hash(&id, &junk_obj)); junk_obj.type = GIT_OBJ__EXT1; must_fail(git_rawobj_hash(&id, &junk_obj)); junk_obj.type = GIT_OBJ__EXT2; must_fail(git_rawobj_hash(&id, &junk_obj)); junk_obj.type = GIT_OBJ_OFS_DELTA; must_fail(git_rawobj_hash(&id, &junk_obj)); junk_obj.type = GIT_OBJ_REF_DELTA; must_fail(git_rawobj_hash(&id, &junk_obj)); /* data can be NULL only if len is zero: */ junk_obj.type = GIT_OBJ_BLOB; junk_obj.data = NULL; must_pass(git_rawobj_hash(&id, &junk_obj)); must_be_true(git_oid_cmp(&id, &id_zero) == 0); junk_obj.len = 1; must_fail(git_rawobj_hash(&id, &junk_obj)); END_TEST BEGIN_TEST("objhash", hash_commit) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, commit_id)); must_pass(git_rawobj_hash(&id2, &commit_obj)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("objhash", hash_tree) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, tree_id)); must_pass(git_rawobj_hash(&id2, &tree_obj)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("objhash", hash_tag) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, tag_id)); must_pass(git_rawobj_hash(&id2, &tag_obj)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("objhash", hash_zero) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, zero_id)); must_pass(git_rawobj_hash(&id2, &zero_obj)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("objhash", hash_one) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, one_id)); must_pass(git_rawobj_hash(&id2, &one_obj)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("objhash", hash_two) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, two_id)); must_pass(git_rawobj_hash(&id2, &two_obj)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST BEGIN_TEST("objhash", hash_some) git_oid id1, id2; must_pass(git_oid_mkstr(&id1, some_id)); must_pass(git_rawobj_hash(&id2, &some_obj)); must_be_true(git_oid_cmp(&id1, &id2) == 0); END_TEST git_testsuite *libgit2_suite_rawobjects(void) { git_testsuite *suite = git_testsuite_new("Raw Objects"); ADD_TEST(suite, "hash", hash_iuf); ADD_TEST(suite, "hash", hash_buf); ADD_TEST(suite, "hash", hash_vec); ADD_TEST(suite, "oid", oid_szs); ADD_TEST(suite, "oid", empty_string); ADD_TEST(suite, "oid", invalid_string_moo); ADD_TEST(suite, "oid", invalid_string_all_chars); ADD_TEST(suite, "oid", invalid_string_16a67770b7d8d72317c4b775213c23a8bd74f5ez); ADD_TEST(suite, "oid", valid_string_16a67770b7d8d72317c4b775213c23a8bd74f5e0); ADD_TEST(suite, "oid", valid_raw); ADD_TEST(suite, "oid", copy_oid); ADD_TEST(suite, "oid", cmp_oid_lt); ADD_TEST(suite, "oid", cmp_oid_eq); ADD_TEST(suite, "oid", cmp_oid_gt); ADD_TEST(suite, "oid", cmp_oid_fmt); ADD_TEST(suite, "oid", cmp_oid_allocfmt); ADD_TEST(suite, "oid", cmp_oid_pathfmt); ADD_TEST(suite, "oid", oid_to_string); ADD_TEST(suite, "oid", oid_to_string_big); ADD_TEST(suite, "objtype", type_to_string); ADD_TEST(suite, "objtype", string_to_type); ADD_TEST(suite, "objtype", loose_object); ADD_TEST(suite, "objhash", hash_junk); ADD_TEST(suite, "objhash", hash_commit); ADD_TEST(suite, "objhash", hash_tree); ADD_TEST(suite, "objhash", hash_tag); ADD_TEST(suite, "objhash", hash_zero); ADD_TEST(suite, "objhash", hash_one); ADD_TEST(suite, "objhash", hash_two); ADD_TEST(suite, "objhash", hash_some); return suite; }