You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ObjectCheckerTest.java 51KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783
  1. /*
  2. * Copyright (C) 2008-2010, Google Inc.
  3. * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
  4. * and other copyright owners as documented in the project's IP log.
  5. *
  6. * This program and the accompanying materials are made available
  7. * under the terms of the Eclipse Distribution License v1.0 which
  8. * accompanies this distribution, is reproduced below, and is
  9. * available at http://www.eclipse.org/org/documents/edl-v10.php
  10. *
  11. * All rights reserved.
  12. *
  13. * Redistribution and use in source and binary forms, with or
  14. * without modification, are permitted provided that the following
  15. * conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. *
  20. * - Redistributions in binary form must reproduce the above
  21. * copyright notice, this list of conditions and the following
  22. * disclaimer in the documentation and/or other materials provided
  23. * with the distribution.
  24. *
  25. * - Neither the name of the Eclipse Foundation, Inc. nor the
  26. * names of its contributors may be used to endorse or promote
  27. * products derived from this software without specific prior
  28. * written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  31. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  32. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  33. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  34. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  35. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  39. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  42. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43. */
  44. package org.eclipse.jgit.lib;
  45. import static java.lang.Integer.valueOf;
  46. import static org.eclipse.jgit.lib.Constants.CHARSET;
  47. import static org.eclipse.jgit.junit.JGitTestUtil.concat;
  48. import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
  49. import static org.eclipse.jgit.lib.Constants.OBJ_BAD;
  50. import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
  51. import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
  52. import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
  53. import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
  54. import static org.eclipse.jgit.lib.Constants.encode;
  55. import static org.eclipse.jgit.lib.Constants.encodeASCII;
  56. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.DUPLICATE_ENTRIES;
  57. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.EMPTY_NAME;
  58. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.FULL_PATHNAME;
  59. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.HAS_DOT;
  60. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.HAS_DOTDOT;
  61. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.HAS_DOTGIT;
  62. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.NULL_SHA1;
  63. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.TREE_NOT_SORTED;
  64. import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.ZERO_PADDED_FILEMODE;
  65. import static org.eclipse.jgit.util.RawParseUtils.decode;
  66. import static org.junit.Assert.assertEquals;
  67. import static org.junit.Assert.assertSame;
  68. import static org.junit.Assert.fail;
  69. import java.text.MessageFormat;
  70. import org.eclipse.jgit.errors.CorruptObjectException;
  71. import org.eclipse.jgit.internal.JGitText;
  72. import org.junit.Before;
  73. import org.junit.Rule;
  74. import org.junit.Test;
  75. import org.junit.rules.ExpectedException;
  76. public class ObjectCheckerTest {
  77. private static final ObjectChecker SECRET_KEY_CHECKER = new ObjectChecker() {
  78. @Override
  79. public void checkBlob(byte[] raw) throws CorruptObjectException {
  80. String in = decode(raw);
  81. if (in.contains("secret_key")) {
  82. throw new CorruptObjectException("don't add a secret key");
  83. }
  84. }
  85. };
  86. private static final ObjectChecker SECRET_KEY_BLOB_CHECKER = new ObjectChecker() {
  87. @Override
  88. public BlobObjectChecker newBlobObjectChecker() {
  89. return new BlobObjectChecker() {
  90. private boolean containSecretKey;
  91. @Override
  92. public void update(byte[] in, int offset, int len) {
  93. String str = decode(in, offset, offset + len);
  94. if (str.contains("secret_key")) {
  95. containSecretKey = true;
  96. }
  97. }
  98. @Override
  99. public void endBlob(AnyObjectId id)
  100. throws CorruptObjectException {
  101. if (containSecretKey) {
  102. throw new CorruptObjectException(
  103. "don't add a secret key");
  104. }
  105. }
  106. };
  107. }
  108. };
  109. private ObjectChecker checker;
  110. @Rule
  111. public final ExpectedException thrown = ExpectedException.none();
  112. @Before
  113. public void setUp() throws Exception {
  114. checker = new ObjectChecker();
  115. }
  116. @Test
  117. public void testInvalidType() {
  118. String msg = MessageFormat.format(
  119. JGitText.get().corruptObjectInvalidType2,
  120. valueOf(OBJ_BAD));
  121. assertCorrupt(msg, OBJ_BAD, new byte[0]);
  122. }
  123. @Test
  124. public void testCheckBlob() throws CorruptObjectException {
  125. // Any blob should pass...
  126. checker.checkBlob(new byte[0]);
  127. checker.checkBlob(new byte[1]);
  128. checker.check(OBJ_BLOB, new byte[0]);
  129. checker.check(OBJ_BLOB, new byte[1]);
  130. }
  131. @Test
  132. public void testCheckBlobNotCorrupt() throws CorruptObjectException {
  133. SECRET_KEY_CHECKER.check(OBJ_BLOB, encodeASCII("key = \"public_key\""));
  134. }
  135. @Test
  136. public void testCheckBlobCorrupt() throws CorruptObjectException {
  137. thrown.expect(CorruptObjectException.class);
  138. SECRET_KEY_CHECKER.check(OBJ_BLOB, encodeASCII("key = \"secret_key\""));
  139. }
  140. @Test
  141. public void testCheckBlobWithBlobObjectCheckerNotCorrupt()
  142. throws CorruptObjectException {
  143. SECRET_KEY_BLOB_CHECKER.check(OBJ_BLOB,
  144. encodeASCII("key = \"public_key\""));
  145. }
  146. @Test
  147. public void testCheckBlobWithBlobObjectCheckerCorrupt()
  148. throws CorruptObjectException {
  149. thrown.expect(CorruptObjectException.class);
  150. SECRET_KEY_BLOB_CHECKER.check(OBJ_BLOB,
  151. encodeASCII("key = \"secret_key\""));
  152. }
  153. @Test
  154. public void testValidCommitNoParent() throws CorruptObjectException {
  155. StringBuilder b = new StringBuilder();
  156. b.append("tree ");
  157. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  158. b.append('\n');
  159. b.append("author A. U. Thor <author@localhost> 1 +0000\n");
  160. b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
  161. byte[] data = encodeASCII(b.toString());
  162. checker.checkCommit(data);
  163. checker.check(OBJ_COMMIT, data);
  164. }
  165. @Test
  166. public void testValidCommitBlankAuthor() throws CorruptObjectException {
  167. StringBuilder b = new StringBuilder();
  168. b.append("tree ");
  169. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  170. b.append('\n');
  171. b.append("author <> 0 +0000\n");
  172. b.append("committer <> 0 +0000\n");
  173. byte[] data = encodeASCII(b.toString());
  174. checker.checkCommit(data);
  175. checker.check(OBJ_COMMIT, data);
  176. }
  177. @Test
  178. public void testCommitCorruptAuthor() throws CorruptObjectException {
  179. StringBuilder b = new StringBuilder();
  180. b.append("tree be9bfa841874ccc9f2ef7c48d0c76226f89b7189\n");
  181. b.append("author b <b@c> <b@c> 0 +0000\n");
  182. b.append("committer <> 0 +0000\n");
  183. byte[] data = encodeASCII(b.toString());
  184. assertCorrupt("bad date", OBJ_COMMIT, data);
  185. checker.setAllowInvalidPersonIdent(true);
  186. checker.checkCommit(data);
  187. checker.setAllowInvalidPersonIdent(false);
  188. assertSkipListAccepts(OBJ_COMMIT, data);
  189. }
  190. @Test
  191. public void testCommitCorruptCommitter() throws CorruptObjectException {
  192. StringBuilder b = new StringBuilder();
  193. b.append("tree be9bfa841874ccc9f2ef7c48d0c76226f89b7189\n");
  194. b.append("author <> 0 +0000\n");
  195. b.append("committer b <b@c> <b@c> 0 +0000\n");
  196. byte[] data = encodeASCII(b.toString());
  197. assertCorrupt("bad date", OBJ_COMMIT, data);
  198. checker.setAllowInvalidPersonIdent(true);
  199. checker.checkCommit(data);
  200. checker.setAllowInvalidPersonIdent(false);
  201. assertSkipListAccepts(OBJ_COMMIT, data);
  202. }
  203. @Test
  204. public void testValidCommit1Parent() throws CorruptObjectException {
  205. StringBuilder b = new StringBuilder();
  206. b.append("tree ");
  207. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  208. b.append('\n');
  209. b.append("parent ");
  210. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  211. b.append('\n');
  212. b.append("author A. U. Thor <author@localhost> 1 +0000\n");
  213. b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
  214. byte[] data = encodeASCII(b.toString());
  215. checker.checkCommit(data);
  216. checker.check(OBJ_COMMIT, data);
  217. }
  218. @Test
  219. public void testValidCommit2Parent() throws CorruptObjectException {
  220. StringBuilder b = new StringBuilder();
  221. b.append("tree ");
  222. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  223. b.append('\n');
  224. b.append("parent ");
  225. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  226. b.append('\n');
  227. b.append("parent ");
  228. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  229. b.append('\n');
  230. b.append("author A. U. Thor <author@localhost> 1 +0000\n");
  231. b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
  232. byte[] data = encodeASCII(b.toString());
  233. checker.checkCommit(data);
  234. checker.check(OBJ_COMMIT, data);
  235. }
  236. @Test
  237. public void testValidCommit128Parent() throws CorruptObjectException {
  238. StringBuilder b = new StringBuilder();
  239. b.append("tree ");
  240. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  241. b.append('\n');
  242. for (int i = 0; i < 128; i++) {
  243. b.append("parent ");
  244. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  245. b.append('\n');
  246. }
  247. b.append("author A. U. Thor <author@localhost> 1 +0000\n");
  248. b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
  249. byte[] data = encodeASCII(b.toString());
  250. checker.checkCommit(data);
  251. checker.check(OBJ_COMMIT, data);
  252. }
  253. @Test
  254. public void testValidCommitNormalTime() throws CorruptObjectException {
  255. StringBuilder b = new StringBuilder();
  256. String when = "1222757360 -0730";
  257. b.append("tree ");
  258. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  259. b.append('\n');
  260. b.append("author A. U. Thor <author@localhost> " + when + "\n");
  261. b.append("committer A. U. Thor <author@localhost> " + when + "\n");
  262. byte[] data = encodeASCII(b.toString());
  263. checker.checkCommit(data);
  264. checker.check(OBJ_COMMIT, data);
  265. }
  266. @Test
  267. public void testInvalidCommitNoTree1() {
  268. StringBuilder b = new StringBuilder();
  269. b.append("parent ");
  270. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  271. b.append('\n');
  272. assertCorrupt("no tree header", OBJ_COMMIT, b);
  273. }
  274. @Test
  275. public void testInvalidCommitNoTree2() {
  276. StringBuilder b = new StringBuilder();
  277. b.append("trie ");
  278. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  279. b.append('\n');
  280. assertCorrupt("no tree header", OBJ_COMMIT, b);
  281. }
  282. @Test
  283. public void testInvalidCommitNoTree3() {
  284. StringBuilder b = new StringBuilder();
  285. b.append("tree");
  286. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  287. b.append('\n');
  288. assertCorrupt("no tree header", OBJ_COMMIT, b);
  289. }
  290. @Test
  291. public void testInvalidCommitNoTree4() {
  292. StringBuilder b = new StringBuilder();
  293. b.append("tree\t");
  294. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  295. b.append('\n');
  296. assertCorrupt("no tree header", OBJ_COMMIT, b);
  297. }
  298. @Test
  299. public void testInvalidCommitInvalidTree1() {
  300. StringBuilder b = new StringBuilder();
  301. b.append("tree ");
  302. b.append("zzzzfa841874ccc9f2ef7c48d0c76226f89b7189");
  303. b.append('\n');
  304. assertCorrupt("invalid tree", OBJ_COMMIT, b);
  305. }
  306. @Test
  307. public void testInvalidCommitInvalidTree2() {
  308. StringBuilder b = new StringBuilder();
  309. b.append("tree ");
  310. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  311. b.append("z\n");
  312. assertCorrupt("invalid tree", OBJ_COMMIT, b);
  313. }
  314. @Test
  315. public void testInvalidCommitInvalidTree3() {
  316. StringBuilder b = new StringBuilder();
  317. b.append("tree ");
  318. b.append("be9b");
  319. b.append("\n");
  320. byte[] data = encodeASCII(b.toString());
  321. assertCorrupt("invalid tree", OBJ_COMMIT, data);
  322. }
  323. @Test
  324. public void testInvalidCommitInvalidTree4() {
  325. StringBuilder b = new StringBuilder();
  326. b.append("tree ");
  327. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  328. b.append('\n');
  329. assertCorrupt("invalid tree", OBJ_COMMIT, b);
  330. }
  331. @Test
  332. public void testInvalidCommitInvalidParent1() {
  333. StringBuilder b = new StringBuilder();
  334. b.append("tree ");
  335. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  336. b.append('\n');
  337. b.append("parent ");
  338. b.append("\n");
  339. assertCorrupt("invalid parent", OBJ_COMMIT, b);
  340. }
  341. @Test
  342. public void testInvalidCommitInvalidParent2() {
  343. StringBuilder b = new StringBuilder();
  344. b.append("tree ");
  345. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  346. b.append('\n');
  347. b.append("parent ");
  348. b.append("zzzzfa841874ccc9f2ef7c48d0c76226f89b7189");
  349. b.append("\n");
  350. assertCorrupt("invalid parent", OBJ_COMMIT, b);
  351. }
  352. @Test
  353. public void testInvalidCommitInvalidParent3() {
  354. StringBuilder b = new StringBuilder();
  355. b.append("tree ");
  356. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  357. b.append('\n');
  358. b.append("parent ");
  359. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  360. b.append("\n");
  361. assertCorrupt("invalid parent", OBJ_COMMIT, b);
  362. }
  363. @Test
  364. public void testInvalidCommitInvalidParent4() {
  365. StringBuilder b = new StringBuilder();
  366. b.append("tree ");
  367. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  368. b.append('\n');
  369. b.append("parent ");
  370. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  371. b.append("z\n");
  372. assertCorrupt("invalid parent", OBJ_COMMIT, b);
  373. }
  374. @Test
  375. public void testInvalidCommitInvalidParent5() {
  376. StringBuilder b = new StringBuilder();
  377. b.append("tree ");
  378. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  379. b.append('\n');
  380. b.append("parent\t");
  381. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  382. b.append("\n");
  383. byte[] data = encodeASCII(b.toString());
  384. // Yes, really, we complain about author not being
  385. // found as the invalid parent line wasn't consumed.
  386. assertCorrupt("no author", OBJ_COMMIT, data);
  387. }
  388. @Test
  389. public void testInvalidCommitNoAuthor() throws CorruptObjectException {
  390. StringBuilder b = new StringBuilder();
  391. b.append("tree ");
  392. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  393. b.append('\n');
  394. b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
  395. byte[] data = encodeASCII(b.toString());
  396. assertCorrupt("no author", OBJ_COMMIT, data);
  397. assertSkipListAccepts(OBJ_COMMIT, data);
  398. }
  399. @Test
  400. public void testInvalidCommitNoCommitter1() throws CorruptObjectException {
  401. StringBuilder b = new StringBuilder();
  402. b.append("tree ");
  403. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  404. b.append('\n');
  405. b.append("author A. U. Thor <author@localhost> 1 +0000\n");
  406. byte[] data = encodeASCII(b.toString());
  407. assertCorrupt("no committer", OBJ_COMMIT, data);
  408. assertSkipListAccepts(OBJ_COMMIT, data);
  409. }
  410. @Test
  411. public void testInvalidCommitNoCommitter2() throws CorruptObjectException {
  412. StringBuilder b = new StringBuilder();
  413. b.append("tree ");
  414. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  415. b.append('\n');
  416. b.append("author A. U. Thor <author@localhost> 1 +0000\n");
  417. b.append("\n");
  418. byte[] data = encodeASCII(b.toString());
  419. assertCorrupt("no committer", OBJ_COMMIT, data);
  420. assertSkipListAccepts(OBJ_COMMIT, data);
  421. }
  422. @Test
  423. public void testInvalidCommitInvalidAuthor1()
  424. throws CorruptObjectException {
  425. StringBuilder b = new StringBuilder();
  426. b.append("tree ");
  427. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  428. b.append('\n');
  429. b.append("author A. U. Thor <foo 1 +0000\n");
  430. byte[] data = encodeASCII(b.toString());
  431. assertCorrupt("bad email", OBJ_COMMIT, data);
  432. assertSkipListAccepts(OBJ_COMMIT, data);
  433. }
  434. @Test
  435. public void testInvalidCommitInvalidAuthor2()
  436. throws CorruptObjectException {
  437. StringBuilder b = new StringBuilder();
  438. b.append("tree ");
  439. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  440. b.append('\n');
  441. b.append("author A. U. Thor foo> 1 +0000\n");
  442. byte[] data = encodeASCII(b.toString());
  443. assertCorrupt("missing email", OBJ_COMMIT, data);
  444. assertSkipListAccepts(OBJ_COMMIT, data);
  445. }
  446. @Test
  447. public void testInvalidCommitInvalidAuthor3()
  448. throws CorruptObjectException {
  449. StringBuilder b = new StringBuilder();
  450. b.append("tree ");
  451. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  452. b.append('\n');
  453. b.append("author 1 +0000\n");
  454. byte[] data = encodeASCII(b.toString());
  455. assertCorrupt("missing email", OBJ_COMMIT, data);
  456. assertSkipListAccepts(OBJ_COMMIT, data);
  457. }
  458. @Test
  459. public void testInvalidCommitInvalidAuthor4()
  460. throws CorruptObjectException {
  461. StringBuilder b = new StringBuilder();
  462. b.append("tree ");
  463. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  464. b.append('\n');
  465. b.append("author a <b> +0000\n");
  466. byte[] data = encodeASCII(b.toString());
  467. assertCorrupt("bad date", OBJ_COMMIT, data);
  468. assertSkipListAccepts(OBJ_COMMIT, data);
  469. }
  470. @Test
  471. public void testInvalidCommitInvalidAuthor5()
  472. throws CorruptObjectException {
  473. StringBuilder b = new StringBuilder();
  474. b.append("tree ");
  475. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  476. b.append('\n');
  477. b.append("author a <b>\n");
  478. byte[] data = encodeASCII(b.toString());
  479. assertCorrupt("bad date", OBJ_COMMIT, data);
  480. assertSkipListAccepts(OBJ_COMMIT, data);
  481. }
  482. @Test
  483. public void testInvalidCommitInvalidAuthor6()
  484. throws CorruptObjectException {
  485. StringBuilder b = new StringBuilder();
  486. b.append("tree ");
  487. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  488. b.append('\n');
  489. b.append("author a <b> z");
  490. byte[] data = encodeASCII(b.toString());
  491. assertCorrupt("bad date", OBJ_COMMIT, data);
  492. assertSkipListAccepts(OBJ_COMMIT, data);
  493. }
  494. @Test
  495. public void testInvalidCommitInvalidAuthor7()
  496. throws CorruptObjectException {
  497. StringBuilder b = new StringBuilder();
  498. b.append("tree ");
  499. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  500. b.append('\n');
  501. b.append("author a <b> 1 z");
  502. byte[] data = encodeASCII(b.toString());
  503. assertCorrupt("bad time zone", OBJ_COMMIT, data);
  504. assertSkipListAccepts(OBJ_COMMIT, data);
  505. }
  506. @Test
  507. public void testInvalidCommitInvalidCommitter()
  508. throws CorruptObjectException {
  509. StringBuilder b = new StringBuilder();
  510. b.append("tree ");
  511. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  512. b.append('\n');
  513. b.append("author a <b> 1 +0000\n");
  514. b.append("committer a <");
  515. byte[] data = encodeASCII(b.toString());
  516. assertCorrupt("bad email", OBJ_COMMIT, data);
  517. assertSkipListAccepts(OBJ_COMMIT, data);
  518. }
  519. @Test
  520. public void testValidTag() throws CorruptObjectException {
  521. StringBuilder b = new StringBuilder();
  522. b.append("object ");
  523. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  524. b.append('\n');
  525. b.append("type commit\n");
  526. b.append("tag test-tag\n");
  527. b.append("tagger A. U. Thor <author@localhost> 1 +0000\n");
  528. byte[] data = encodeASCII(b.toString());
  529. checker.checkTag(data);
  530. checker.check(OBJ_TAG, data);
  531. }
  532. @Test
  533. public void testInvalidTagNoObject1() {
  534. assertCorrupt("no object header", OBJ_TAG, new byte[0]);
  535. }
  536. @Test
  537. public void testInvalidTagNoObject2() {
  538. StringBuilder b = new StringBuilder();
  539. b.append("object\t");
  540. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  541. b.append('\n');
  542. assertCorrupt("no object header", OBJ_TAG, b);
  543. }
  544. @Test
  545. public void testInvalidTagNoObject3() {
  546. StringBuilder b = new StringBuilder();
  547. b.append("obejct ");
  548. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  549. b.append('\n');
  550. assertCorrupt("no object header", OBJ_TAG, b);
  551. }
  552. @Test
  553. public void testInvalidTagNoObject4() {
  554. StringBuilder b = new StringBuilder();
  555. b.append("object ");
  556. b.append("zz9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  557. b.append('\n');
  558. assertCorrupt("invalid object", OBJ_TAG, b);
  559. }
  560. @Test
  561. public void testInvalidTagNoObject5() {
  562. StringBuilder b = new StringBuilder();
  563. b.append("object ");
  564. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  565. b.append(" \n");
  566. assertCorrupt("invalid object", OBJ_TAG, b);
  567. }
  568. @Test
  569. public void testInvalidTagNoObject6() {
  570. StringBuilder b = new StringBuilder();
  571. b.append("object ");
  572. b.append("be9");
  573. assertCorrupt("invalid object", OBJ_TAG, b);
  574. }
  575. @Test
  576. public void testInvalidTagNoType1() {
  577. StringBuilder b = new StringBuilder();
  578. b.append("object ");
  579. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  580. b.append('\n');
  581. assertCorrupt("no type header", OBJ_TAG, b);
  582. }
  583. @Test
  584. public void testInvalidTagNoType2() {
  585. StringBuilder b = new StringBuilder();
  586. b.append("object ");
  587. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  588. b.append('\n');
  589. b.append("type\tcommit\n");
  590. assertCorrupt("no type header", OBJ_TAG, b);
  591. }
  592. @Test
  593. public void testInvalidTagNoType3() {
  594. StringBuilder b = new StringBuilder();
  595. b.append("object ");
  596. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  597. b.append('\n');
  598. b.append("tpye commit\n");
  599. assertCorrupt("no type header", OBJ_TAG, b);
  600. }
  601. @Test
  602. public void testInvalidTagNoType4() {
  603. StringBuilder b = new StringBuilder();
  604. b.append("object ");
  605. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  606. b.append('\n');
  607. b.append("type commit");
  608. assertCorrupt("no tag header", OBJ_TAG, b);
  609. }
  610. @Test
  611. public void testInvalidTagNoTagHeader1() {
  612. StringBuilder b = new StringBuilder();
  613. b.append("object ");
  614. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  615. b.append('\n');
  616. b.append("type commit\n");
  617. assertCorrupt("no tag header", OBJ_TAG, b);
  618. }
  619. @Test
  620. public void testInvalidTagNoTagHeader2() {
  621. StringBuilder b = new StringBuilder();
  622. b.append("object ");
  623. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  624. b.append('\n');
  625. b.append("type commit\n");
  626. b.append("tag\tfoo\n");
  627. assertCorrupt("no tag header", OBJ_TAG, b);
  628. }
  629. @Test
  630. public void testInvalidTagNoTagHeader3() {
  631. StringBuilder b = new StringBuilder();
  632. b.append("object ");
  633. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  634. b.append('\n');
  635. b.append("type commit\n");
  636. b.append("tga foo\n");
  637. assertCorrupt("no tag header", OBJ_TAG, b);
  638. }
  639. @Test
  640. public void testValidTagHasNoTaggerHeader() throws CorruptObjectException {
  641. StringBuilder b = new StringBuilder();
  642. b.append("object ");
  643. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  644. b.append('\n');
  645. b.append("type commit\n");
  646. b.append("tag foo\n");
  647. checker.checkTag(encodeASCII(b.toString()));
  648. }
  649. @Test
  650. public void testInvalidTagInvalidTaggerHeader1()
  651. throws CorruptObjectException {
  652. StringBuilder b = new StringBuilder();
  653. b.append("object ");
  654. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  655. b.append('\n');
  656. b.append("type commit\n");
  657. b.append("tag foo\n");
  658. b.append("tagger \n");
  659. byte[] data = encodeASCII(b.toString());
  660. assertCorrupt("missing email", OBJ_TAG, data);
  661. checker.setAllowInvalidPersonIdent(true);
  662. checker.checkTag(data);
  663. checker.setAllowInvalidPersonIdent(false);
  664. assertSkipListAccepts(OBJ_TAG, data);
  665. }
  666. @Test
  667. public void testInvalidTagInvalidTaggerHeader3()
  668. throws CorruptObjectException {
  669. StringBuilder b = new StringBuilder();
  670. b.append("object ");
  671. b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
  672. b.append('\n');
  673. b.append("type commit\n");
  674. b.append("tag foo\n");
  675. b.append("tagger a < 1 +000\n");
  676. byte[] data = encodeASCII(b.toString());
  677. assertCorrupt("bad email", OBJ_TAG, data);
  678. assertSkipListAccepts(OBJ_TAG, data);
  679. }
  680. @Test
  681. public void testValidEmptyTree() throws CorruptObjectException {
  682. checker.checkTree(new byte[0]);
  683. checker.check(OBJ_TREE, new byte[0]);
  684. }
  685. @Test
  686. public void testValidTree1() throws CorruptObjectException {
  687. StringBuilder b = new StringBuilder();
  688. entry(b, "100644 regular-file");
  689. checker.checkTree(encodeASCII(b.toString()));
  690. }
  691. @Test
  692. public void testValidTree2() throws CorruptObjectException {
  693. StringBuilder b = new StringBuilder();
  694. entry(b, "100755 executable");
  695. checker.checkTree(encodeASCII(b.toString()));
  696. }
  697. @Test
  698. public void testValidTree3() throws CorruptObjectException {
  699. StringBuilder b = new StringBuilder();
  700. entry(b, "40000 tree");
  701. checker.checkTree(encodeASCII(b.toString()));
  702. }
  703. @Test
  704. public void testValidTree4() throws CorruptObjectException {
  705. StringBuilder b = new StringBuilder();
  706. entry(b, "120000 symlink");
  707. checker.checkTree(encodeASCII(b.toString()));
  708. }
  709. @Test
  710. public void testValidTree5() throws CorruptObjectException {
  711. StringBuilder b = new StringBuilder();
  712. entry(b, "160000 git link");
  713. checker.checkTree(encodeASCII(b.toString()));
  714. }
  715. @Test
  716. public void testValidTree6() throws CorruptObjectException {
  717. StringBuilder b = new StringBuilder();
  718. entry(b, "100644 .a");
  719. checker.checkTree(encodeASCII(b.toString()));
  720. }
  721. @Test
  722. public void testValidTreeWithGitmodules() throws CorruptObjectException {
  723. ObjectId treeId = ObjectId
  724. .fromString("0123012301230123012301230123012301230123");
  725. StringBuilder b = new StringBuilder();
  726. ObjectId blobId = entry(b, "100644 .gitmodules");
  727. byte[] data = encodeASCII(b.toString());
  728. checker.checkTree(treeId, data);
  729. assertEquals(1, checker.getGitsubmodules().size());
  730. assertEquals(treeId, checker.getGitsubmodules().get(0).getTreeId());
  731. assertEquals(blobId, checker.getGitsubmodules().get(0).getBlobId());
  732. }
  733. /*
  734. * Windows case insensitivity and long file name handling
  735. * means that .gitmodules has many synonyms.
  736. *
  737. * Examples inspired by git.git's t/t0060-path-utils.sh, by
  738. * Johannes Schindelin and Congyi Wu.
  739. */
  740. @Test
  741. public void testNTFSGitmodules() throws CorruptObjectException {
  742. for (String gitmodules : new String[] {
  743. ".GITMODULES",
  744. ".gitmodules",
  745. ".Gitmodules",
  746. ".gitmoduleS",
  747. "gitmod~1",
  748. "GITMOD~1",
  749. "gitmod~4",
  750. "GI7EBA~1",
  751. "gi7eba~9",
  752. "GI7EB~10",
  753. "GI7E~123",
  754. "~1000000",
  755. "~9999999"
  756. }) {
  757. checker = new ObjectChecker(); // Reset the ObjectChecker state.
  758. checker.setSafeForWindows(true);
  759. ObjectId treeId = ObjectId
  760. .fromString("0123012301230123012301230123012301230123");
  761. StringBuilder b = new StringBuilder();
  762. ObjectId blobId = entry(b, "100644 " + gitmodules);
  763. byte[] data = encodeASCII(b.toString());
  764. checker.checkTree(treeId, data);
  765. assertEquals(1, checker.getGitsubmodules().size());
  766. assertEquals(treeId, checker.getGitsubmodules().get(0).getTreeId());
  767. assertEquals(blobId, checker.getGitsubmodules().get(0).getBlobId());
  768. }
  769. }
  770. @Test
  771. public void testNotGitmodules() throws CorruptObjectException {
  772. for (String notGitmodules : new String[] {
  773. ".gitmodu",
  774. ".gitmodules oh never mind",
  775. }) {
  776. checker = new ObjectChecker(); // Reset the ObjectChecker state.
  777. checker.setSafeForWindows(true);
  778. ObjectId treeId = ObjectId
  779. .fromString("0123012301230123012301230123012301230123");
  780. StringBuilder b = new StringBuilder();
  781. entry(b, "100644 " + notGitmodules);
  782. byte[] data = encodeASCII(b.toString());
  783. checker.checkTree(treeId, data);
  784. assertEquals(0, checker.getGitsubmodules().size());
  785. }
  786. }
  787. /*
  788. * TODO HFS: match ".gitmodules" case-insensitively, after stripping out
  789. * certain zero-length Unicode code points that HFS+ strips out
  790. */
  791. @Test
  792. public void testValidTreeWithGitmodulesUppercase()
  793. throws CorruptObjectException {
  794. ObjectId treeId = ObjectId
  795. .fromString("0123012301230123012301230123012301230123");
  796. StringBuilder b = new StringBuilder();
  797. ObjectId blobId = entry(b, "100644 .GITMODULES");
  798. byte[] data = encodeASCII(b.toString());
  799. checker.setSafeForWindows(true);
  800. checker.checkTree(treeId, data);
  801. assertEquals(1, checker.getGitsubmodules().size());
  802. assertEquals(treeId, checker.getGitsubmodules().get(0).getTreeId());
  803. assertEquals(blobId, checker.getGitsubmodules().get(0).getBlobId());
  804. }
  805. @Test
  806. public void testTreeWithInvalidGitmodules() throws CorruptObjectException {
  807. ObjectId treeId = ObjectId
  808. .fromString("0123012301230123012301230123012301230123");
  809. StringBuilder b = new StringBuilder();
  810. entry(b, "100644 .gitmodulez");
  811. byte[] data = encodeASCII(b.toString());
  812. checker.checkTree(treeId, data);
  813. checker.setSafeForWindows(true);
  814. assertEquals(0, checker.getGitsubmodules().size());
  815. }
  816. @Test
  817. public void testNullSha1InTreeEntry() throws CorruptObjectException {
  818. byte[] data = concat(
  819. encodeASCII("100644 A"), new byte[] { '\0' },
  820. new byte[OBJECT_ID_LENGTH]);
  821. assertCorrupt("entry points to null SHA-1", OBJ_TREE, data);
  822. assertSkipListAccepts(OBJ_TREE, data);
  823. checker.setIgnore(NULL_SHA1, true);
  824. checker.checkTree(data);
  825. }
  826. @Test
  827. public void testValidPosixTree() throws CorruptObjectException {
  828. checkOneName("a<b>c:d|e");
  829. checkOneName("test ");
  830. checkOneName("test.");
  831. checkOneName("NUL");
  832. }
  833. @Test
  834. public void testValidTreeSorting1() throws CorruptObjectException {
  835. StringBuilder b = new StringBuilder();
  836. entry(b, "100644 fooaaa");
  837. entry(b, "100755 foobar");
  838. checker.checkTree(encodeASCII(b.toString()));
  839. }
  840. @Test
  841. public void testValidTreeSorting2() throws CorruptObjectException {
  842. StringBuilder b = new StringBuilder();
  843. entry(b, "100755 fooaaa");
  844. entry(b, "100644 foobar");
  845. checker.checkTree(encodeASCII(b.toString()));
  846. }
  847. @Test
  848. public void testValidTreeSorting3() throws CorruptObjectException {
  849. StringBuilder b = new StringBuilder();
  850. entry(b, "40000 a");
  851. entry(b, "100644 b");
  852. checker.checkTree(encodeASCII(b.toString()));
  853. }
  854. @Test
  855. public void testValidTreeSorting4() throws CorruptObjectException {
  856. StringBuilder b = new StringBuilder();
  857. entry(b, "100644 a");
  858. entry(b, "40000 b");
  859. checker.checkTree(encodeASCII(b.toString()));
  860. }
  861. @Test
  862. public void testValidTreeSorting5() throws CorruptObjectException {
  863. StringBuilder b = new StringBuilder();
  864. entry(b, "100644 a.c");
  865. entry(b, "40000 a");
  866. entry(b, "100644 a0c");
  867. checker.checkTree(encodeASCII(b.toString()));
  868. }
  869. @Test
  870. public void testValidTreeSorting6() throws CorruptObjectException {
  871. StringBuilder b = new StringBuilder();
  872. entry(b, "40000 a");
  873. entry(b, "100644 apple");
  874. checker.checkTree(encodeASCII(b.toString()));
  875. }
  876. @Test
  877. public void testValidTreeSorting7() throws CorruptObjectException {
  878. StringBuilder b = new StringBuilder();
  879. entry(b, "40000 an orang");
  880. entry(b, "40000 an orange");
  881. checker.checkTree(encodeASCII(b.toString()));
  882. }
  883. @Test
  884. public void testValidTreeSorting8() throws CorruptObjectException {
  885. StringBuilder b = new StringBuilder();
  886. entry(b, "100644 a");
  887. entry(b, "100644 a0c");
  888. entry(b, "100644 b");
  889. checker.checkTree(encodeASCII(b.toString()));
  890. }
  891. @Test
  892. public void testAcceptTreeModeWithZero() throws CorruptObjectException {
  893. StringBuilder b = new StringBuilder();
  894. entry(b, "040000 a");
  895. byte[] data = encodeASCII(b.toString());
  896. checker.setAllowLeadingZeroFileMode(true);
  897. checker.checkTree(data);
  898. checker.setAllowLeadingZeroFileMode(false);
  899. assertSkipListAccepts(OBJ_TREE, data);
  900. checker.setIgnore(ZERO_PADDED_FILEMODE, true);
  901. checker.checkTree(data);
  902. }
  903. @Test
  904. public void testInvalidTreeModeStartsWithZero1() {
  905. StringBuilder b = new StringBuilder();
  906. entry(b, "0 a");
  907. assertCorrupt("mode starts with '0'", OBJ_TREE, b);
  908. }
  909. @Test
  910. public void testInvalidTreeModeStartsWithZero2() {
  911. StringBuilder b = new StringBuilder();
  912. entry(b, "0100644 a");
  913. assertCorrupt("mode starts with '0'", OBJ_TREE, b);
  914. }
  915. @Test
  916. public void testInvalidTreeModeStartsWithZero3() {
  917. StringBuilder b = new StringBuilder();
  918. entry(b, "040000 a");
  919. assertCorrupt("mode starts with '0'", OBJ_TREE, b);
  920. }
  921. @Test
  922. public void testInvalidTreeModeNotOctal1() {
  923. StringBuilder b = new StringBuilder();
  924. entry(b, "8 a");
  925. assertCorrupt("invalid mode character", OBJ_TREE, b);
  926. }
  927. @Test
  928. public void testInvalidTreeModeNotOctal2() {
  929. StringBuilder b = new StringBuilder();
  930. entry(b, "Z a");
  931. byte[] data = encodeASCII(b.toString());
  932. assertCorrupt("invalid mode character", OBJ_TREE, data);
  933. assertSkipListRejects("invalid mode character", OBJ_TREE, data);
  934. }
  935. @Test
  936. public void testInvalidTreeModeNotSupportedMode1() {
  937. StringBuilder b = new StringBuilder();
  938. entry(b, "1 a");
  939. byte[] data = encodeASCII(b.toString());
  940. assertCorrupt("invalid mode 1", OBJ_TREE, data);
  941. assertSkipListRejects("invalid mode 1", OBJ_TREE, data);
  942. }
  943. @Test
  944. public void testInvalidTreeModeNotSupportedMode2() {
  945. StringBuilder b = new StringBuilder();
  946. entry(b, "170000 a");
  947. assertCorrupt("invalid mode " + 0170000, OBJ_TREE, b);
  948. }
  949. @Test
  950. public void testInvalidTreeModeMissingName() {
  951. StringBuilder b = new StringBuilder();
  952. b.append("100644");
  953. assertCorrupt("truncated in mode", OBJ_TREE, b);
  954. }
  955. @Test
  956. public void testInvalidTreeNameContainsSlash()
  957. throws CorruptObjectException {
  958. StringBuilder b = new StringBuilder();
  959. entry(b, "100644 a/b");
  960. byte[] data = encodeASCII(b.toString());
  961. assertCorrupt("name contains '/'", OBJ_TREE, data);
  962. assertSkipListAccepts(OBJ_TREE, data);
  963. checker.setIgnore(FULL_PATHNAME, true);
  964. checker.checkTree(data);
  965. }
  966. @Test
  967. public void testInvalidTreeNameIsEmpty() throws CorruptObjectException {
  968. StringBuilder b = new StringBuilder();
  969. entry(b, "100644 ");
  970. byte[] data = encodeASCII(b.toString());
  971. assertCorrupt("zero length name", OBJ_TREE, data);
  972. assertSkipListAccepts(OBJ_TREE, data);
  973. checker.setIgnore(EMPTY_NAME, true);
  974. checker.checkTree(data);
  975. }
  976. @Test
  977. public void testInvalidTreeNameIsDot() throws CorruptObjectException {
  978. StringBuilder b = new StringBuilder();
  979. entry(b, "100644 .");
  980. byte[] data = encodeASCII(b.toString());
  981. assertCorrupt("invalid name '.'", OBJ_TREE, data);
  982. assertSkipListAccepts(OBJ_TREE, data);
  983. checker.setIgnore(HAS_DOT, true);
  984. checker.checkTree(data);
  985. }
  986. @Test
  987. public void testInvalidTreeNameIsDotDot() throws CorruptObjectException {
  988. StringBuilder b = new StringBuilder();
  989. entry(b, "100644 ..");
  990. byte[] data = encodeASCII(b.toString());
  991. assertCorrupt("invalid name '..'", OBJ_TREE, data);
  992. assertSkipListAccepts(OBJ_TREE, data);
  993. checker.setIgnore(HAS_DOTDOT, true);
  994. checker.checkTree(data);
  995. }
  996. @Test
  997. public void testInvalidTreeNameIsGit() throws CorruptObjectException {
  998. StringBuilder b = new StringBuilder();
  999. entry(b, "100644 .git");
  1000. byte[] data = encodeASCII(b.toString());
  1001. assertCorrupt("invalid name '.git'", OBJ_TREE, data);
  1002. assertSkipListAccepts(OBJ_TREE, data);
  1003. checker.setIgnore(HAS_DOTGIT, true);
  1004. checker.checkTree(data);
  1005. }
  1006. @Test
  1007. public void testInvalidTreeNameIsMixedCaseGit()
  1008. throws CorruptObjectException {
  1009. StringBuilder b = new StringBuilder();
  1010. entry(b, "100644 .GiT");
  1011. byte[] data = encodeASCII(b.toString());
  1012. assertCorrupt("invalid name '.GiT'", OBJ_TREE, data);
  1013. assertSkipListAccepts(OBJ_TREE, data);
  1014. checker.setIgnore(HAS_DOTGIT, true);
  1015. checker.checkTree(data);
  1016. }
  1017. @Test
  1018. public void testInvalidTreeNameIsMacHFSGit() throws CorruptObjectException {
  1019. StringBuilder b = new StringBuilder();
  1020. entry(b, "100644 .gi\u200Ct");
  1021. byte[] data = encode(b.toString());
  1022. // Fine on POSIX.
  1023. checker.checkTree(data);
  1024. // Rejected on Mac OS.
  1025. checker.setSafeForMacOS(true);
  1026. assertCorrupt(
  1027. "invalid name '.gi\u200Ct' contains ignorable Unicode characters",
  1028. OBJ_TREE, data);
  1029. assertSkipListAccepts(OBJ_TREE, data);
  1030. checker.setIgnore(HAS_DOTGIT, true);
  1031. checker.checkTree(data);
  1032. }
  1033. @Test
  1034. public void testInvalidTreeNameIsMacHFSGit2()
  1035. throws CorruptObjectException {
  1036. StringBuilder b = new StringBuilder();
  1037. entry(b, "100644 \u206B.git");
  1038. byte[] data = encode(b.toString());
  1039. // Fine on POSIX.
  1040. checker.checkTree(data);
  1041. // Rejected on Mac OS.
  1042. checker.setSafeForMacOS(true);
  1043. assertCorrupt(
  1044. "invalid name '\u206B.git' contains ignorable Unicode characters",
  1045. OBJ_TREE, data);
  1046. assertSkipListAccepts(OBJ_TREE, data);
  1047. checker.setIgnore(HAS_DOTGIT, true);
  1048. checker.checkTree(data);
  1049. }
  1050. @Test
  1051. public void testInvalidTreeNameIsMacHFSGit3()
  1052. throws CorruptObjectException {
  1053. StringBuilder b = new StringBuilder();
  1054. entry(b, "100644 .git\uFEFF");
  1055. byte[] data = encode(b.toString());
  1056. // Fine on POSIX.
  1057. checker.checkTree(data);
  1058. // Rejected on Mac OS.
  1059. checker.setSafeForMacOS(true);
  1060. assertCorrupt(
  1061. "invalid name '.git\uFEFF' contains ignorable Unicode characters",
  1062. OBJ_TREE, data);
  1063. assertSkipListAccepts(OBJ_TREE, data);
  1064. checker.setIgnore(HAS_DOTGIT, true);
  1065. checker.checkTree(data);
  1066. }
  1067. @Test
  1068. public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd()
  1069. throws CorruptObjectException {
  1070. byte[] data = concat(encode("100644 .git"),
  1071. new byte[] { (byte) 0xef });
  1072. StringBuilder b = new StringBuilder();
  1073. entry(b, "");
  1074. data = concat(data, encode(b.toString()));
  1075. // Fine on POSIX.
  1076. checker.checkTree(data);
  1077. // Rejected on Mac OS.
  1078. checker.setSafeForMacOS(true);
  1079. assertCorrupt(
  1080. "invalid name contains byte sequence '0xef' which is not a valid UTF-8 character",
  1081. OBJ_TREE, data);
  1082. assertSkipListAccepts(OBJ_TREE, data);
  1083. }
  1084. @Test
  1085. public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd2()
  1086. throws CorruptObjectException {
  1087. byte[] data = concat(encode("100644 .git"),
  1088. new byte[] {
  1089. (byte) 0xe2, (byte) 0xab });
  1090. StringBuilder b = new StringBuilder();
  1091. entry(b, "");
  1092. data = concat(data, encode(b.toString()));
  1093. // Fine on POSIX.
  1094. checker.checkTree(data);
  1095. // Rejected on Mac OS.
  1096. checker.setSafeForMacOS(true);
  1097. assertCorrupt(
  1098. "invalid name contains byte sequence '0xe2ab' which is not a valid UTF-8 character",
  1099. OBJ_TREE, data);
  1100. assertSkipListAccepts(OBJ_TREE, data);
  1101. }
  1102. @Test
  1103. public void testInvalidTreeNameIsNotMacHFSGit()
  1104. throws CorruptObjectException {
  1105. StringBuilder b = new StringBuilder();
  1106. entry(b, "100644 .git\u200Cx");
  1107. byte[] data = encode(b.toString());
  1108. checker.setSafeForMacOS(true);
  1109. checker.checkTree(data);
  1110. }
  1111. @Test
  1112. public void testInvalidTreeNameIsNotMacHFSGit2()
  1113. throws CorruptObjectException {
  1114. StringBuilder b = new StringBuilder();
  1115. entry(b, "100644 .kit\u200C");
  1116. byte[] data = encode(b.toString());
  1117. checker.setSafeForMacOS(true);
  1118. checker.checkTree(data);
  1119. }
  1120. @Test
  1121. public void testInvalidTreeNameIsNotMacHFSGitOtherPlatform()
  1122. throws CorruptObjectException {
  1123. StringBuilder b = new StringBuilder();
  1124. entry(b, "100644 .git\u200C");
  1125. byte[] data = encode(b.toString());
  1126. checker.checkTree(data);
  1127. }
  1128. @Test
  1129. public void testInvalidTreeNameIsDotGitDot() throws CorruptObjectException {
  1130. StringBuilder b = new StringBuilder();
  1131. entry(b, "100644 .git.");
  1132. byte[] data = encodeASCII(b.toString());
  1133. assertCorrupt("invalid name '.git.'", OBJ_TREE, data);
  1134. assertSkipListAccepts(OBJ_TREE, data);
  1135. checker.setIgnore(HAS_DOTGIT, true);
  1136. checker.checkTree(data);
  1137. }
  1138. @Test
  1139. public void testValidTreeNameIsDotGitDotDot()
  1140. throws CorruptObjectException {
  1141. StringBuilder b = new StringBuilder();
  1142. entry(b, "100644 .git..");
  1143. checker.checkTree(encodeASCII(b.toString()));
  1144. }
  1145. @Test
  1146. public void testInvalidTreeNameIsDotGitSpace()
  1147. throws CorruptObjectException {
  1148. StringBuilder b = new StringBuilder();
  1149. entry(b, "100644 .git ");
  1150. byte[] data = encodeASCII(b.toString());
  1151. assertCorrupt("invalid name '.git '", OBJ_TREE, data);
  1152. assertSkipListAccepts(OBJ_TREE, data);
  1153. checker.setIgnore(HAS_DOTGIT, true);
  1154. checker.checkTree(data);
  1155. }
  1156. @Test
  1157. public void testInvalidTreeNameIsDotGitSomething()
  1158. throws CorruptObjectException {
  1159. StringBuilder b = new StringBuilder();
  1160. entry(b, "100644 .gitfoobar");
  1161. byte[] data = encodeASCII(b.toString());
  1162. checker.checkTree(data);
  1163. }
  1164. @Test
  1165. public void testInvalidTreeNameIsDotGitSomethingSpaceSomething()
  1166. throws CorruptObjectException {
  1167. StringBuilder b = new StringBuilder();
  1168. entry(b, "100644 .gitfoo bar");
  1169. byte[] data = encodeASCII(b.toString());
  1170. checker.checkTree(data);
  1171. }
  1172. @Test
  1173. public void testInvalidTreeNameIsDotGitSomethingDot()
  1174. throws CorruptObjectException {
  1175. StringBuilder b = new StringBuilder();
  1176. entry(b, "100644 .gitfoobar.");
  1177. byte[] data = encodeASCII(b.toString());
  1178. checker.checkTree(data);
  1179. }
  1180. @Test
  1181. public void testInvalidTreeNameIsDotGitSomethingDotDot()
  1182. throws CorruptObjectException {
  1183. StringBuilder b = new StringBuilder();
  1184. entry(b, "100644 .gitfoobar..");
  1185. byte[] data = encodeASCII(b.toString());
  1186. checker.checkTree(data);
  1187. }
  1188. @Test
  1189. public void testInvalidTreeNameIsDotGitDotSpace()
  1190. throws CorruptObjectException {
  1191. StringBuilder b = new StringBuilder();
  1192. entry(b, "100644 .git. ");
  1193. byte[] data = encodeASCII(b.toString());
  1194. assertCorrupt("invalid name '.git. '", OBJ_TREE, data);
  1195. assertSkipListAccepts(OBJ_TREE, data);
  1196. checker.setIgnore(HAS_DOTGIT, true);
  1197. checker.checkTree(data);
  1198. }
  1199. @Test
  1200. public void testInvalidTreeNameIsDotGitSpaceDot()
  1201. throws CorruptObjectException {
  1202. StringBuilder b = new StringBuilder();
  1203. entry(b, "100644 .git . ");
  1204. byte[] data = encodeASCII(b.toString());
  1205. assertCorrupt("invalid name '.git . '", OBJ_TREE, data);
  1206. assertSkipListAccepts(OBJ_TREE, data);
  1207. checker.setIgnore(HAS_DOTGIT, true);
  1208. checker.checkTree(data);
  1209. }
  1210. @Test
  1211. public void testInvalidTreeNameIsGITTilde1() throws CorruptObjectException {
  1212. StringBuilder b = new StringBuilder();
  1213. entry(b, "100644 GIT~1");
  1214. byte[] data = encodeASCII(b.toString());
  1215. assertCorrupt("invalid name 'GIT~1'", OBJ_TREE, data);
  1216. assertSkipListAccepts(OBJ_TREE, data);
  1217. checker.setIgnore(HAS_DOTGIT, true);
  1218. checker.checkTree(data);
  1219. }
  1220. @Test
  1221. public void testInvalidTreeNameIsGiTTilde1() throws CorruptObjectException {
  1222. StringBuilder b = new StringBuilder();
  1223. entry(b, "100644 GiT~1");
  1224. byte[] data = encodeASCII(b.toString());
  1225. assertCorrupt("invalid name 'GiT~1'", OBJ_TREE, data);
  1226. assertSkipListAccepts(OBJ_TREE, data);
  1227. checker.setIgnore(HAS_DOTGIT, true);
  1228. checker.checkTree(data);
  1229. }
  1230. @Test
  1231. public void testValidTreeNameIsGitTilde11() throws CorruptObjectException {
  1232. StringBuilder b = new StringBuilder();
  1233. entry(b, "100644 GIT~11");
  1234. byte[] data = encodeASCII(b.toString());
  1235. checker.checkTree(data);
  1236. }
  1237. @Test
  1238. public void testInvalidTreeTruncatedInName() {
  1239. StringBuilder b = new StringBuilder();
  1240. b.append("100644 b");
  1241. byte[] data = encodeASCII(b.toString());
  1242. assertCorrupt("truncated in name", OBJ_TREE, data);
  1243. assertSkipListRejects("truncated in name", OBJ_TREE, data);
  1244. }
  1245. @Test
  1246. public void testInvalidTreeTruncatedInObjectId() {
  1247. StringBuilder b = new StringBuilder();
  1248. b.append("100644 b\0\1\2");
  1249. byte[] data = encodeASCII(b.toString());
  1250. assertCorrupt("truncated in object id", OBJ_TREE, data);
  1251. assertSkipListRejects("truncated in object id", OBJ_TREE, data);
  1252. }
  1253. @Test
  1254. public void testInvalidTreeBadSorting1() throws CorruptObjectException {
  1255. StringBuilder b = new StringBuilder();
  1256. entry(b, "100644 foobar");
  1257. entry(b, "100644 fooaaa");
  1258. byte[] data = encodeASCII(b.toString());
  1259. assertCorrupt("incorrectly sorted", OBJ_TREE, data);
  1260. ObjectId id = idFor(OBJ_TREE, data);
  1261. try {
  1262. checker.check(id, OBJ_TREE, data);
  1263. fail("Did not throw CorruptObjectException");
  1264. } catch (CorruptObjectException e) {
  1265. assertSame(TREE_NOT_SORTED, e.getErrorType());
  1266. assertEquals("treeNotSorted: object " + id.name()
  1267. + ": incorrectly sorted", e.getMessage());
  1268. }
  1269. assertSkipListAccepts(OBJ_TREE, data);
  1270. checker.setIgnore(TREE_NOT_SORTED, true);
  1271. checker.checkTree(data);
  1272. }
  1273. @Test
  1274. public void testInvalidTreeBadSorting2() throws CorruptObjectException {
  1275. StringBuilder b = new StringBuilder();
  1276. entry(b, "40000 a");
  1277. entry(b, "100644 a.c");
  1278. byte[] data = encodeASCII(b.toString());
  1279. assertCorrupt("incorrectly sorted", OBJ_TREE, data);
  1280. assertSkipListAccepts(OBJ_TREE, data);
  1281. checker.setIgnore(TREE_NOT_SORTED, true);
  1282. checker.checkTree(data);
  1283. }
  1284. @Test
  1285. public void testInvalidTreeBadSorting3() throws CorruptObjectException {
  1286. StringBuilder b = new StringBuilder();
  1287. entry(b, "100644 a0c");
  1288. entry(b, "40000 a");
  1289. byte[] data = encodeASCII(b.toString());
  1290. assertCorrupt("incorrectly sorted", OBJ_TREE, data);
  1291. assertSkipListAccepts(OBJ_TREE, data);
  1292. checker.setIgnore(TREE_NOT_SORTED, true);
  1293. checker.checkTree(data);
  1294. }
  1295. @Test
  1296. public void testInvalidTreeDuplicateNames1_File()
  1297. throws CorruptObjectException {
  1298. StringBuilder b = new StringBuilder();
  1299. entry(b, "100644 a");
  1300. entry(b, "100644 a");
  1301. byte[] data = encodeASCII(b.toString());
  1302. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1303. assertSkipListAccepts(OBJ_TREE, data);
  1304. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1305. checker.checkTree(data);
  1306. }
  1307. @Test
  1308. public void testInvalidTreeDuplicateNames1_Tree()
  1309. throws CorruptObjectException {
  1310. StringBuilder b = new StringBuilder();
  1311. entry(b, "40000 a");
  1312. entry(b, "40000 a");
  1313. byte[] data = encodeASCII(b.toString());
  1314. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1315. assertSkipListAccepts(OBJ_TREE, data);
  1316. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1317. checker.checkTree(data);
  1318. }
  1319. @Test
  1320. public void testInvalidTreeDuplicateNames2() throws CorruptObjectException {
  1321. StringBuilder b = new StringBuilder();
  1322. entry(b, "100644 a");
  1323. entry(b, "100755 a");
  1324. byte[] data = encodeASCII(b.toString());
  1325. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1326. assertSkipListAccepts(OBJ_TREE, data);
  1327. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1328. checker.checkTree(data);
  1329. }
  1330. @Test
  1331. public void testInvalidTreeDuplicateNames3() throws CorruptObjectException {
  1332. StringBuilder b = new StringBuilder();
  1333. entry(b, "100644 a");
  1334. entry(b, "40000 a");
  1335. byte[] data = encodeASCII(b.toString());
  1336. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1337. assertSkipListAccepts(OBJ_TREE, data);
  1338. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1339. checker.checkTree(data);
  1340. }
  1341. @Test
  1342. public void testInvalidTreeDuplicateNames4() throws CorruptObjectException {
  1343. StringBuilder b = new StringBuilder();
  1344. entry(b, "100644 a");
  1345. entry(b, "100644 a.c");
  1346. entry(b, "100644 a.d");
  1347. entry(b, "100644 a.e");
  1348. entry(b, "40000 a");
  1349. entry(b, "100644 zoo");
  1350. byte[] data = encodeASCII(b.toString());
  1351. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1352. assertSkipListAccepts(OBJ_TREE, data);
  1353. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1354. checker.checkTree(data);
  1355. }
  1356. @Test
  1357. public void testInvalidTreeDuplicateNames5()
  1358. throws CorruptObjectException {
  1359. StringBuilder b = new StringBuilder();
  1360. entry(b, "100644 A");
  1361. entry(b, "100644 a");
  1362. byte[] data = b.toString().getBytes(CHARSET);
  1363. checker.setSafeForWindows(true);
  1364. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1365. assertSkipListAccepts(OBJ_TREE, data);
  1366. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1367. checker.checkTree(data);
  1368. }
  1369. @Test
  1370. public void testInvalidTreeDuplicateNames6()
  1371. throws CorruptObjectException {
  1372. StringBuilder b = new StringBuilder();
  1373. entry(b, "100644 A");
  1374. entry(b, "100644 a");
  1375. byte[] data = b.toString().getBytes(CHARSET);
  1376. checker.setSafeForMacOS(true);
  1377. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1378. assertSkipListAccepts(OBJ_TREE, data);
  1379. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1380. checker.checkTree(data);
  1381. }
  1382. @Test
  1383. public void testInvalidTreeDuplicateNames7()
  1384. throws CorruptObjectException {
  1385. StringBuilder b = new StringBuilder();
  1386. entry(b, "100644 \u0065\u0301");
  1387. entry(b, "100644 \u00e9");
  1388. byte[] data = b.toString().getBytes(CHARSET);
  1389. checker.setSafeForMacOS(true);
  1390. assertCorrupt("duplicate entry names", OBJ_TREE, data);
  1391. assertSkipListAccepts(OBJ_TREE, data);
  1392. checker.setIgnore(DUPLICATE_ENTRIES, true);
  1393. checker.checkTree(data);
  1394. }
  1395. @Test
  1396. public void testInvalidTreeDuplicateNames8()
  1397. throws CorruptObjectException {
  1398. StringBuilder b = new StringBuilder();
  1399. entry(b, "100644 A");
  1400. checker.setSafeForMacOS(true);
  1401. checker.checkTree(b.toString().getBytes(CHARSET));
  1402. }
  1403. @Test
  1404. public void testRejectNulInPathSegment() {
  1405. try {
  1406. checker.checkPathSegment(encodeASCII("a\u0000b"), 0, 3);
  1407. fail("incorrectly accepted NUL in middle of name");
  1408. } catch (CorruptObjectException e) {
  1409. assertEquals("name contains byte 0x00", e.getMessage());
  1410. }
  1411. }
  1412. @Test
  1413. public void testRejectSpaceAtEndOnWindows() {
  1414. checker.setSafeForWindows(true);
  1415. try {
  1416. checkOneName("test ");
  1417. fail("incorrectly accepted space at end");
  1418. } catch (CorruptObjectException e) {
  1419. assertEquals("invalid name ends with ' '", e.getMessage());
  1420. }
  1421. }
  1422. @Test
  1423. public void testBug477090() throws CorruptObjectException {
  1424. checker.setSafeForMacOS(true);
  1425. final byte[] bytes = {
  1426. // U+221E 0xe2889e INFINITY ∞
  1427. (byte) 0xe2, (byte) 0x88, (byte) 0x9e,
  1428. // .html
  1429. 0x2e, 0x68, 0x74, 0x6d, 0x6c };
  1430. checker.checkPathSegment(bytes, 0, bytes.length);
  1431. }
  1432. @Test
  1433. public void testRejectDotAtEndOnWindows() {
  1434. checker.setSafeForWindows(true);
  1435. try {
  1436. checkOneName("test.");
  1437. fail("incorrectly accepted dot at end");
  1438. } catch (CorruptObjectException e) {
  1439. assertEquals("invalid name ends with '.'", e.getMessage());
  1440. }
  1441. }
  1442. @Test
  1443. public void testRejectDevicesOnWindows() {
  1444. checker.setSafeForWindows(true);
  1445. String[] bad = { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3",
  1446. "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2",
  1447. "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" };
  1448. for (String b : bad) {
  1449. try {
  1450. checkOneName(b);
  1451. fail("incorrectly accepted " + b);
  1452. } catch (CorruptObjectException e) {
  1453. assertEquals("invalid name '" + b + "'", e.getMessage());
  1454. }
  1455. try {
  1456. checkOneName(b + ".txt");
  1457. fail("incorrectly accepted " + b + ".txt");
  1458. } catch (CorruptObjectException e) {
  1459. assertEquals("invalid name '" + b + "'", e.getMessage());
  1460. }
  1461. }
  1462. }
  1463. @Test
  1464. public void testRejectInvalidWindowsCharacters() {
  1465. checker.setSafeForWindows(true);
  1466. rejectName('<');
  1467. rejectName('>');
  1468. rejectName(':');
  1469. rejectName('"');
  1470. rejectName('/');
  1471. rejectName('\\');
  1472. rejectName('|');
  1473. rejectName('?');
  1474. rejectName('*');
  1475. for (int i = 1; i <= 31; i++)
  1476. rejectName((byte) i);
  1477. }
  1478. private void rejectName(char c) {
  1479. try {
  1480. checkOneName("te" + c + "st");
  1481. fail("incorrectly accepted with " + c);
  1482. } catch (CorruptObjectException e) {
  1483. assertEquals("name contains '" + c + "'", e.getMessage());
  1484. }
  1485. }
  1486. private void rejectName(byte c) {
  1487. String h = Integer.toHexString(c);
  1488. try {
  1489. checkOneName("te" + ((char) c) + "st");
  1490. fail("incorrectly accepted with 0x" + h);
  1491. } catch (CorruptObjectException e) {
  1492. assertEquals("name contains byte 0x" + h, e.getMessage());
  1493. }
  1494. }
  1495. private void checkOneName(String name) throws CorruptObjectException {
  1496. StringBuilder b = new StringBuilder();
  1497. entry(b, "100644 " + name);
  1498. checker.checkTree(encodeASCII(b.toString()));
  1499. }
  1500. /*
  1501. * Returns the id generated for the entry
  1502. */
  1503. private static ObjectId entry(StringBuilder b, String modeName) {
  1504. byte[] id = new byte[OBJECT_ID_LENGTH];
  1505. b.append(modeName);
  1506. b.append('\0');
  1507. for (int i = 0; i < OBJECT_ID_LENGTH; i++) {
  1508. b.append((char) i);
  1509. id[i] = (byte) i;
  1510. }
  1511. return ObjectId.fromRaw(id);
  1512. }
  1513. private void assertCorrupt(String msg, int type, StringBuilder b) {
  1514. assertCorrupt(msg, type, encodeASCII(b.toString()));
  1515. }
  1516. private void assertCorrupt(String msg, int type, byte[] data) {
  1517. try {
  1518. checker.check(type, data);
  1519. fail("Did not throw CorruptObjectException");
  1520. } catch (CorruptObjectException e) {
  1521. assertEquals(msg, e.getMessage());
  1522. }
  1523. }
  1524. private void assertSkipListAccepts(int type, byte[] data)
  1525. throws CorruptObjectException {
  1526. ObjectId id = idFor(type, data);
  1527. checker.setSkipList(set(id));
  1528. checker.check(id, type, data);
  1529. checker.setSkipList(null);
  1530. }
  1531. private void assertSkipListRejects(String msg, int type, byte[] data) {
  1532. ObjectId id = idFor(type, data);
  1533. checker.setSkipList(set(id));
  1534. try {
  1535. checker.check(id, type, data);
  1536. fail("Did not throw CorruptObjectException");
  1537. } catch (CorruptObjectException e) {
  1538. assertEquals(msg, e.getMessage());
  1539. }
  1540. checker.setSkipList(null);
  1541. }
  1542. private static ObjectIdSet set(ObjectId... ids) {
  1543. return new ObjectIdSet() {
  1544. @Override
  1545. public boolean contains(AnyObjectId objectId) {
  1546. for (ObjectId id : ids) {
  1547. if (id.equals(objectId)) {
  1548. return true;
  1549. }
  1550. }
  1551. return false;
  1552. }
  1553. };
  1554. }
  1555. @SuppressWarnings("resource")
  1556. private static ObjectId idFor(int type, byte[] raw) {
  1557. return new ObjectInserter.Formatter().idFor(type, raw);
  1558. }
  1559. }