Skip to content

Commit

Permalink
Merge pull request #133 from cryptomator/feature/132-handle-root-grac…
Browse files Browse the repository at this point in the history
…efully

Handle root path as filesystem API parameter gracefully
  • Loading branch information
infeo authored May 12, 2022
2 parents 59a8ec2 + b920d25 commit 3fcd710
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/main/java/org/cryptomator/cryptofs/CryptoFileSystemImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileStore;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
Expand All @@ -59,6 +60,7 @@
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -288,6 +290,10 @@ boolean isHidden(CryptoPath cleartextPath) throws IOException {
void createDirectory(CryptoPath cleartextDir, FileAttribute<?>... attrs) throws IOException {
readonlyFlag.assertWritable();
assertCleartextNameLengthAllowed(cleartextDir);
if (rootPath.equals(cleartextDir)) {
throw new FileAlreadyExistsException(rootPath.toString());
}

CryptoPath cleartextParentDir = cleartextDir.getParent();
if (cleartextParentDir == null) {
return;
Expand Down Expand Up @@ -382,14 +388,17 @@ private FileChannel newFileChannelFromFile(CryptoPath cleartextFilePath, Effecti
stats.incrementAccessesRead();
}
return ch;
} catch (Exception e){
} catch (Exception e) {
ch.close();
throw e;
}
}

void delete(CryptoPath cleartextPath) throws IOException {
readonlyFlag.assertWritable();
if (rootPath.equals(cleartextPath)) {
throw new FileSystemException("The filesystem root cannot be deleted.");
}
CiphertextFileType ciphertextFileType = cryptoPathMapper.getCiphertextFileType(cleartextPath);
CiphertextFilePath ciphertextPath = cryptoPathMapper.getCiphertextFilePath(cleartextPath);
switch (ciphertextFileType) {
Expand Down Expand Up @@ -421,6 +430,11 @@ void copy(CryptoPath cleartextSource, CryptoPath cleartextTarget, CopyOption...
if (cleartextSource.equals(cleartextTarget)) {
return;
}

if (rootPath.equals(cleartextTarget) && ArrayUtils.contains(options, StandardCopyOption.REPLACE_EXISTING)) {
throw new FileSystemException("The filesystem root cannot be replaced.");
}

CiphertextFileType ciphertextFileType = cryptoPathMapper.getCiphertextFileType(cleartextSource);
if (!ArrayUtils.contains(options, StandardCopyOption.REPLACE_EXISTING)) {
cryptoPathMapper.assertNonExisting(cleartextTarget);
Expand Down Expand Up @@ -515,6 +529,16 @@ private void copyAttributes(Path src, Path dst) throws IOException {
void move(CryptoPath cleartextSource, CryptoPath cleartextTarget, CopyOption... options) throws IOException {
readonlyFlag.assertWritable();
assertCleartextNameLengthAllowed(cleartextTarget);

if (rootPath.equals(cleartextSource)) {
throw new FileSystemException("Filesystem root cannot be moved.");

}

if (rootPath.equals(cleartextTarget)) {
throw new FileAlreadyExistsException(rootPath.toString());
}

if (cleartextSource.equals(cleartextTarget)) {
return;
}
Expand Down Expand Up @@ -628,7 +652,7 @@ CryptoPath getEmptyPath() {
}

void assertCleartextNameLengthAllowed(CryptoPath cleartextPath) throws FileNameTooLongException {
String filename = cleartextPath.getFileName().toString();
String filename = Optional.ofNullable(cleartextPath.getFileName()).map(CryptoPath::toString).orElse(""); //fs root has no explicit name
if (filename.length() > fileSystemProperties.maxCleartextNameLength()) {
throw new FileNameTooLongException(cleartextPath.toString(), fileSystemProperties.maxCleartextNameLength());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemException;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
Expand Down Expand Up @@ -481,6 +482,11 @@ public void setup() throws IOException {

}

@Test
public void testDeleteRootFails() {
Assertions.assertThrows(FileSystemException.class, () -> inTest.delete(root));
}

@Test
public void testDeleteExistingFile() throws IOException {
when(cryptoPathMapper.getCiphertextFileType(cleartextPath)).thenReturn(CiphertextFileType.FILE);
Expand Down Expand Up @@ -607,6 +613,16 @@ public void moveFileToItselfDoesNothing() throws IOException {
verifyNoInteractions(cryptoPathMapper);
}

@Test
public void moveFilesystemRootFails() {
Assertions.assertThrows(FileSystemException.class, () -> inTest.move(root, cleartextDestination));
}

@Test
public void moveToFilesystemRootFails() {
Assertions.assertThrows(FileSystemException.class, () -> inTest.move(cleartextSource, root));
}

@Test
public void moveNonExistingFile() throws IOException {
when(cryptoPathMapper.getCiphertextFileType(cleartextSource)).thenThrow(NoSuchFileException.class);
Expand Down Expand Up @@ -765,6 +781,11 @@ public void copyFileToItselfDoesNothing() throws IOException {
verifyNoInteractions(cryptoPathMapper);
}

@Test
public void copyToRootWithReplacingFails() {
Assertions.assertThrows(FileSystemException.class, () -> inTest.copy(cleartextSource, root, StandardCopyOption.REPLACE_EXISTING));
}

@Test
public void copyNonExistingFile() throws IOException {
when(cryptoPathMapper.getCiphertextFileType(cleartextSource)).thenThrow(NoSuchFileException.class);
Expand Down Expand Up @@ -1001,6 +1022,11 @@ public void setup() {
when(path.getParent()).thenReturn(parent);
}

@Test
public void createFilesystemRootFails() {
Assertions.assertThrows(FileAlreadyExistsException.class, () -> inTest.createDirectory(root));
}

@Test
public void createDirectoryIfPathHasNoParentDoesNothing() throws IOException {
when(path.getParent()).thenReturn(null);
Expand Down Expand Up @@ -1454,4 +1480,35 @@ public void setAttributeOnFile() throws IOException {

}

@Nested
public class AssertFileNameLength {

CryptoPath p = Mockito.mock(CryptoPath.class);

@BeforeEach
public void init() {
when(p.getFileName()).thenReturn(p);
when(p.toString()).thenReturn("takatuka");
}

@Test
public void testFittingPath() {
when(fileSystemProperties.maxCleartextNameLength()).thenReturn(20);
Assertions.assertDoesNotThrow(() -> inTest.assertCleartextNameLengthAllowed(p));
}

@Test
public void testTooLongPath() {
when(fileSystemProperties.maxCleartextNameLength()).thenReturn(4);
Assertions.assertThrows(FileNameTooLongException.class, () -> inTest.assertCleartextNameLengthAllowed(p));
}

@Test
public void testRootPath() {
when(fileSystemProperties.maxCleartextNameLength()).thenReturn(0);
when(p.getFileName()).thenReturn(null);
Assertions.assertDoesNotThrow(() -> inTest.assertCleartextNameLengthAllowed(p));
}
}

}

0 comments on commit 3fcd710

Please sign in to comment.