Skip to content

Commit cd42970

Browse files
authored
Merge pull request #179 from cryptomator/feature/176-ignore-dirid
Fix: Move directory to existing dir specifiying REPLACE_EXISTING
2 parents 6901c32 + d653636 commit cd42970

File tree

3 files changed

+37
-8
lines changed

3 files changed

+37
-8
lines changed

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

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.cryptomator.cryptofs.common.DeletingFileVisitor;
1919
import org.cryptomator.cryptofs.common.FinallyUtil;
2020
import org.cryptomator.cryptofs.dir.CiphertextDirectoryDeleter;
21+
import org.cryptomator.cryptofs.dir.DirectoryStreamFilters;
2122
import org.cryptomator.cryptofs.dir.DirectoryStreamFactory;
2223
import org.cryptomator.cryptofs.fh.OpenCryptoFiles;
2324
import org.cryptomator.cryptolib.api.Cryptor;
@@ -621,20 +622,21 @@ private void moveDirectory(CryptoPath cleartextSource, CryptoPath cleartextTarge
621622
throw new AtomicMoveNotSupportedException(cleartextSource.toString(), cleartextTarget.toString(), "Replacing directories during move requires non-atomic status checks.");
622623
}
623624
// check if dir is empty:
624-
Path oldCiphertextDir = cryptoPathMapper.getCiphertextDir(cleartextTarget).path;
625-
boolean oldCiphertextDirExists = true;
626-
try (DirectoryStream<Path> ds = Files.newDirectoryStream(oldCiphertextDir)) {
625+
Path targetCiphertextDirContentDir = cryptoPathMapper.getCiphertextDir(cleartextTarget).path;
626+
boolean targetCiphertextDirExists = true;
627+
try (DirectoryStream<Path> ds = Files.newDirectoryStream(targetCiphertextDirContentDir, DirectoryStreamFilters.EXCLUDE_DIR_ID_BACKUP)) {
627628
if (ds.iterator().hasNext()) {
628629
throw new DirectoryNotEmptyException(cleartextTarget.toString());
629630
}
630631
} catch (NoSuchFileException e) {
631-
oldCiphertextDirExists = false;
632-
}
633-
// cleanup dir to be replaced:
634-
if (oldCiphertextDirExists) {
635-
Files.walkFileTree(oldCiphertextDir, DeletingFileVisitor.INSTANCE);
632+
targetCiphertextDirExists = false;
636633
}
634+
//delete dir link
637635
Files.walkFileTree(ciphertextTarget.getRawPath(), DeletingFileVisitor.INSTANCE);
636+
// cleanup content dir
637+
if (targetCiphertextDirExists) {
638+
Files.walkFileTree(targetCiphertextDirContentDir, DeletingFileVisitor.INSTANCE);
639+
}
638640
}
639641

640642
// no exceptions until this point, so MOVE:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.cryptomator.cryptofs.dir;
2+
3+
import org.cryptomator.cryptofs.common.Constants;
4+
5+
import java.nio.file.DirectoryStream;
6+
import java.nio.file.Path;
7+
8+
public interface DirectoryStreamFilters {
9+
10+
static DirectoryStream.Filter<Path> EXCLUDE_DIR_ID_BACKUP = p -> !p.equals(p.resolveSibling(Constants.DIR_BACKUP_FILE_NAME));
11+
12+
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ public static void afterAll() throws IOException {
5858
tmpFs.close();
5959
}
6060

61+
@Test
62+
@DisplayName("Replace an existing, shortened, empty directory")
63+
public void testReplaceExistingShortenedDirEmpty() throws IOException {
64+
try (var fs = setupCryptoFs(50, 100, false)) {
65+
var dirName50Chars = "/target_89_123456789_123456789_123456789_123456789_"; //since filename encryption increases filename length, 50 cleartext chars are sufficient
66+
var source = fs.getPath("/sourceDir");
67+
var target = fs.getPath(dirName50Chars);
68+
Files.createDirectory(source);
69+
Files.createDirectory(target);
70+
assertDoesNotThrow(() -> Files.move(source, target, REPLACE_EXISTING));
71+
assertTrue(Files.notExists(source));
72+
assertTrue(Files.exists(target));
73+
}
74+
}
75+
6176
@Test
6277
@DisplayName("Replace an existing, shortened file")
6378
public void testReplaceExistingShortenedFile() throws IOException {

0 commit comments

Comments
 (0)