Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DataStoreTest.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DataStoreTest.java (revision 1784247) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DataStoreTest.java (working copy) @@ -24,12 +24,19 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Random; /** @@ -103,14 +110,35 @@ } } + public static void main(String... args) throws NoSuchAlgorithmException { + // create and print a "directory-collision", that is, two byte arrays + // where the hash starts with the same bytes + // those values can be used for testDeleteRecordWithParentCollision + HashMap map = new HashMap(); + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + ByteBuffer input = ByteBuffer.allocate(8); + byte[] array = input.array(); + for(long x = 0;; x++) { + input.putLong(x).flip(); + long h = ByteBuffer.wrap(digest.digest(array)).getLong(); + Long old = map.put(h & 0xffffffffff000000L, x); + if (old != null) { + System.out.println(Long.toHexString(old) + " " + Long.toHexString(x)); + break; + } + } + } + public void testDeleteRecordWithParentCollision() throws Exception { FileDataStore fds = new FileDataStore(); fds.init(testDir + "/fileDeleteCollision"); - String c1 = "06b2f82fd81b2c20"; - String c2 = "02c60cb75083ceef"; - DataRecord d1 = fds.addRecord(IOUtils.toInputStream(c1)); - DataRecord d2 = fds.addRecord(IOUtils.toInputStream(c2)); + ByteArrayInputStream c1 = new ByteArrayInputStream(ByteBuffer + .allocate(8).putLong(0x181c7).array()); + ByteArrayInputStream c2 = new ByteArrayInputStream(ByteBuffer + .allocate(8).putLong(0x11fd78).array()); + DataRecord d1 = fds.addRecord(c1); + DataRecord d2 = fds.addRecord(c2); fds.deleteRecord(d1.getIdentifier()); DataRecord testRecord = fds.getRecordIfStored(d2.getIdentifier()); Index: jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/CachingDataStore.java =================================================================== --- jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/CachingDataStore.java (revision 1784247) +++ jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/CachingDataStore.java (working copy) @@ -93,7 +93,7 @@ /** * The digest algorithm used to uniquely identify records. */ - private static final String DIGEST = "SHA-1"; + private static final String DIGEST = "SHA-256"; private static final String DS_STORE = ".DS_Store"; @@ -389,9 +389,9 @@ /** * Creates a new data record in {@link Backend}. The stream is first - * consumed and the contents are saved in a temporary file and the SHA-1 + * consumed and the contents are saved in a temporary file and the SHA-256 * message digest of the stream is calculated. If a record with the same - * SHA-1 digest (and length) is found then it is returned. Otherwise new + * SHA-256 digest (and length) is found then it is returned. Otherwise new * record is created in {@link Backend} and the temporary file is moved in * place to {@link LocalCache}. * @@ -423,7 +423,7 @@ long currTime = System.currentTimeMillis(); DataIdentifier identifier = new DataIdentifier( encodeHexString(digest.digest())); - LOG.debug("SHA1 of [{}], length =[{}] took [{}]ms ", + LOG.debug("SHA-256 of [{}], length =[{}] took [{}]ms ", new Object[] { identifier, length, (currTime - startTime) }); String fileName = getFileName(identifier); AsyncUploadCacheResult result = null; Index: jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java =================================================================== --- jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java (revision 1784247) +++ jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java (working copy) @@ -71,7 +71,7 @@ /** * The digest algorithm used to uniquely identify records. */ - private static final String DIGEST = "SHA-1"; + private static final String DIGEST = "SHA-256"; /** * The default value for the minimum object size. @@ -163,8 +163,8 @@ /** * Creates a new data record. * The stream is first consumed and the contents are saved in a temporary file - * and the SHA-1 message digest of the stream is calculated. If a - * record with the same SHA-1 digest (and length) is found then it is + * and the SHA-256 message digest of the stream is calculated. If a + * record with the same SHA-256 digest (and length) is found then it is * returned. Otherwise the temporary file is moved in place to become * the new data record that gets returned. * Index: jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java =================================================================== --- jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java (revision 1784247) +++ jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java (working copy) @@ -128,7 +128,7 @@ /** * The digest algorithm used to uniquely identify records. */ - protected static final String DIGEST = "SHA-1"; + protected static final String DIGEST = "SHA-256"; /** * The prefix used for temporary objects.