mktag.c: improve verification of tagger field and tests
Since nearly its birth, git's tags have included a "tagger" field which describes the name of tagger, email of tagger, and date and time of tagging. But, this field was only loosely tested by git-mktag. Provide some thorough testing for this field and also ensure that the tag header is separated from the tag body by an empty line to reduce the convenience of creating a flawed tag. Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Brandon Casey committed
Mar 27, 2008 at 11:16 UTC
e0aaf781f656671694a0aa04d8a665bd4d7956e6
2 files changed
+176
-14
mktag.c
+52
-9
@@ -8,10 +8,11 @@
8
* message and a signature block that git itself doesn't care about,
9
* but that can be verified with gpg or similar.
10
*
11
- * The first three lines are guaranteed to be at least 63 bytes:
11
+ * The first four lines are guaranteed to be at least 83 bytes:
12
* "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
13
- * shortest possible type-line, and "tag .\n" at 6 bytes is the
14
- * shortest single-character-tag line.
13
+ * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
14
+ * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
15
+ * the shortest possible tagger-line.
16
*/
17
18
/*
@@ -43,9 +44,9 @@ static int verify_tag(char *buffer, unsigned long size)
44
int typelen;
45
char type[20];
46
unsigned char sha1[20];
46
- const char *object, *type_line, *tag_line, *tagger_line;
47
+ const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb;
48
48
- if (size < 64)
49
+ if (size < 84)
50
return error("wanna fool me ? you obviously got the size wrong !");
51
52
buffer[size] = 0;
@@ -97,11 +98,53 @@ static int verify_tag(char *buffer, unsigned long size)
98
/* Verify the tagger line */
99
tagger_line = tag_line;
100
100
- if (memcmp(tagger_line, "tagger", 6) || (tagger_line[6] == '\n'))
101
- return error("char" PD_FMT ": could not find \"tagger\"", tagger_line - buffer);
101
+ if (memcmp(tagger_line, "tagger ", 7) || (tagger_line[7] == '\n'))
102
+ return error("char" PD_FMT ": could not find \"tagger \"",
103
+ tagger_line - buffer);
104
+
105
+ /*
106
+ * Check for correct form for name and email
107
+ * i.e. " <" followed by "> " on _this_ line
108
+ */
109
+ tagger_line += 7;
110
+ if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
111
+ strchr(tagger_line, '\n') < rb)
112
+ return error("char" PD_FMT ": malformed tagger",
113
+ tagger_line - buffer);
114
+
115
+ /* Check for author name, at least one character, space is acceptable */
116
+ if (lb == tagger_line)
117
+ return error("char" PD_FMT ": missing tagger name",
118
+ tagger_line - buffer);
119
+
120
+ /* timestamp */
121
+ tagger_line = rb + 2;
122
+ if (*tagger_line == ' ')
123
+ return error("char" PD_FMT ": malformed tag timestamp",
124
+ tagger_line - buffer);
125
+ for (;;) {
126
+ unsigned char c = *tagger_line++;
127
+ if (c == ' ')
128
+ break;
129
+ if (isdigit(c))
130
+ continue;
131
+ return error("char" PD_FMT ": malformed tag timestamp",
132
+ tagger_line - buffer);
133
+ }
134
103
- /* TODO: check for committer info + blank line? */
104
- /* Also, the minimum length is probably + "tagger .", or 63+8=71 */
135
+ /* timezone, 5 digits [+-]hhmm, max. 1400 */
136
+ if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
137
+ isdigit(tagger_line[1]) && isdigit(tagger_line[2]) &&
138
+ isdigit(tagger_line[3]) && isdigit(tagger_line[4]) &&
139
+ tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
140
+ return error("char" PD_FMT ": malformed tag timezone",
141
+ tagger_line - buffer);
142
+ tagger_line += 6;
143
+
144
+ /* Verify the blank line separating the header from the body */
145
+ if (*tagger_line != '\n')
146
+ return error("char" PD_FMT ": trailing garbage in tag header",
147
+ tagger_line - buffer);
148
149
/* The actual stuff afterwards we don't care about.. */
150
return 0;
t/t3800-mktag.sh
+124
-5
@@ -44,6 +44,8 @@ cat >tag.sig <<EOF
44
xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
45
type tag
46
tag mytag
47
+tagger . <> 0 +0000
48
+
49
EOF
50
51
check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
@@ -55,6 +57,8 @@ cat >tag.sig <<EOF
57
object zz9e9b33986b1c2670fff52c5067603117b3e895
58
type tag
59
tag mytag
60
+tagger . <> 0 +0000
61
+
62
EOF
63
64
check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
@@ -66,6 +70,8 @@ cat >tag.sig <<EOF
70
object 779e9b33986b1c2670fff52c5067603117b3e895
71
xxxx tag
72
tag mytag
73
+tagger . <> 0 +0000
74
+
75
EOF
76
77
check_verify_failure '"type" line label check' '^error: char47: .*"\\ntype "$'
@@ -85,6 +91,8 @@ cat >tag.sig <<EOF
91
object 779e9b33986b1c2670fff52c5067603117b3e895
92
type tag
93
xxx mytag
94
+tagger . <> 0 +0000
95
+
96
EOF
97
98
check_verify_failure '"tag" line label check #1' \
@@ -121,6 +129,8 @@ cat >tag.sig <<EOF
129
object 779e9b33986b1c2670fff52c5067603117b3e895
130
type tagggg
131
tag mytag
132
+tagger . <> 0 +0000
133
+
134
EOF
135
136
check_verify_failure 'verify object (SHA1/type) check' \
@@ -133,6 +143,8 @@ cat >tag.sig <<EOF
143
object $head
144
type commit
145
tag my tag
146
+tagger . <> 0 +0000
147
+
148
EOF
149
150
check_verify_failure 'verify tag-name check' \
@@ -145,10 +157,12 @@ cat >tag.sig <<EOF
157
object $head
158
type commit
159
tag mytag
160
+
161
+This is filler
162
EOF
163
164
check_verify_failure '"tagger" line label check #1' \
151
- '^error: char70: could not find "tagger"$'
165
+ '^error: char70: could not find "tagger "$'
166
167
############################################################
168
# 12. tagger line label check #2
@@ -158,19 +172,124 @@ object $head
172
type commit
173
tag mytag
174
tagger
175
+
176
+This is filler
177
EOF
178
179
check_verify_failure '"tagger" line label check #2' \
164
- '^error: char70: could not find "tagger"$'
180
+ '^error: char70: could not find "tagger "$'
181
182
############################################################
167
-# 13. create valid tag
183
+# 13. detect missing tag author name
184
185
cat >tag.sig <<EOF
186
object $head
187
type commit
188
tag mytag
173
-tagger another@example.com
189
+tagger <> 0 +0000
190
+
191
+This is filler
192
+EOF
193
+
194
+check_verify_failure 'detect missing tag author name' \
195
+ '^error: char77: missing tagger name$'
196
+
197
+############################################################
198
+# 14. detect missing tag author name
199
+
200
+cat >tag.sig <<EOF
201
+object $head
202
+type commit
203
+tag mytag
204
+tagger T A Gger <
205
+ > 0 +0000
206
+
207
+EOF
208
+
209
+check_verify_failure 'detect malformed tagger' \
210
+ '^error: char77: malformed tagger$'
211
+
212
+############################################################
213
+# 15. allow empty tag email
214
+
215
+cat >tag.sig <<EOF
216
+object $head
217
+type commit
218
+tag mytag
219
+tagger T A Gger <> 0 +0000
220
+
221
+EOF
222
+
223
+test_expect_success \
224
+ 'allow empty tag email' \
225
+ 'git-mktag <tag.sig >.git/refs/tags/mytag 2>message'
226
+
227
+############################################################
228
+# 16. detect missing tag timestamp
229
+
230
+cat >tag.sig <<EOF
231
+object $head
232
+type commit
233
+tag mytag
234
+tagger T A Gger <tagger@example.com>
235
+
236
+EOF
237
+
238
+check_verify_failure 'detect missing tag timestamp' \
239
+ '^error: char107: malformed tag timestamp$'
240
+
241
+############################################################
242
+# 17. detect invalid tag timestamp
243
+
244
+cat >tag.sig <<EOF
245
+object $head
246
+type commit
247
+tag mytag
248
+tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
249
+
250
+EOF
251
+
252
+check_verify_failure 'detect invalid tag timestamp' \
253
+ '^error: char108: malformed tag timestamp$'
254
+
255
+############################################################
256
+# 18. detect invalid tag timezone
257
+
258
+cat >tag.sig <<EOF
259
+object $head
260
+type commit
261
+tag mytag
262
+tagger T A Gger <tagger@example.com> 1206478233 GMT
263
+
264
+EOF
265
+
266
+check_verify_failure 'detect invalid tag timezone' \
267
+ '^error: char118: malformed tag timezone$'
268
+
269
+############################################################
270
+# 19. detect invalid header entry
271
+
272
+cat >tag.sig <<EOF
273
+object $head
274
+type commit
275
+tag mytag
276
+tagger T A Gger <tagger@example.com> 1206478233 -0500
277
+this line should not be here
278
+
279
+EOF
280
+
281
+check_verify_failure 'detect invalid header entry' \
282
+ '^error: char124: trailing garbage in tag header$'
283
+
284
+############################################################
285
+# 20. create valid tag
286
+
287
+cat >tag.sig <<EOF
288
+object $head
289
+type commit
290
+tag mytag
291
+tagger T A Gger <tagger@example.com> 1206478233 -0500
292
+
293
EOF
294
295
test_expect_success \
@@ -178,7 +297,7 @@ test_expect_success \
297
'git-mktag <tag.sig >.git/refs/tags/mytag 2>message'
298
299
############################################################
181
-# 14. check mytag
300
+# 21. check mytag
301
302
test_expect_success \
303
'check mytag' \