Skip to content

Commit a0d93ca

Browse files
Opening FileChannels on readonly file systems no longer attempts to write long filename metadata
fixes #68
1 parent ea8356f commit a0d93ca

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/main/java/org/cryptomator/cryptofs/CryptoFileSystemImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,9 @@ private FileChannel newFileChannel(CryptoPath cleartextFilePath, EffectiveOpenOp
356356
} else {
357357
// might also throw FileAlreadyExists:
358358
FileChannel ch = openCryptoFiles.getOrCreate(ciphertextPath).newFileChannel(options);
359-
longFileNameProvider.getCached(ciphertextPath).ifPresent(LongFileNameProvider.DeflatedFileName::persist);
359+
if (options.writable()) {
360+
longFileNameProvider.getCached(ciphertextPath).ifPresent(LongFileNameProvider.DeflatedFileName::persist);
361+
}
360362
return ch;
361363
}
362364
}

src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.cryptomator.cryptofs.attr.AttributeProvider;
66
import org.cryptomator.cryptofs.attr.AttributeViewProvider;
77
import org.cryptomator.cryptofs.attr.AttributeViewType;
8+
import org.cryptomator.cryptofs.fh.OpenCryptoFile;
89
import org.cryptomator.cryptofs.fh.OpenCryptoFiles;
910
import org.cryptomator.cryptofs.fh.OpenCryptoFiles.TwoPhaseMove;
1011
import org.cryptomator.cryptofs.mocks.FileChannelMock;
@@ -17,6 +18,7 @@
1718
import org.junit.jupiter.api.Test;
1819
import org.mockito.Mockito;
1920

21+
import javax.inject.Named;
2022
import java.io.IOException;
2123
import java.lang.reflect.Field;
2224
import java.nio.ByteBuffer;
@@ -52,6 +54,7 @@
5254
import java.util.Collections;
5355
import java.util.EnumSet;
5456
import java.util.Iterator;
57+
import java.util.Optional;
5558
import java.util.Set;
5659
import java.util.concurrent.TimeUnit;
5760

@@ -333,6 +336,59 @@ public void testNewWatchServiceThrowsUnsupportedOperationException() throws IOEx
333336
inTest.newWatchService();
334337
});
335338
}
339+
340+
@Nested
341+
public class NewFileChannel {
342+
343+
private final CryptoPath cleartextPath = mock(CryptoPath.class, "cleartext");
344+
private final Path ciphertextPath = mock(Path.class, "ciphertext");
345+
private final OpenCryptoFile openCryptoFile = mock(OpenCryptoFile.class);
346+
private final FileChannel fileChannel = mock(FileChannel.class);
347+
348+
@BeforeEach
349+
public void setup() throws IOException {
350+
when(cryptoPathMapper.getCiphertextFileType(cleartextPath)).thenReturn(CiphertextFileType.FILE);
351+
when(cryptoPathMapper.getCiphertextFilePath(cleartextPath, CiphertextFileType.FILE)).thenReturn(ciphertextPath);
352+
when(openCryptoFiles.getOrCreate(ciphertextPath)).thenReturn(openCryptoFile);
353+
when(openCryptoFile.newFileChannel(any())).thenReturn(fileChannel);
354+
}
355+
356+
@Test
357+
@Named("newFileChannel read-only")
358+
public void testNewFileChannelReadOnly() throws IOException {
359+
FileChannel ch = inTest.newFileChannel(cleartextPath, EnumSet.of(StandardOpenOption.READ));
360+
361+
Assertions.assertSame(fileChannel, ch);
362+
verify(readonlyFlag, Mockito.never()).assertWritable();
363+
}
364+
365+
@Test
366+
@Named("newFileChannel read-only with long filename")
367+
public void testNewFileChannelReadOnlyShortened() throws IOException {
368+
LongFileNameProvider.DeflatedFileName deflatedFileName = Mockito.mock(LongFileNameProvider.DeflatedFileName.class);
369+
when(longFileNameProvider.getCached(ciphertextPath)).thenReturn(Optional.of(deflatedFileName));
370+
371+
FileChannel ch = inTest.newFileChannel(cleartextPath, EnumSet.of(StandardOpenOption.READ));
372+
373+
Assertions.assertSame(fileChannel, ch);
374+
verify(readonlyFlag, Mockito.never()).assertWritable();
375+
verify(deflatedFileName, Mockito.never()).persist();
376+
}
377+
378+
@Test
379+
@Named("newFileChannel read-write with long filename")
380+
public void testNewFileChannelReadWriteShortened() throws IOException {
381+
LongFileNameProvider.DeflatedFileName deflatedFileName = Mockito.mock(LongFileNameProvider.DeflatedFileName.class);
382+
when(longFileNameProvider.getCached(ciphertextPath)).thenReturn(Optional.of(deflatedFileName));
383+
384+
FileChannel ch = inTest.newFileChannel(cleartextPath, EnumSet.of(StandardOpenOption.WRITE));
385+
386+
Assertions.assertSame(fileChannel, ch);
387+
verify(readonlyFlag, Mockito.atLeastOnce()).assertWritable();
388+
verify(deflatedFileName).persist();
389+
}
390+
391+
}
336392

337393
@Nested
338394
public class Delete {

0 commit comments

Comments
 (0)