diff --git a/src/main/java/org/cryptomator/cryptofs/fh/ChunkCache.java b/src/main/java/org/cryptomator/cryptofs/fh/ChunkCache.java index 9e8e2a20..ee5eb56f 100644 --- a/src/main/java/org/cryptomator/cryptofs/fh/ChunkCache.java +++ b/src/main/java/org/cryptomator/cryptofs/fh/ChunkCache.java @@ -86,9 +86,10 @@ public Chunk putChunk(long chunkIndex, ByteBuffer chunkData) throws IllegalArgum if (chunk == null) { chunk = new Chunk(chunkData, true, () -> releaseChunk(chunkIndex)); } else { - var dst = chunk.data().duplicate().clear(); + var dst = chunk.data().clear(); Preconditions.checkArgument(chunkData.remaining() == dst.remaining()); - dst.put(chunkData); + dst.put(chunkData) // + .flip(); chunk.dirty().set(true); } chunk.currentAccesses().incrementAndGet(); diff --git a/src/test/java/org/cryptomator/cryptofs/CryptoFileChannelWriteReadIntegrationTest.java b/src/test/java/org/cryptomator/cryptofs/CryptoFileChannelWriteReadIntegrationTest.java index 02bda852..2bcbaf42 100644 --- a/src/test/java/org/cryptomator/cryptofs/CryptoFileChannelWriteReadIntegrationTest.java +++ b/src/test/java/org/cryptomator/cryptofs/CryptoFileChannelWriteReadIntegrationTest.java @@ -53,7 +53,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -175,6 +174,25 @@ public void afterEach() throws IOException { Files.deleteIfExists(file); } + //https://github.com/cryptomator/cryptofs/issues/173 + @Test + @DisplayName("First incomplete, then completely filled chunks are stored completely") + public void testFullChunksAreSavedCompletely() throws IOException { + int halfAChunk = 16_384; //half of cleartext chunk size + try (var writer = FileChannel.open(file, CREATE, WRITE)) { + writer.write(ByteBuffer.allocate(3 * halfAChunk), 0); //fill chunk 0, half fill chunk 1 + writer.write(ByteBuffer.allocate(5 * halfAChunk), 0); //fill chunks 0 and 1, half fill chunk 2 + } + + try (var reader = FileChannel.open(file, CREATE, READ)) { + Assertions.assertAll(() -> reader.read(ByteBuffer.allocate(2 * halfAChunk), 0), //read chunk 0 + () -> reader.read(ByteBuffer.allocate(2 * halfAChunk), 2 * halfAChunk), //read chunk 1 + () -> reader.read(ByteBuffer.allocate(halfAChunk), 4 * halfAChunk) //read chunk 2 + ); + } + + } + @Test public void testLockEmptyChannel() throws IOException { try (FileChannel ch = FileChannel.open(file, CREATE, WRITE)) {