예제 #1
0
 /**
  * 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());
 }
예제 #2
0
 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()));
 }
예제 #3
0
  @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()));
  }
예제 #4
0
 /**
  * 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());
 }
예제 #5
0
  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();
  }
예제 #6
0
 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();
     }
   }
 }
예제 #7
0
 private static ObjectId hash(final byte[] rawText) {
   return ObjectId.fromRaw(Constants.newMessageDigest().digest(rawText));
 }