/** * Compute the name of an object, without inserting it. * * @param type type code of the object to store. * @param data complete content of the object. * @param off first position within {@code data}. * @param len number of bytes to copy from {@code data}. * @return the name of the object. */ public ObjectId idFor(int type, byte[] data, int off, int len) { MessageDigest md = digest(); md.update(Constants.encodedTypeString(type)); md.update((byte) ' '); md.update(Constants.encodeASCII(len)); md.update((byte) 0); md.update(data, off, len); return ObjectId.fromRaw(md.digest()); }
private static void assertHash(RevObject id, byte[] bin) { MessageDigest md = Constants.newMessageDigest(); md.update(Constants.encodedTypeString(id.getType())); md.update((byte) ' '); md.update(Constants.encodeASCII(bin.length)); md.update((byte) 0); md.update(bin); assertEquals(id, ObjectId.fromRaw(md.digest())); }
@Test public void testAbbreviateIsActuallyUnique() throws Exception { // This test is far more difficult. We have to manually craft // an input that contains collisions at a particular prefix, // but this is computationally difficult. Instead we force an // index file to have what we want. // ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba"); byte[] idBuf = toByteArray(id); List<PackedObjectInfo> objects = new ArrayList<PackedObjectInfo>(); for (int i = 0; i < 256; i++) { idBuf[9] = (byte) i; objects.add(new PackedObjectInfo(ObjectId.fromRaw(idBuf))); } String packName = "pack-" + id.name(); File packDir = new File(db.getObjectDatabase().getDirectory(), "pack"); File idxFile = new File(packDir, packName + ".idx"); File packFile = new File(packDir, packName + ".pack"); FileUtils.mkdir(packDir, true); OutputStream dst = new SafeBufferedOutputStream(new FileOutputStream(idxFile)); try { PackIndexWriter writer = new PackIndexWriterV2(dst); writer.write(objects, new byte[OBJECT_ID_LENGTH]); } finally { dst.close(); } new FileOutputStream(packFile).close(); assertEquals(id.abbreviate(20), reader.abbreviate(id, 2)); AbbreviatedObjectId abbrev8 = id.abbreviate(8); Collection<ObjectId> matches = reader.resolve(abbrev8); assertNotNull(matches); assertEquals(objects.size(), matches.size()); for (PackedObjectInfo info : objects) assertTrue("contains " + info.name(), matches.contains(info)); try { db.resolve(abbrev8.name()); fail("did not throw AmbiguousObjectException"); } catch (AmbiguousObjectException err) { assertEquals(abbrev8, err.getAbbreviatedObjectId()); matches = err.getCandidates(); assertNotNull(matches); assertEquals(objects.size(), matches.size()); for (PackedObjectInfo info : objects) assertTrue("contains " + info.name(), matches.contains(info)); } assertEquals(id, db.resolve(id.abbreviate(20).name())); }
/** * Compute the name of an object, without inserting it. * * @param objectType type code of the object to store. * @param length number of bytes to scan from {@code in}. * @param in stream providing the object content. The caller is responsible for closing the * stream. * @return the name of the object. * @throws IOException the source stream could not be read. */ public ObjectId idFor(int objectType, long length, InputStream in) throws IOException { MessageDigest md = digest(); md.update(Constants.encodedTypeString(objectType)); md.update((byte) ' '); md.update(Constants.encodeASCII(length)); md.update((byte) 0); byte[] buf = buffer(); while (length > 0) { int n = in.read(buf, 0, (int) Math.min(length, buf.length)); if (n < 0) throw new EOFException("Unexpected end of input"); md.update(buf, 0, n); length -= n; } return ObjectId.fromRaw(md.digest()); }
private String rand(final HttpServletRequest req, final String suffix) throws UnsupportedEncodingException { // Produce a random suffix that is difficult (or nearly impossible) // for an attacker to guess in advance. This reduces the risk that // an attacker could upload a *.class file and have us send a ZIP // that can be invoked through an applet tag in the victim's browser. // final MessageDigest md = Constants.newMessageDigest(); final byte[] buf = new byte[8]; NB.encodeInt32(buf, 0, req.getRemotePort()); md.update(req.getRemoteAddr().getBytes("UTF-8")); md.update(buf, 0, 4); NB.encodeInt64(buf, 0, System.currentTimeMillis()); md.update(buf, 0, 8); rng.nextBytes(buf); md.update(buf, 0, 8); return suffix + "-" + ObjectId.fromRaw(md.digest()).name(); }
private PackedRefList readPackedRefs() throws IOException { int maxStaleRetries = 5; int retries = 0; while (true) { final FileSnapshot snapshot = FileSnapshot.save(packedRefsFile); final BufferedReader br; final MessageDigest digest = Constants.newMessageDigest(); try { br = new BufferedReader( new InputStreamReader( new DigestInputStream(new FileInputStream(packedRefsFile), digest), CHARSET)); } catch (FileNotFoundException noPackedRefs) { if (packedRefsFile.exists()) { throw noPackedRefs; } // Ignore it and leave the new list empty. return PackedRefList.NO_PACKED_REFS; } try { return new PackedRefList(parsePackedRefs(br), snapshot, ObjectId.fromRaw(digest.digest())); } catch (IOException e) { if (FileUtils.isStaleFileHandle(e) && retries < maxStaleRetries) { if (LOG.isDebugEnabled()) { LOG.debug( MessageFormat.format( JGitText.get().packedRefsHandleIsStale, Integer.valueOf(retries)), e); } retries++; continue; } throw e; } finally { br.close(); } } }
private static ObjectId hash(final byte[] rawText) { return ObjectId.fromRaw(Constants.newMessageDigest().digest(rawText)); }