1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 package org.eclipse.jgit.lib;
46
47 import static java.lang.Integer.valueOf;
48 import static java.lang.Long.valueOf;
49 import static org.junit.Assert.assertEquals;
50 import static org.junit.Assert.fail;
51
52 import java.io.UnsupportedEncodingException;
53 import java.text.MessageFormat;
54
55 import org.eclipse.jgit.errors.CorruptObjectException;
56 import org.eclipse.jgit.internal.JGitText;
57 import org.junit.Before;
58 import org.junit.Test;
59
60 public class ObjectCheckerTest {
61 private ObjectChecker checker;
62
63 @Before
64 public void setUp() throws Exception {
65 checker = new ObjectChecker();
66 }
67
68 @Test
69 public void testInvalidType() {
70 try {
71 checker.check(Constants.OBJ_BAD, new byte[0]);
72 fail("Did not throw CorruptObjectException");
73 } catch (CorruptObjectException e) {
74 final String m = e.getMessage();
75 assertEquals(MessageFormat.format(
76 JGitText.get().corruptObjectInvalidType2,
77 valueOf(Constants.OBJ_BAD)), m);
78 }
79 }
80
81 @Test
82 public void testCheckBlob() throws CorruptObjectException {
83
84 checker.checkBlob(new byte[0]);
85 checker.checkBlob(new byte[1]);
86
87 checker.check(Constants.OBJ_BLOB, new byte[0]);
88 checker.check(Constants.OBJ_BLOB, new byte[1]);
89 }
90
91 @Test
92 public void testValidCommitNoParent() throws CorruptObjectException {
93 final StringBuilder b = new StringBuilder();
94
95 b.append("tree ");
96 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
97 b.append('\n');
98
99 b.append("author A. U. Thor <author@localhost> 1 +0000\n");
100 b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
101
102 final byte[] data = Constants.encodeASCII(b.toString());
103 checker.checkCommit(data);
104 checker.check(Constants.OBJ_COMMIT, data);
105 }
106
107 @Test
108 public void testValidCommitBlankAuthor() throws CorruptObjectException {
109 final StringBuilder b = new StringBuilder();
110
111 b.append("tree ");
112 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
113 b.append('\n');
114
115 b.append("author <> 0 +0000\n");
116 b.append("committer <> 0 +0000\n");
117
118 final byte[] data = Constants.encodeASCII(b.toString());
119 checker.checkCommit(data);
120 checker.check(Constants.OBJ_COMMIT, data);
121 }
122
123 @Test
124 public void testCommitCorruptAuthor() throws CorruptObjectException {
125 StringBuilder b = new StringBuilder();
126 b.append("tree be9bfa841874ccc9f2ef7c48d0c76226f89b7189\n");
127 b.append("author b <b@c> <b@c> 0 +0000\n");
128 b.append("committer <> 0 +0000\n");
129
130 byte[] data = Constants.encodeASCII(b.toString());
131 try {
132 checker.checkCommit(data);
133 fail("Did not catch corrupt object");
134 } catch (CorruptObjectException e) {
135 assertEquals("invalid author", e.getMessage());
136 }
137 checker.setAllowInvalidPersonIdent(true);
138 checker.checkCommit(data);
139 }
140
141 @Test
142 public void testCommitCorruptCommitter() throws CorruptObjectException {
143 StringBuilder b = new StringBuilder();
144 b.append("tree be9bfa841874ccc9f2ef7c48d0c76226f89b7189\n");
145 b.append("author <> 0 +0000\n");
146 b.append("committer b <b@c> <b@c> 0 +0000\n");
147
148 byte[] data = Constants.encodeASCII(b.toString());
149 try {
150 checker.checkCommit(data);
151 fail("Did not catch corrupt object");
152 } catch (CorruptObjectException e) {
153 assertEquals("invalid committer", e.getMessage());
154 }
155 checker.setAllowInvalidPersonIdent(true);
156 checker.checkCommit(data);
157 }
158
159 @Test
160 public void testValidCommit1Parent() throws CorruptObjectException {
161 final StringBuilder b = new StringBuilder();
162
163 b.append("tree ");
164 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
165 b.append('\n');
166
167 b.append("parent ");
168 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
169 b.append('\n');
170
171 b.append("author A. U. Thor <author@localhost> 1 +0000\n");
172 b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
173
174 final byte[] data = Constants.encodeASCII(b.toString());
175 checker.checkCommit(data);
176 checker.check(Constants.OBJ_COMMIT, data);
177 }
178
179 @Test
180 public void testValidCommit2Parent() throws CorruptObjectException {
181 final StringBuilder b = new StringBuilder();
182
183 b.append("tree ");
184 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
185 b.append('\n');
186
187 b.append("parent ");
188 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
189 b.append('\n');
190
191 b.append("parent ");
192 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
193 b.append('\n');
194
195 b.append("author A. U. Thor <author@localhost> 1 +0000\n");
196 b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
197
198 final byte[] data = Constants.encodeASCII(b.toString());
199 checker.checkCommit(data);
200 checker.check(Constants.OBJ_COMMIT, data);
201 }
202
203 @Test
204 public void testValidCommit128Parent() throws CorruptObjectException {
205 final StringBuilder b = new StringBuilder();
206
207 b.append("tree ");
208 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
209 b.append('\n');
210
211 for (int i = 0; i < 128; i++) {
212 b.append("parent ");
213 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
214 b.append('\n');
215 }
216
217 b.append("author A. U. Thor <author@localhost> 1 +0000\n");
218 b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
219
220 final byte[] data = Constants.encodeASCII(b.toString());
221 checker.checkCommit(data);
222 checker.check(Constants.OBJ_COMMIT, data);
223 }
224
225 @Test
226 public void testValidCommitNormalTime() throws CorruptObjectException {
227 final StringBuilder b = new StringBuilder();
228 final String when = "1222757360 -0730";
229
230 b.append("tree ");
231 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
232 b.append('\n');
233
234 b.append("author A. U. Thor <author@localhost> " + when + "\n");
235 b.append("committer A. U. Thor <author@localhost> " + when + "\n");
236
237 final byte[] data = Constants.encodeASCII(b.toString());
238 checker.checkCommit(data);
239 checker.check(Constants.OBJ_COMMIT, data);
240 }
241
242 @Test
243 public void testInvalidCommitNoTree1() {
244 final StringBuilder b = new StringBuilder();
245
246 b.append("parent ");
247 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
248 b.append('\n');
249
250 final byte[] data = Constants.encodeASCII(b.toString());
251 try {
252 checker.checkCommit(data);
253 fail("Did not catch corrupt object");
254 } catch (CorruptObjectException e) {
255 assertEquals("no tree header", e.getMessage());
256 }
257 }
258
259 @Test
260 public void testInvalidCommitNoTree2() {
261 final StringBuilder b = new StringBuilder();
262
263 b.append("trie ");
264 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
265 b.append('\n');
266
267 final byte[] data = Constants.encodeASCII(b.toString());
268 try {
269 checker.checkCommit(data);
270 fail("Did not catch corrupt object");
271 } catch (CorruptObjectException e) {
272 assertEquals("no tree header", e.getMessage());
273 }
274 }
275
276 @Test
277 public void testInvalidCommitNoTree3() {
278 final StringBuilder b = new StringBuilder();
279
280 b.append("tree");
281 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
282 b.append('\n');
283
284 final byte[] data = Constants.encodeASCII(b.toString());
285 try {
286 checker.checkCommit(data);
287 fail("Did not catch corrupt object");
288 } catch (CorruptObjectException e) {
289 assertEquals("no tree header", e.getMessage());
290 }
291 }
292
293 @Test
294 public void testInvalidCommitNoTree4() {
295 final StringBuilder b = new StringBuilder();
296
297 b.append("tree\t");
298 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
299 b.append('\n');
300
301 final byte[] data = Constants.encodeASCII(b.toString());
302 try {
303 checker.checkCommit(data);
304 fail("Did not catch corrupt object");
305 } catch (CorruptObjectException e) {
306 assertEquals("no tree header", e.getMessage());
307 }
308 }
309
310 @Test
311 public void testInvalidCommitInvalidTree1() {
312 final StringBuilder b = new StringBuilder();
313
314 b.append("tree ");
315 b.append("zzzzfa841874ccc9f2ef7c48d0c76226f89b7189");
316 b.append('\n');
317
318 final byte[] data = Constants.encodeASCII(b.toString());
319 try {
320 checker.checkCommit(data);
321 fail("Did not catch corrupt object");
322 } catch (CorruptObjectException e) {
323 assertEquals("invalid tree", e.getMessage());
324 }
325 }
326
327 @Test
328 public void testInvalidCommitInvalidTree2() {
329 final StringBuilder b = new StringBuilder();
330
331 b.append("tree ");
332 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
333 b.append("z\n");
334
335 final byte[] data = Constants.encodeASCII(b.toString());
336 try {
337 checker.checkCommit(data);
338 fail("Did not catch corrupt object");
339 } catch (CorruptObjectException e) {
340 assertEquals("invalid tree", e.getMessage());
341 }
342 }
343
344 @Test
345 public void testInvalidCommitInvalidTree3() {
346 final StringBuilder b = new StringBuilder();
347
348 b.append("tree ");
349 b.append("be9b");
350 b.append("\n");
351
352 final byte[] data = Constants.encodeASCII(b.toString());
353 try {
354 checker.checkCommit(data);
355 fail("Did not catch corrupt object");
356 } catch (CorruptObjectException e) {
357 assertEquals("invalid tree", e.getMessage());
358 }
359 }
360
361 @Test
362 public void testInvalidCommitInvalidTree4() {
363 final StringBuilder b = new StringBuilder();
364
365 b.append("tree ");
366 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
367 b.append('\n');
368
369 final byte[] data = Constants.encodeASCII(b.toString());
370 try {
371 checker.checkCommit(data);
372 fail("Did not catch corrupt object");
373 } catch (CorruptObjectException e) {
374 assertEquals("invalid tree", e.getMessage());
375 }
376 }
377
378 @Test
379 public void testInvalidCommitInvalidParent1() {
380 final StringBuilder b = new StringBuilder();
381
382 b.append("tree ");
383 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
384 b.append('\n');
385
386 b.append("parent ");
387 b.append("\n");
388
389 final byte[] data = Constants.encodeASCII(b.toString());
390 try {
391 checker.checkCommit(data);
392 fail("Did not catch corrupt object");
393 } catch (CorruptObjectException e) {
394 assertEquals("invalid parent", e.getMessage());
395 }
396 }
397
398 @Test
399 public void testInvalidCommitInvalidParent2() {
400 final StringBuilder b = new StringBuilder();
401
402 b.append("tree ");
403 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
404 b.append('\n');
405
406 b.append("parent ");
407 b.append("zzzzfa841874ccc9f2ef7c48d0c76226f89b7189");
408 b.append("\n");
409
410 final byte[] data = Constants.encodeASCII(b.toString());
411 try {
412 checker.checkCommit(data);
413 fail("Did not catch corrupt object");
414 } catch (CorruptObjectException e) {
415 assertEquals("invalid parent", e.getMessage());
416 }
417 }
418
419 @Test
420 public void testInvalidCommitInvalidParent3() {
421 final StringBuilder b = new StringBuilder();
422
423 b.append("tree ");
424 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
425 b.append('\n');
426
427 b.append("parent ");
428 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
429 b.append("\n");
430
431 final byte[] data = Constants.encodeASCII(b.toString());
432 try {
433 checker.checkCommit(data);
434 fail("Did not catch corrupt object");
435 } catch (CorruptObjectException e) {
436 assertEquals("invalid parent", e.getMessage());
437 }
438 }
439
440 @Test
441 public void testInvalidCommitInvalidParent4() {
442 final StringBuilder b = new StringBuilder();
443
444 b.append("tree ");
445 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
446 b.append('\n');
447
448 b.append("parent ");
449 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
450 b.append("z\n");
451
452 final byte[] data = Constants.encodeASCII(b.toString());
453 try {
454 checker.checkCommit(data);
455 fail("Did not catch corrupt object");
456 } catch (CorruptObjectException e) {
457 assertEquals("invalid parent", e.getMessage());
458 }
459 }
460
461 @Test
462 public void testInvalidCommitInvalidParent5() {
463 final StringBuilder b = new StringBuilder();
464
465 b.append("tree ");
466 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
467 b.append('\n');
468
469 b.append("parent\t");
470 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
471 b.append("\n");
472
473 final byte[] data = Constants.encodeASCII(b.toString());
474 try {
475 checker.checkCommit(data);
476 fail("Did not catch corrupt object");
477 } catch (CorruptObjectException e) {
478
479
480 assertEquals("no author", e.getMessage());
481 }
482 }
483
484 @Test
485 public void testInvalidCommitNoAuthor() {
486 final StringBuilder b = new StringBuilder();
487
488 b.append("tree ");
489 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
490 b.append('\n');
491
492 b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
493
494 final byte[] data = Constants.encodeASCII(b.toString());
495 try {
496 checker.checkCommit(data);
497 fail("Did not catch corrupt object");
498 } catch (CorruptObjectException e) {
499
500
501 assertEquals("no author", e.getMessage());
502 }
503 }
504
505 @Test
506 public void testInvalidCommitNoCommitter1() {
507 final StringBuilder b = new StringBuilder();
508
509 b.append("tree ");
510 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
511 b.append('\n');
512
513 b.append("author A. U. Thor <author@localhost> 1 +0000\n");
514
515 final byte[] data = Constants.encodeASCII(b.toString());
516 try {
517 checker.checkCommit(data);
518 fail("Did not catch corrupt object");
519 } catch (CorruptObjectException e) {
520
521
522 assertEquals("no committer", e.getMessage());
523 }
524 }
525
526 @Test
527 public void testInvalidCommitNoCommitter2() {
528 final StringBuilder b = new StringBuilder();
529
530 b.append("tree ");
531 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
532 b.append('\n');
533
534 b.append("author A. U. Thor <author@localhost> 1 +0000\n");
535 b.append("\n");
536
537 final byte[] data = Constants.encodeASCII(b.toString());
538 try {
539 checker.checkCommit(data);
540 fail("Did not catch corrupt object");
541 } catch (CorruptObjectException e) {
542
543
544 assertEquals("no committer", e.getMessage());
545 }
546 }
547
548 @Test
549 public void testInvalidCommitInvalidAuthor1() {
550 final StringBuilder b = new StringBuilder();
551
552 b.append("tree ");
553 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
554 b.append('\n');
555
556 b.append("author A. U. Thor <foo 1 +0000\n");
557
558 final byte[] data = Constants.encodeASCII(b.toString());
559 try {
560 checker.checkCommit(data);
561 fail("Did not catch corrupt object");
562 } catch (CorruptObjectException e) {
563
564
565 assertEquals("invalid author", e.getMessage());
566 }
567 }
568
569 @Test
570 public void testInvalidCommitInvalidAuthor2() {
571 final StringBuilder b = new StringBuilder();
572
573 b.append("tree ");
574 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
575 b.append('\n');
576
577 b.append("author A. U. Thor foo> 1 +0000\n");
578
579 final byte[] data = Constants.encodeASCII(b.toString());
580 try {
581 checker.checkCommit(data);
582 fail("Did not catch corrupt object");
583 } catch (CorruptObjectException e) {
584
585
586 assertEquals("invalid author", e.getMessage());
587 }
588 }
589
590 @Test
591 public void testInvalidCommitInvalidAuthor3() {
592 final StringBuilder b = new StringBuilder();
593
594 b.append("tree ");
595 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
596 b.append('\n');
597
598 b.append("author 1 +0000\n");
599
600 final byte[] data = Constants.encodeASCII(b.toString());
601 try {
602 checker.checkCommit(data);
603 fail("Did not catch corrupt object");
604 } catch (CorruptObjectException e) {
605
606
607 assertEquals("invalid author", e.getMessage());
608 }
609 }
610
611 @Test
612 public void testInvalidCommitInvalidAuthor4() {
613 final StringBuilder b = new StringBuilder();
614
615 b.append("tree ");
616 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
617 b.append('\n');
618
619 b.append("author a <b> +0000\n");
620
621 final byte[] data = Constants.encodeASCII(b.toString());
622 try {
623 checker.checkCommit(data);
624 fail("Did not catch corrupt object");
625 } catch (CorruptObjectException e) {
626
627
628 assertEquals("invalid author", e.getMessage());
629 }
630 }
631
632 @Test
633 public void testInvalidCommitInvalidAuthor5() {
634 final StringBuilder b = new StringBuilder();
635
636 b.append("tree ");
637 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
638 b.append('\n');
639
640 b.append("author a <b>\n");
641
642 final byte[] data = Constants.encodeASCII(b.toString());
643 try {
644 checker.checkCommit(data);
645 fail("Did not catch corrupt object");
646 } catch (CorruptObjectException e) {
647
648
649 assertEquals("invalid author", e.getMessage());
650 }
651 }
652
653 @Test
654 public void testInvalidCommitInvalidAuthor6() {
655 final StringBuilder b = new StringBuilder();
656
657 b.append("tree ");
658 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
659 b.append('\n');
660
661 b.append("author a <b> z");
662
663 final byte[] data = Constants.encodeASCII(b.toString());
664 try {
665 checker.checkCommit(data);
666 fail("Did not catch corrupt object");
667 } catch (CorruptObjectException e) {
668
669
670 assertEquals("invalid author", e.getMessage());
671 }
672 }
673
674 @Test
675 public void testInvalidCommitInvalidAuthor7() {
676 final StringBuilder b = new StringBuilder();
677
678 b.append("tree ");
679 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
680 b.append('\n');
681
682 b.append("author a <b> 1 z");
683
684 final byte[] data = Constants.encodeASCII(b.toString());
685 try {
686 checker.checkCommit(data);
687 fail("Did not catch corrupt object");
688 } catch (CorruptObjectException e) {
689
690
691 assertEquals("invalid author", e.getMessage());
692 }
693 }
694
695 @Test
696 public void testInvalidCommitInvalidCommitter() {
697 final StringBuilder b = new StringBuilder();
698
699 b.append("tree ");
700 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
701 b.append('\n');
702
703 b.append("author a <b> 1 +0000\n");
704 b.append("committer a <");
705
706 final byte[] data = Constants.encodeASCII(b.toString());
707 try {
708 checker.checkCommit(data);
709 fail("Did not catch corrupt object");
710 } catch (CorruptObjectException e) {
711
712
713 assertEquals("invalid committer", e.getMessage());
714 }
715 }
716
717 @Test
718 public void testValidTag() throws CorruptObjectException {
719 final StringBuilder b = new StringBuilder();
720
721 b.append("object ");
722 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
723 b.append('\n');
724
725 b.append("type commit\n");
726 b.append("tag test-tag\n");
727 b.append("tagger A. U. Thor <author@localhost> 1 +0000\n");
728
729 final byte[] data = Constants.encodeASCII(b.toString());
730 checker.checkTag(data);
731 checker.check(Constants.OBJ_TAG, data);
732 }
733
734 @Test
735 public void testInvalidTagNoObject1() {
736 final StringBuilder b = new StringBuilder();
737
738 final byte[] data = Constants.encodeASCII(b.toString());
739 try {
740 checker.checkTag(data);
741 fail("incorrectly accepted invalid tag");
742 } catch (CorruptObjectException e) {
743 assertEquals("no object header", e.getMessage());
744 }
745 }
746
747 @Test
748 public void testInvalidTagNoObject2() {
749 final StringBuilder b = new StringBuilder();
750
751 b.append("object\t");
752 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
753 b.append('\n');
754
755 final byte[] data = Constants.encodeASCII(b.toString());
756 try {
757 checker.checkTag(data);
758 fail("incorrectly accepted invalid tag");
759 } catch (CorruptObjectException e) {
760 assertEquals("no object header", e.getMessage());
761 }
762 }
763
764 @Test
765 public void testInvalidTagNoObject3() {
766 final StringBuilder b = new StringBuilder();
767
768 b.append("obejct ");
769 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
770 b.append('\n');
771
772 final byte[] data = Constants.encodeASCII(b.toString());
773 try {
774 checker.checkTag(data);
775 fail("incorrectly accepted invalid tag");
776 } catch (CorruptObjectException e) {
777 assertEquals("no object header", e.getMessage());
778 }
779 }
780
781 @Test
782 public void testInvalidTagNoObject4() {
783 final StringBuilder b = new StringBuilder();
784
785 b.append("object ");
786 b.append("zz9bfa841874ccc9f2ef7c48d0c76226f89b7189");
787 b.append('\n');
788
789 final byte[] data = Constants.encodeASCII(b.toString());
790 try {
791 checker.checkTag(data);
792 fail("incorrectly accepted invalid tag");
793 } catch (CorruptObjectException e) {
794 assertEquals("invalid object", e.getMessage());
795 }
796 }
797
798 @Test
799 public void testInvalidTagNoObject5() {
800 final StringBuilder b = new StringBuilder();
801
802 b.append("object ");
803 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
804 b.append(" \n");
805
806 final byte[] data = Constants.encodeASCII(b.toString());
807 try {
808 checker.checkTag(data);
809 fail("incorrectly accepted invalid tag");
810 } catch (CorruptObjectException e) {
811 assertEquals("invalid object", e.getMessage());
812 }
813 }
814
815 @Test
816 public void testInvalidTagNoObject6() {
817 final StringBuilder b = new StringBuilder();
818
819 b.append("object ");
820 b.append("be9");
821
822 final byte[] data = Constants.encodeASCII(b.toString());
823 try {
824 checker.checkTag(data);
825 fail("incorrectly accepted invalid tag");
826 } catch (CorruptObjectException e) {
827 assertEquals("invalid object", e.getMessage());
828 }
829 }
830
831 @Test
832 public void testInvalidTagNoType1() {
833 final StringBuilder b = new StringBuilder();
834
835 b.append("object ");
836 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
837 b.append('\n');
838
839 final byte[] data = Constants.encodeASCII(b.toString());
840 try {
841 checker.checkTag(data);
842 fail("incorrectly accepted invalid tag");
843 } catch (CorruptObjectException e) {
844 assertEquals("no type header", e.getMessage());
845 }
846 }
847
848 @Test
849 public void testInvalidTagNoType2() {
850 final StringBuilder b = new StringBuilder();
851
852 b.append("object ");
853 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
854 b.append('\n');
855
856 b.append("type\tcommit\n");
857
858 final byte[] data = Constants.encodeASCII(b.toString());
859 try {
860 checker.checkTag(data);
861 fail("incorrectly accepted invalid tag");
862 } catch (CorruptObjectException e) {
863 assertEquals("no type header", e.getMessage());
864 }
865 }
866
867 @Test
868 public void testInvalidTagNoType3() {
869 final StringBuilder b = new StringBuilder();
870
871 b.append("object ");
872 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
873 b.append('\n');
874
875 b.append("tpye commit\n");
876
877 final byte[] data = Constants.encodeASCII(b.toString());
878 try {
879 checker.checkTag(data);
880 fail("incorrectly accepted invalid tag");
881 } catch (CorruptObjectException e) {
882 assertEquals("no type header", e.getMessage());
883 }
884 }
885
886 @Test
887 public void testInvalidTagNoType4() {
888 final StringBuilder b = new StringBuilder();
889
890 b.append("object ");
891 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
892 b.append('\n');
893
894 b.append("type commit");
895
896 final byte[] data = Constants.encodeASCII(b.toString());
897 try {
898 checker.checkTag(data);
899 fail("incorrectly accepted invalid tag");
900 } catch (CorruptObjectException e) {
901 assertEquals("no tag header", e.getMessage());
902 }
903 }
904
905 @Test
906 public void testInvalidTagNoTagHeader1() {
907 final StringBuilder b = new StringBuilder();
908
909 b.append("object ");
910 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
911 b.append('\n');
912
913 b.append("type commit\n");
914
915 final byte[] data = Constants.encodeASCII(b.toString());
916 try {
917 checker.checkTag(data);
918 fail("incorrectly accepted invalid tag");
919 } catch (CorruptObjectException e) {
920 assertEquals("no tag header", e.getMessage());
921 }
922 }
923
924 @Test
925 public void testInvalidTagNoTagHeader2() {
926 final StringBuilder b = new StringBuilder();
927
928 b.append("object ");
929 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
930 b.append('\n');
931
932 b.append("type commit\n");
933 b.append("tag\tfoo\n");
934
935 final byte[] data = Constants.encodeASCII(b.toString());
936 try {
937 checker.checkTag(data);
938 fail("incorrectly accepted invalid tag");
939 } catch (CorruptObjectException e) {
940 assertEquals("no tag header", e.getMessage());
941 }
942 }
943
944 @Test
945 public void testInvalidTagNoTagHeader3() {
946 final StringBuilder b = new StringBuilder();
947
948 b.append("object ");
949 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
950 b.append('\n');
951
952 b.append("type commit\n");
953 b.append("tga foo\n");
954
955 final byte[] data = Constants.encodeASCII(b.toString());
956 try {
957 checker.checkTag(data);
958 fail("incorrectly accepted invalid tag");
959 } catch (CorruptObjectException e) {
960 assertEquals("no tag header", e.getMessage());
961 }
962 }
963
964 @Test
965 public void testValidTagHasNoTaggerHeader() throws CorruptObjectException {
966 final StringBuilder b = new StringBuilder();
967
968 b.append("object ");
969 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
970 b.append('\n');
971
972 b.append("type commit\n");
973 b.append("tag foo\n");
974
975 checker.checkTag(Constants.encodeASCII(b.toString()));
976 }
977
978 @Test
979 public void testInvalidTagInvalidTaggerHeader1()
980 throws CorruptObjectException {
981 final StringBuilder b = new StringBuilder();
982
983 b.append("object ");
984 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
985 b.append('\n');
986
987 b.append("type commit\n");
988 b.append("tag foo\n");
989 b.append("tagger \n");
990
991 final byte[] data = Constants.encodeASCII(b.toString());
992 try {
993 checker.checkTag(data);
994 fail("incorrectly accepted invalid tag");
995 } catch (CorruptObjectException e) {
996 assertEquals("invalid tagger", e.getMessage());
997 }
998 checker.setAllowInvalidPersonIdent(true);
999 checker.checkTag(data);
1000 }
1001
1002 @Test
1003 public void testInvalidTagInvalidTaggerHeader3() {
1004 final StringBuilder b = new StringBuilder();
1005
1006 b.append("object ");
1007 b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
1008 b.append('\n');
1009
1010 b.append("type commit\n");
1011 b.append("tag foo\n");
1012 b.append("tagger a < 1 +000\n");
1013
1014 final byte[] data = Constants.encodeASCII(b.toString());
1015 try {
1016 checker.checkTag(data);
1017 fail("incorrectly accepted invalid tag");
1018 } catch (CorruptObjectException e) {
1019 assertEquals("invalid tagger", e.getMessage());
1020 }
1021 }
1022
1023 @Test
1024 public void testValidEmptyTree() throws CorruptObjectException {
1025 checker.checkTree(new byte[0]);
1026 checker.check(Constants.OBJ_TREE, new byte[0]);
1027 }
1028
1029 @Test
1030 public void testValidTree1() throws CorruptObjectException {
1031 final StringBuilder b = new StringBuilder();
1032 entry(b, "100644 regular-file");
1033 final byte[] data = Constants.encodeASCII(b.toString());
1034 checker.checkTree(data);
1035 }
1036
1037 @Test
1038 public void testValidTree2() throws CorruptObjectException {
1039 final StringBuilder b = new StringBuilder();
1040 entry(b, "100755 executable");
1041 final byte[] data = Constants.encodeASCII(b.toString());
1042 checker.checkTree(data);
1043 }
1044
1045 @Test
1046 public void testValidTree3() throws CorruptObjectException {
1047 final StringBuilder b = new StringBuilder();
1048 entry(b, "40000 tree");
1049 final byte[] data = Constants.encodeASCII(b.toString());
1050 checker.checkTree(data);
1051 }
1052
1053 @Test
1054 public void testValidTree4() throws CorruptObjectException {
1055 final StringBuilder b = new StringBuilder();
1056 entry(b, "120000 symlink");
1057 final byte[] data = Constants.encodeASCII(b.toString());
1058 checker.checkTree(data);
1059 }
1060
1061 @Test
1062 public void testValidTree5() throws CorruptObjectException {
1063 final StringBuilder b = new StringBuilder();
1064 entry(b, "160000 git link");
1065 final byte[] data = Constants.encodeASCII(b.toString());
1066 checker.checkTree(data);
1067 }
1068
1069 @Test
1070 public void testValidTree6() throws CorruptObjectException {
1071 final StringBuilder b = new StringBuilder();
1072 entry(b, "100644 .a");
1073 final byte[] data = Constants.encodeASCII(b.toString());
1074 checker.checkTree(data);
1075 }
1076
1077 @Test
1078 public void testValidPosixTree() throws CorruptObjectException {
1079 checkOneName("a<b>c:d|e");
1080 checkOneName("test ");
1081 checkOneName("test.");
1082 checkOneName("NUL");
1083 }
1084
1085 @Test
1086 public void testValidTreeSorting1() throws CorruptObjectException {
1087 final StringBuilder b = new StringBuilder();
1088 entry(b, "100644 fooaaa");
1089 entry(b, "100755 foobar");
1090 final byte[] data = Constants.encodeASCII(b.toString());
1091 checker.checkTree(data);
1092 }
1093
1094 @Test
1095 public void testValidTreeSorting2() throws CorruptObjectException {
1096 final StringBuilder b = new StringBuilder();
1097 entry(b, "100755 fooaaa");
1098 entry(b, "100644 foobar");
1099 final byte[] data = Constants.encodeASCII(b.toString());
1100 checker.checkTree(data);
1101 }
1102
1103 @Test
1104 public void testValidTreeSorting3() throws CorruptObjectException {
1105 final StringBuilder b = new StringBuilder();
1106 entry(b, "40000 a");
1107 entry(b, "100644 b");
1108 final byte[] data = Constants.encodeASCII(b.toString());
1109 checker.checkTree(data);
1110 }
1111
1112 @Test
1113 public void testValidTreeSorting4() throws CorruptObjectException {
1114 final StringBuilder b = new StringBuilder();
1115 entry(b, "100644 a");
1116 entry(b, "40000 b");
1117 final byte[] data = Constants.encodeASCII(b.toString());
1118 checker.checkTree(data);
1119 }
1120
1121 @Test
1122 public void testValidTreeSorting5() throws CorruptObjectException {
1123 final StringBuilder b = new StringBuilder();
1124 entry(b, "100644 a.c");
1125 entry(b, "40000 a");
1126 entry(b, "100644 a0c");
1127 final byte[] data = Constants.encodeASCII(b.toString());
1128 checker.checkTree(data);
1129 }
1130
1131 @Test
1132 public void testValidTreeSorting6() throws CorruptObjectException {
1133 final StringBuilder b = new StringBuilder();
1134 entry(b, "40000 a");
1135 entry(b, "100644 apple");
1136 final byte[] data = Constants.encodeASCII(b.toString());
1137 checker.checkTree(data);
1138 }
1139
1140 @Test
1141 public void testValidTreeSorting7() throws CorruptObjectException {
1142 final StringBuilder b = new StringBuilder();
1143 entry(b, "40000 an orang");
1144 entry(b, "40000 an orange");
1145 final byte[] data = Constants.encodeASCII(b.toString());
1146 checker.checkTree(data);
1147 }
1148
1149 @Test
1150 public void testValidTreeSorting8() throws CorruptObjectException {
1151 final StringBuilder b = new StringBuilder();
1152 entry(b, "100644 a");
1153 entry(b, "100644 a0c");
1154 entry(b, "100644 b");
1155 final byte[] data = Constants.encodeASCII(b.toString());
1156 checker.checkTree(data);
1157 }
1158
1159 @Test
1160 public void testAcceptTreeModeWithZero() throws CorruptObjectException {
1161 StringBuilder b = new StringBuilder();
1162 entry(b, "040000 a");
1163 checker.setAllowLeadingZeroFileMode(true);
1164 checker.checkTree(Constants.encodeASCII(b.toString()));
1165 }
1166
1167 @Test
1168 public void testInvalidTreeModeStartsWithZero1() {
1169 final StringBuilder b = new StringBuilder();
1170 entry(b, "0 a");
1171 final byte[] data = Constants.encodeASCII(b.toString());
1172 try {
1173 checker.checkTree(data);
1174 fail("incorrectly accepted an invalid tree");
1175 } catch (CorruptObjectException e) {
1176 assertEquals("mode starts with '0'", e.getMessage());
1177 }
1178 }
1179
1180 @Test
1181 public void testInvalidTreeModeStartsWithZero2() {
1182 final StringBuilder b = new StringBuilder();
1183 entry(b, "0100644 a");
1184 final byte[] data = Constants.encodeASCII(b.toString());
1185 try {
1186 checker.checkTree(data);
1187 fail("incorrectly accepted an invalid tree");
1188 } catch (CorruptObjectException e) {
1189 assertEquals("mode starts with '0'", e.getMessage());
1190 }
1191 }
1192
1193 @Test
1194 public void testInvalidTreeModeStartsWithZero3() {
1195 final StringBuilder b = new StringBuilder();
1196 entry(b, "040000 a");
1197 final byte[] data = Constants.encodeASCII(b.toString());
1198 try {
1199 checker.checkTree(data);
1200 fail("incorrectly accepted an invalid tree");
1201 } catch (CorruptObjectException e) {
1202 assertEquals("mode starts with '0'", e.getMessage());
1203 }
1204 }
1205
1206 @Test
1207 public void testInvalidTreeModeNotOctal1() {
1208 final StringBuilder b = new StringBuilder();
1209 entry(b, "8 a");
1210 final byte[] data = Constants.encodeASCII(b.toString());
1211 try {
1212 checker.checkTree(data);
1213 fail("incorrectly accepted an invalid tree");
1214 } catch (CorruptObjectException e) {
1215 assertEquals("invalid mode character", e.getMessage());
1216 }
1217 }
1218
1219 @Test
1220 public void testInvalidTreeModeNotOctal2() {
1221 final StringBuilder b = new StringBuilder();
1222 entry(b, "Z a");
1223 final byte[] data = Constants.encodeASCII(b.toString());
1224 try {
1225 checker.checkTree(data);
1226 fail("incorrectly accepted an invalid tree");
1227 } catch (CorruptObjectException e) {
1228 assertEquals("invalid mode character", e.getMessage());
1229 }
1230 }
1231
1232 @Test
1233 public void testInvalidTreeModeNotSupportedMode1() {
1234 final StringBuilder b = new StringBuilder();
1235 entry(b, "1 a");
1236 final byte[] data = Constants.encodeASCII(b.toString());
1237 try {
1238 checker.checkTree(data);
1239 fail("incorrectly accepted an invalid tree");
1240 } catch (CorruptObjectException e) {
1241 assertEquals("invalid mode 1", e.getMessage());
1242 }
1243 }
1244
1245 @Test
1246 public void testInvalidTreeModeNotSupportedMode2() {
1247 final StringBuilder b = new StringBuilder();
1248 entry(b, "170000 a");
1249 final byte[] data = Constants.encodeASCII(b.toString());
1250 try {
1251 checker.checkTree(data);
1252 fail("incorrectly accepted an invalid tree");
1253 } catch (CorruptObjectException e) {
1254 assertEquals("invalid mode " + 0170000, e.getMessage());
1255 }
1256 }
1257
1258 @Test
1259 public void testInvalidTreeModeMissingName() {
1260 final StringBuilder b = new StringBuilder();
1261 b.append("100644");
1262 final byte[] data = Constants.encodeASCII(b.toString());
1263 try {
1264 checker.checkTree(data);
1265 fail("incorrectly accepted an invalid tree");
1266 } catch (CorruptObjectException e) {
1267 assertEquals("truncated in mode", e.getMessage());
1268 }
1269 }
1270
1271 @Test
1272 public void testInvalidTreeNameContainsSlash() {
1273 final StringBuilder b = new StringBuilder();
1274 entry(b, "100644 a/b");
1275 final byte[] data = Constants.encodeASCII(b.toString());
1276 try {
1277 checker.checkTree(data);
1278 fail("incorrectly accepted an invalid tree");
1279 } catch (CorruptObjectException e) {
1280 assertEquals("name contains '/'", e.getMessage());
1281 }
1282 }
1283
1284 @Test
1285 public void testInvalidTreeNameIsEmpty() {
1286 final StringBuilder b = new StringBuilder();
1287 entry(b, "100644 ");
1288 final byte[] data = Constants.encodeASCII(b.toString());
1289 try {
1290 checker.checkTree(data);
1291 fail("incorrectly accepted an invalid tree");
1292 } catch (CorruptObjectException e) {
1293 assertEquals("zero length name", e.getMessage());
1294 }
1295 }
1296
1297 @Test
1298 public void testInvalidTreeNameIsDot() {
1299 final StringBuilder b = new StringBuilder();
1300 entry(b, "100644 .");
1301 final byte[] data = Constants.encodeASCII(b.toString());
1302 try {
1303 checker.checkTree(data);
1304 fail("incorrectly accepted an invalid tree");
1305 } catch (CorruptObjectException e) {
1306 assertEquals("invalid name '.'", e.getMessage());
1307 }
1308 }
1309
1310 @Test
1311 public void testInvalidTreeNameIsDotDot() {
1312 final StringBuilder b = new StringBuilder();
1313 entry(b, "100644 ..");
1314 final byte[] data = Constants.encodeASCII(b.toString());
1315 try {
1316 checker.checkTree(data);
1317 fail("incorrectly accepted an invalid tree");
1318 } catch (CorruptObjectException e) {
1319 assertEquals("invalid name '..'", e.getMessage());
1320 }
1321 }
1322
1323 @Test
1324 public void testInvalidTreeNameIsGit() {
1325 StringBuilder b = new StringBuilder();
1326 entry(b, "100644 .git");
1327 byte[] data = Constants.encodeASCII(b.toString());
1328 try {
1329 checker.checkTree(data);
1330 fail("incorrectly accepted an invalid tree");
1331 } catch (CorruptObjectException e) {
1332 assertEquals("invalid name '.git'", e.getMessage());
1333 }
1334 }
1335
1336 @Test
1337 public void testInvalidTreeNameIsMixedCaseGit() {
1338 StringBuilder b = new StringBuilder();
1339 entry(b, "100644 .GiT");
1340 byte[] data = Constants.encodeASCII(b.toString());
1341 try {
1342 checker.checkTree(data);
1343 fail("incorrectly accepted an invalid tree");
1344 } catch (CorruptObjectException e) {
1345 assertEquals("invalid name '.GiT'", e.getMessage());
1346 }
1347 }
1348
1349 @Test
1350 public void testInvalidTreeNameIsMacHFSGit() {
1351 StringBuilder b = new StringBuilder();
1352 entry(b, "100644 .gi\u200Ct");
1353 byte[] data = Constants.encode(b.toString());
1354 try {
1355 checker.setSafeForMacOS(true);
1356 checker.checkTree(data);
1357 fail("incorrectly accepted an invalid tree");
1358 } catch (CorruptObjectException e) {
1359 assertEquals(
1360 "invalid name '.gi\u200Ct' contains ignorable Unicode characters",
1361 e.getMessage());
1362 }
1363 }
1364
1365 @Test
1366 public void testInvalidTreeNameIsMacHFSGit2() {
1367 StringBuilder b = new StringBuilder();
1368 entry(b, "100644 \u206B.git");
1369 byte[] data = Constants.encode(b.toString());
1370 try {
1371 checker.setSafeForMacOS(true);
1372 checker.checkTree(data);
1373 fail("incorrectly accepted an invalid tree");
1374 } catch (CorruptObjectException e) {
1375 assertEquals(
1376 "invalid name '\u206B.git' contains ignorable Unicode characters",
1377 e.getMessage());
1378 }
1379 }
1380
1381 @Test
1382 public void testInvalidTreeNameIsMacHFSGit3() {
1383 StringBuilder b = new StringBuilder();
1384 entry(b, "100644 .git\uFEFF");
1385 byte[] data = Constants.encode(b.toString());
1386 try {
1387 checker.setSafeForMacOS(true);
1388 checker.checkTree(data);
1389 fail("incorrectly accepted an invalid tree");
1390 } catch (CorruptObjectException e) {
1391 assertEquals(
1392 "invalid name '.git\uFEFF' contains ignorable Unicode characters",
1393 e.getMessage());
1394 }
1395 }
1396
1397 private static byte[] concat(byte[] b1, byte[] b2) {
1398 byte[] data = new byte[b1.length + b2.length];
1399 System.arraycopy(b1, 0, data, 0, b1.length);
1400 System.arraycopy(b2, 0, data, b1.length, b2.length);
1401 return data;
1402 }
1403
1404 @Test
1405 public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd() {
1406 byte[] data = concat(Constants.encode("100644 .git"),
1407 new byte[] { (byte) 0xef });
1408 StringBuilder b = new StringBuilder();
1409 entry(b, "");
1410 data = concat(data, Constants.encode(b.toString()));
1411 try {
1412 checker.setSafeForMacOS(true);
1413 checker.checkTree(data);
1414 fail("incorrectly accepted an invalid tree");
1415 } catch (CorruptObjectException e) {
1416 assertEquals(
1417 "invalid name contains byte sequence '0xef' which is not a valid UTF-8 character",
1418 e.getMessage());
1419 }
1420 }
1421
1422 @Test
1423 public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd2() {
1424 byte[] data = concat(Constants.encode("100644 .git"), new byte[] {
1425 (byte) 0xe2, (byte) 0xab });
1426 StringBuilder b = new StringBuilder();
1427 entry(b, "");
1428 data = concat(data, Constants.encode(b.toString()));
1429 try {
1430 checker.setSafeForMacOS(true);
1431 checker.checkTree(data);
1432 fail("incorrectly accepted an invalid tree");
1433 } catch (CorruptObjectException e) {
1434 assertEquals(
1435 "invalid name contains byte sequence '0xe2ab' which is not a valid UTF-8 character",
1436 e.getMessage());
1437 }
1438 }
1439
1440 @Test
1441 public void testInvalidTreeNameIsNotMacHFSGit()
1442 throws CorruptObjectException {
1443 StringBuilder b = new StringBuilder();
1444 entry(b, "100644 .git\u200Cx");
1445 byte[] data = Constants.encode(b.toString());
1446 checker.setSafeForMacOS(true);
1447 checker.checkTree(data);
1448 }
1449
1450 @Test
1451 public void testInvalidTreeNameIsNotMacHFSGit2()
1452 throws CorruptObjectException {
1453 StringBuilder b = new StringBuilder();
1454 entry(b, "100644 .kit\u200C");
1455 byte[] data = Constants.encode(b.toString());
1456 checker.setSafeForMacOS(true);
1457 checker.checkTree(data);
1458 }
1459
1460 @Test
1461 public void testInvalidTreeNameIsNotMacHFSGitOtherPlatform()
1462 throws CorruptObjectException {
1463 StringBuilder b = new StringBuilder();
1464 entry(b, "100644 .git\u200C");
1465 byte[] data = Constants.encode(b.toString());
1466 checker.checkTree(data);
1467 }
1468
1469 @Test
1470 public void testInvalidTreeNameIsDotGitDot() {
1471 StringBuilder b = new StringBuilder();
1472 entry(b, "100644 .git.");
1473 byte[] data = Constants.encodeASCII(b.toString());
1474 try {
1475 checker.checkTree(data);
1476 fail("incorrectly accepted an invalid tree");
1477 } catch (CorruptObjectException e) {
1478 assertEquals("invalid name '.git.'", e.getMessage());
1479 }
1480 }
1481
1482 @Test
1483 public void testValidTreeNameIsDotGitDotDot()
1484 throws CorruptObjectException {
1485 StringBuilder b = new StringBuilder();
1486 entry(b, "100644 .git..");
1487 checker.checkTree(Constants.encodeASCII(b.toString()));
1488 }
1489
1490 @Test
1491 public void testInvalidTreeNameIsDotGitSpace() {
1492 StringBuilder b = new StringBuilder();
1493 entry(b, "100644 .git ");
1494 byte[] data = Constants.encodeASCII(b.toString());
1495 try {
1496 checker.checkTree(data);
1497 fail("incorrectly accepted an invalid tree");
1498 } catch (CorruptObjectException e) {
1499 assertEquals("invalid name '.git '", e.getMessage());
1500 }
1501 }
1502
1503 @Test
1504 public void testInvalidTreeNameIsDotGitSomething()
1505 throws CorruptObjectException {
1506 StringBuilder b = new StringBuilder();
1507 entry(b, "100644 .gitfoobar");
1508 byte[] data = Constants.encodeASCII(b.toString());
1509 checker.checkTree(data);
1510 }
1511
1512 @Test
1513 public void testInvalidTreeNameIsDotGitSomethingSpaceSomething()
1514 throws CorruptObjectException {
1515 StringBuilder b = new StringBuilder();
1516 entry(b, "100644 .gitfoo bar");
1517 byte[] data = Constants.encodeASCII(b.toString());
1518 checker.checkTree(data);
1519 }
1520
1521 @Test
1522 public void testInvalidTreeNameIsDotGitSomethingDot()
1523 throws CorruptObjectException {
1524 StringBuilder b = new StringBuilder();
1525 entry(b, "100644 .gitfoobar.");
1526 byte[] data = Constants.encodeASCII(b.toString());
1527 checker.checkTree(data);
1528 }
1529
1530 @Test
1531 public void testInvalidTreeNameIsDotGitSomethingDotDot()
1532 throws CorruptObjectException {
1533 StringBuilder b = new StringBuilder();
1534 entry(b, "100644 .gitfoobar..");
1535 byte[] data = Constants.encodeASCII(b.toString());
1536 checker.checkTree(data);
1537 }
1538
1539 @Test
1540 public void testInvalidTreeNameIsDotGitDotSpace() {
1541 StringBuilder b = new StringBuilder();
1542 entry(b, "100644 .git. ");
1543 byte[] data = Constants.encodeASCII(b.toString());
1544 try {
1545 checker.checkTree(data);
1546 fail("incorrectly accepted an invalid tree");
1547 } catch (CorruptObjectException e) {
1548 assertEquals("invalid name '.git. '", e.getMessage());
1549 }
1550 }
1551
1552 @Test
1553 public void testInvalidTreeNameIsDotGitSpaceDot() {
1554 StringBuilder b = new StringBuilder();
1555 entry(b, "100644 .git . ");
1556 byte[] data = Constants.encodeASCII(b.toString());
1557 try {
1558 checker.checkTree(data);
1559 fail("incorrectly accepted an invalid tree");
1560 } catch (CorruptObjectException e) {
1561 assertEquals("invalid name '.git . '", e.getMessage());
1562 }
1563 }
1564
1565 @Test
1566 public void testInvalidTreeNameIsGITTilde1() {
1567 StringBuilder b = new StringBuilder();
1568 entry(b, "100644 GIT~1");
1569 byte[] data = Constants.encodeASCII(b.toString());
1570 try {
1571 checker.checkTree(data);
1572 fail("incorrectly accepted an invalid tree");
1573 } catch (CorruptObjectException e) {
1574 assertEquals("invalid name 'GIT~1'", e.getMessage());
1575 }
1576 }
1577
1578 @Test
1579 public void testInvalidTreeNameIsGiTTilde1() {
1580 StringBuilder b = new StringBuilder();
1581 entry(b, "100644 GiT~1");
1582 byte[] data = Constants.encodeASCII(b.toString());
1583 try {
1584 checker.checkTree(data);
1585 fail("incorrectly accepted an invalid tree");
1586 } catch (CorruptObjectException e) {
1587 assertEquals("invalid name 'GiT~1'", e.getMessage());
1588 }
1589 }
1590
1591 @Test
1592 public void testValidTreeNameIsGitTilde11() throws CorruptObjectException {
1593 StringBuilder b = new StringBuilder();
1594 entry(b, "100644 GIT~11");
1595 byte[] data = Constants.encodeASCII(b.toString());
1596 checker.checkTree(data);
1597 }
1598
1599 @Test
1600 public void testInvalidTreeTruncatedInName() {
1601 final StringBuilder b = new StringBuilder();
1602 b.append("100644 b");
1603 final byte[] data = Constants.encodeASCII(b.toString());
1604 try {
1605 checker.checkTree(data);
1606 fail("incorrectly accepted an invalid tree");
1607 } catch (CorruptObjectException e) {
1608 assertEquals("truncated in name", e.getMessage());
1609 }
1610 }
1611
1612 @Test
1613 public void testInvalidTreeTruncatedInObjectId() {
1614 final StringBuilder b = new StringBuilder();
1615 b.append("100644 b\0\1\2");
1616 final byte[] data = Constants.encodeASCII(b.toString());
1617 try {
1618 checker.checkTree(data);
1619 fail("incorrectly accepted an invalid tree");
1620 } catch (CorruptObjectException e) {
1621 assertEquals("truncated in object id", e.getMessage());
1622 }
1623 }
1624
1625 @Test
1626 public void testInvalidTreeBadSorting1() {
1627 final StringBuilder b = new StringBuilder();
1628 entry(b, "100644 foobar");
1629 entry(b, "100644 fooaaa");
1630 final byte[] data = Constants.encodeASCII(b.toString());
1631 try {
1632 checker.checkTree(data);
1633 fail("incorrectly accepted an invalid tree");
1634 } catch (CorruptObjectException e) {
1635 assertEquals("incorrectly sorted", e.getMessage());
1636 }
1637 }
1638
1639 @Test
1640 public void testInvalidTreeBadSorting2() {
1641 final StringBuilder b = new StringBuilder();
1642 entry(b, "40000 a");
1643 entry(b, "100644 a.c");
1644 final byte[] data = Constants.encodeASCII(b.toString());
1645 try {
1646 checker.checkTree(data);
1647 fail("incorrectly accepted an invalid tree");
1648 } catch (CorruptObjectException e) {
1649 assertEquals("incorrectly sorted", e.getMessage());
1650 }
1651 }
1652
1653 @Test
1654 public void testInvalidTreeBadSorting3() {
1655 final StringBuilder b = new StringBuilder();
1656 entry(b, "100644 a0c");
1657 entry(b, "40000 a");
1658 final byte[] data = Constants.encodeASCII(b.toString());
1659 try {
1660 checker.checkTree(data);
1661 fail("incorrectly accepted an invalid tree");
1662 } catch (CorruptObjectException e) {
1663 assertEquals("incorrectly sorted", e.getMessage());
1664 }
1665 }
1666
1667 @Test
1668 public void testInvalidTreeDuplicateNames1() {
1669 final StringBuilder b = new StringBuilder();
1670 entry(b, "100644 a");
1671 entry(b, "100644 a");
1672 final byte[] data = Constants.encodeASCII(b.toString());
1673 try {
1674 checker.checkTree(data);
1675 fail("incorrectly accepted an invalid tree");
1676 } catch (CorruptObjectException e) {
1677 assertEquals("duplicate entry names", e.getMessage());
1678 }
1679 }
1680
1681 @Test
1682 public void testInvalidTreeDuplicateNames2() {
1683 final StringBuilder b = new StringBuilder();
1684 entry(b, "100644 a");
1685 entry(b, "100755 a");
1686 final byte[] data = Constants.encodeASCII(b.toString());
1687 try {
1688 checker.checkTree(data);
1689 fail("incorrectly accepted an invalid tree");
1690 } catch (CorruptObjectException e) {
1691 assertEquals("duplicate entry names", e.getMessage());
1692 }
1693 }
1694
1695 @Test
1696 public void testInvalidTreeDuplicateNames3() {
1697 final StringBuilder b = new StringBuilder();
1698 entry(b, "100644 a");
1699 entry(b, "40000 a");
1700 final byte[] data = Constants.encodeASCII(b.toString());
1701 try {
1702 checker.checkTree(data);
1703 fail("incorrectly accepted an invalid tree");
1704 } catch (CorruptObjectException e) {
1705 assertEquals("duplicate entry names", e.getMessage());
1706 }
1707 }
1708
1709 @Test
1710 public void testInvalidTreeDuplicateNames4() {
1711 final StringBuilder b = new StringBuilder();
1712 entry(b, "100644 a");
1713 entry(b, "100644 a.c");
1714 entry(b, "100644 a.d");
1715 entry(b, "100644 a.e");
1716 entry(b, "40000 a");
1717 entry(b, "100644 zoo");
1718 final byte[] data = Constants.encodeASCII(b.toString());
1719 try {
1720 checker.checkTree(data);
1721 fail("incorrectly accepted an invalid tree");
1722 } catch (CorruptObjectException e) {
1723 assertEquals("duplicate entry names", e.getMessage());
1724 }
1725 }
1726
1727 @Test
1728 public void testInvalidTreeDuplicateNames5()
1729 throws UnsupportedEncodingException {
1730 StringBuilder b = new StringBuilder();
1731 entry(b, "100644 a");
1732 entry(b, "100644 A");
1733 byte[] data = b.toString().getBytes("UTF-8");
1734 try {
1735 checker.setSafeForWindows(true);
1736 checker.checkTree(data);
1737 fail("incorrectly accepted an invalid tree");
1738 } catch (CorruptObjectException e) {
1739 assertEquals("duplicate entry names", e.getMessage());
1740 }
1741 }
1742
1743 @Test
1744 public void testInvalidTreeDuplicateNames6()
1745 throws UnsupportedEncodingException {
1746 StringBuilder b = new StringBuilder();
1747 entry(b, "100644 a");
1748 entry(b, "100644 A");
1749 byte[] data = b.toString().getBytes("UTF-8");
1750 try {
1751 checker.setSafeForMacOS(true);
1752 checker.checkTree(data);
1753 fail("incorrectly accepted an invalid tree");
1754 } catch (CorruptObjectException e) {
1755 assertEquals("duplicate entry names", e.getMessage());
1756 }
1757 }
1758
1759 @Test
1760 public void testInvalidTreeDuplicateNames7()
1761 throws UnsupportedEncodingException {
1762 try {
1763 Class.forName("java.text.Normalizer");
1764 } catch (ClassNotFoundException e) {
1765
1766 return;
1767 }
1768
1769 StringBuilder b = new StringBuilder();
1770 entry(b, "100644 \u0065\u0301");
1771 entry(b, "100644 \u00e9");
1772 byte[] data = b.toString().getBytes("UTF-8");
1773 try {
1774 checker.setSafeForMacOS(true);
1775 checker.checkTree(data);
1776 fail("incorrectly accepted an invalid tree");
1777 } catch (CorruptObjectException e) {
1778 assertEquals("duplicate entry names", e.getMessage());
1779 }
1780 }
1781
1782 @Test
1783 public void testInvalidTreeDuplicateNames8()
1784 throws UnsupportedEncodingException, CorruptObjectException {
1785 StringBuilder b = new StringBuilder();
1786 entry(b, "100644 A");
1787 checker.setSafeForMacOS(true);
1788 checker.checkTree(b.toString().getBytes("UTF-8"));
1789 }
1790
1791 @Test
1792 public void testRejectNulInPathSegment() {
1793 try {
1794 checker.checkPathSegment(Constants.encodeASCII("a\u0000b"), 0, 3);
1795 fail("incorrectly accepted NUL in middle of name");
1796 } catch (CorruptObjectException e) {
1797 assertEquals("name contains byte 0x00", e.getMessage());
1798 }
1799 }
1800
1801 @Test
1802 public void testRejectSpaceAtEndOnWindows() {
1803 checker.setSafeForWindows(true);
1804 try {
1805 checkOneName("test ");
1806 fail("incorrectly accepted space at end");
1807 } catch (CorruptObjectException e) {
1808 assertEquals("invalid name ends with ' '", e.getMessage());
1809 }
1810 }
1811
1812 @Test
1813 public void testRejectDotAtEndOnWindows() {
1814 checker.setSafeForWindows(true);
1815 try {
1816 checkOneName("test.");
1817 fail("incorrectly accepted dot at end");
1818 } catch (CorruptObjectException e) {
1819 assertEquals("invalid name ends with '.'", e.getMessage());
1820 }
1821 }
1822
1823 @Test
1824 public void testRejectDevicesOnWindows() {
1825 checker.setSafeForWindows(true);
1826
1827 String[] bad = { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3",
1828 "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2",
1829 "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" };
1830 for (String b : bad) {
1831 try {
1832 checkOneName(b);
1833 fail("incorrectly accepted " + b);
1834 } catch (CorruptObjectException e) {
1835 assertEquals("invalid name '" + b + "'", e.getMessage());
1836 }
1837 try {
1838 checkOneName(b + ".txt");
1839 fail("incorrectly accepted " + b + ".txt");
1840 } catch (CorruptObjectException e) {
1841 assertEquals("invalid name '" + b + "'", e.getMessage());
1842 }
1843 }
1844 }
1845
1846 @Test
1847 public void testRejectInvalidWindowsCharacters() {
1848 checker.setSafeForWindows(true);
1849 rejectName('<');
1850 rejectName('>');
1851 rejectName(':');
1852 rejectName('"');
1853 rejectName('/');
1854 rejectName('\\');
1855 rejectName('|');
1856 rejectName('?');
1857 rejectName('*');
1858
1859 for (int i = 1; i <= 31; i++)
1860 rejectName((byte) i);
1861 }
1862
1863 private void rejectName(char c) {
1864 try {
1865 checkOneName("te" + c + "st");
1866 fail("incorrectly accepted with " + c);
1867 } catch (CorruptObjectException e) {
1868 assertEquals("name contains '" + c + "'", e.getMessage());
1869 }
1870 }
1871
1872 private void rejectName(byte c) {
1873 String h = Integer.toHexString(c);
1874 try {
1875 checkOneName("te" + ((char) c) + "st");
1876 fail("incorrectly accepted with 0x" + h);
1877 } catch (CorruptObjectException e) {
1878 assertEquals("name contains byte 0x" + h, e.getMessage());
1879 }
1880 }
1881
1882 private void checkOneName(String name) throws CorruptObjectException {
1883 StringBuilder b = new StringBuilder();
1884 entry(b, "100644 " + name);
1885 checker.checkTree(Constants.encodeASCII(b.toString()));
1886 }
1887
1888 private static void entry(final StringBuilder b, final String modeName) {
1889 b.append(modeName);
1890 b.append('\0');
1891 for (int i = 0; i < Constants.OBJECT_ID_LENGTH; i++)
1892 b.append((char) i);
1893 }
1894 }