]> git.proxmox.com Git - libgit2.git/blob - tests/object/tree/parse.c
9d76a74f0c25539c5a404debf78ff46376d89fa8
[libgit2.git] / tests / object / tree / parse.c
1 #include "clar_libgit2.h"
2 #include "tree.h"
3 #include "object.h"
4
5 #define OID1_HEX \
6 "\xae\x90\xf1\x2e\xea\x69\x97\x29\xed\x24" \
7 "\x55\x5e\x40\xb9\xfd\x66\x9d\xa1\x2a\x12"
8 #define OID1_STR "ae90f12eea699729ed24555e40b9fd669da12a12"
9
10 #define OID2_HEX \
11 "\xe8\xbf\xe5\xaf\x39\x57\x9a\x7e\x48\x98" \
12 "\xbb\x23\xf3\xa7\x6a\x72\xc3\x68\xce\xe6"
13 #define OID2_STR "e8bfe5af39579a7e4898bb23f3a76a72c368cee6"
14
15 typedef struct {
16 const char *filename;
17 uint16_t attr;
18 const char *oid;
19 } expected_entry;
20
21 static void assert_tree_parses(const char *data, size_t datalen,
22 expected_entry *expected_entries, size_t expected_nentries)
23 {
24 git_tree *tree;
25 size_t n;
26
27 if (!datalen)
28 datalen = strlen(data);
29 cl_git_pass(git_object__from_raw((git_object **) &tree, data, datalen, GIT_OBJECT_TREE));
30
31 cl_assert_equal_i(git_tree_entrycount(tree), expected_nentries);
32
33 for (n = 0; n < expected_nentries; n++) {
34 expected_entry *expected = expected_entries + n;
35 const git_tree_entry *entry;
36 git_oid oid;
37
38 cl_git_pass(git_oid_fromstr(&oid, expected->oid));
39
40 cl_assert(entry = git_tree_entry_byname(tree, expected->filename));
41 cl_assert_equal_s(expected->filename, entry->filename);
42 cl_assert_equal_i(expected->attr, entry->attr);
43 cl_assert_equal_oid(&oid, entry->oid);
44 }
45
46 git_object_free(&tree->object);
47 }
48
49 static void assert_tree_fails(const char *data, size_t datalen)
50 {
51 git_object *object;
52 if (!datalen)
53 datalen = strlen(data);
54 cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TREE));
55 }
56
57 void test_object_tree_parse__single_blob_parses(void)
58 {
59 expected_entry entries[] = {
60 { "foo", 0100644, OID1_STR },
61 };
62 const char data[] = "100644 foo\x00" OID1_HEX;
63
64 assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
65 }
66
67 void test_object_tree_parse__single_tree_parses(void)
68 {
69 expected_entry entries[] = {
70 { "foo", 040000, OID1_STR },
71 };
72 const char data[] = "040000 foo\x00" OID1_HEX;
73
74 assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
75 }
76
77 void test_object_tree_parse__leading_filename_spaces_parse(void)
78 {
79 expected_entry entries[] = {
80 { " bar", 0100644, OID1_STR },
81 };
82 const char data[] = "100644 bar\x00" OID1_HEX;
83
84 assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
85 }
86
87 void test_object_tree_parse__multiple_entries_parse(void)
88 {
89 expected_entry entries[] = {
90 { "bar", 0100644, OID1_STR },
91 { "foo", 040000, OID2_STR },
92 };
93 const char data[] =
94 "100644 bar\x00" OID1_HEX
95 "040000 foo\x00" OID2_HEX;
96
97 assert_tree_parses(data, ARRAY_SIZE(data) - 1, entries, ARRAY_SIZE(entries));
98 }
99
100 void test_object_tree_parse__invalid_mode_fails(void)
101 {
102 const char data[] = "10x644 bar\x00" OID1_HEX;
103 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
104 }
105
106 void test_object_tree_parse__missing_mode_fails(void)
107 {
108 const char data[] = " bar\x00" OID1_HEX;
109 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
110 }
111
112 void test_object_tree_parse__mode_doesnt_cause_oob_read(void)
113 {
114 const char data[] = "100644 bar\x00" OID1_HEX;
115 assert_tree_fails(data, 2);
116 /*
117 * An oob-read would correctly parse the filename and
118 * later fail to parse the OID with a different error
119 * message
120 */
121 cl_assert_equal_s(git_error_last()->message, "failed to parse tree: missing space after filemode");
122 }
123
124 void test_object_tree_parse__unreasonably_large_mode_fails(void)
125 {
126 const char data[] = "10000000000000000000000000 bar\x00" OID1_HEX;
127 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
128 }
129
130 void test_object_tree_parse__missing_filename_separator_fails(void)
131 {
132 const char data[] = "100644bar\x00" OID1_HEX;
133 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
134 }
135
136 void test_object_tree_parse__missing_filename_terminator_fails(void)
137 {
138 const char data[] = "100644 bar" OID1_HEX;
139 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
140 }
141
142 void test_object_tree_parse__empty_filename_fails(void)
143 {
144 const char data[] = "100644 \x00" OID1_HEX;
145 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
146 }
147
148 void test_object_tree_parse__trailing_garbage_fails(void)
149 {
150 const char data[] = "100644 bar\x00" OID1_HEX "x";
151 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
152 }
153
154 void test_object_tree_parse__leading_space_fails(void)
155 {
156 const char data[] = " 100644 bar\x00" OID1_HEX;
157 assert_tree_fails(data, ARRAY_SIZE(data) - 1);
158 }
159
160 void test_object_tree_parse__truncated_oid_fails(void)
161 {
162 const char data[] = " 100644 bar\x00" OID1_HEX;
163 assert_tree_fails(data, ARRAY_SIZE(data) - 2);
164 }