Skip to content

Commit 3e8dede

Browse files
committed
check existence of alternativeName file to not overwrite data
1 parent 61f3706 commit 3e8dede

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

src/main/java/org/cryptomator/cryptofs/dir/C9rConflictResolver.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import javax.inject.Named;
1515
import java.io.IOException;
1616
import java.nio.charset.StandardCharsets;
17-
import java.nio.file.FileAlreadyExistsException;
1817
import java.nio.file.Files;
1918
import java.nio.file.NoSuchFileException;
2019
import java.nio.file.Path;
@@ -123,18 +122,17 @@ private Stream<Node> renameConflictingFile(Path canonicalPath, Node conflicting)
123122
}
124123

125124
assert alternativeCiphertextName.length() <= maxC9rFileNameLength;
126-
try {
127-
Files.move(conflicting.ciphertextPath, alternativePath, StandardCopyOption.ATOMIC_MOVE);
128-
LOG.info("Renamed conflicting file {} to {}...", conflicting.ciphertextPath, alternativePath);
129-
Node node = new Node(alternativePath);
130-
node.cleartextName = alternativeCleartext;
131-
node.extractedCiphertext = alternativeCiphertext;
132-
return Stream.of(node);
133-
} catch (FileAlreadyExistsException e) {
134-
// TODO notify user about unresolved conflict: `canonicalPath`
135-
LOG.warn("Failed to rename conflicting file {} to {}. Keeping original name.", conflicting.ciphertextPath, alternativePath);
125+
if (Files.exists(alternativePath)) {
126+
LOG.warn("Failed finding alternative name for {}. Keeping original name.", conflicting.ciphertextPath);
136127
return Stream.empty();
137128
}
129+
130+
Files.move(conflicting.ciphertextPath, alternativePath, StandardCopyOption.ATOMIC_MOVE);
131+
LOG.info("Renamed conflicting file {} to {}...", conflicting.ciphertextPath, alternativePath);
132+
Node node = new Node(alternativePath);
133+
node.cleartextName = alternativeCleartext;
134+
node.extractedCiphertext = alternativeCiphertext;
135+
return Stream.of(node);
138136
}
139137

140138

src/test/java/org/cryptomator/cryptofs/dir/C9rConflictResolverTest.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import org.junit.jupiter.api.Test;
99
import org.junit.jupiter.api.io.TempDir;
1010
import org.junit.jupiter.params.ParameterizedTest;
11-
import org.junit.jupiter.params.provider.CsvSource;
1211
import org.junit.jupiter.params.provider.ValueSource;
1312
import org.mockito.Mockito;
1413

@@ -116,6 +115,22 @@ public void testResolveConflictingFileByChoosingNewLengthLimitedName(@TempDir Pa
116115
Assertions.assertFalse(Files.exists(unresolved.ciphertextPath));
117116
}
118117

118+
@Test
119+
public void testResolveConflictFailedAlternativeNamesReserved(@TempDir Path dir) throws IOException {
120+
Files.createFile(dir.resolve("foo (Created by Alice on 2024-01-31).c9r"));
121+
Files.createFile(dir.resolve("foo.c9r"));
122+
Files.createFile(dir.resolve("baz.c9r"));
123+
Mockito.when(fileNameCryptor.encryptFilename(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn("baz");
124+
Node unresolved = new Node(dir.resolve("foo (Created by Alice on 2024-01-31).c9r"));
125+
unresolved.cleartextName = "this is a rather long file name.txt";
126+
unresolved.extractedCiphertext = "foo";
127+
128+
Stream<Node> result = conflictResolver.process(unresolved);
129+
Assertions.assertTrue(result.findAny().isEmpty());
130+
Assertions.assertTrue(Files.exists(unresolved.ciphertextPath));
131+
Mockito.verify(fileNameCryptor, Mockito.times(10)).encryptFilename(Mockito.any(), Mockito.any(), Mockito.any());
132+
}
133+
119134
@Test
120135
public void testResolveConflictingFileTrivially(@TempDir Path dir) throws IOException {
121136
Files.createFile(dir.resolve("foo (1).c9r"));

0 commit comments

Comments
 (0)