Skip to content

Feature: Block write if file is in use#338

Merged
infeo merged 8 commits intodevelopfrom
feature/prevent-write-on-in-use
Mar 2, 2026
Merged

Feature: Block write if file is in use#338
infeo merged 8 commits intodevelopfrom
feature/prevent-write-on-in-use

Conversation

@infeo
Copy link
Member

@infeo infeo commented Feb 25, 2026

This PR is a follow-up on #312.

In the former PR, opening a file channel was blocked when a file is marked in use. This is extended by preventing (not already cached) writes on a file if the file is suddenly (e.g. sync activity) marked as in use.

Implementation note:

  • many changes are just "passing through data" (the cleartext path)
  • already cached changes (i.e. writes persisted in the chunk cache) will not be prevented

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • ✅ Review completed - (🔄 Check again to review again)

Walkthrough

The PR propagates cleartext CryptoPath through open-file lifecycle and move operations. OpenCryptoFiles gains overloads for getOrCreate, readCiphertextFile, writeCiphertextFile, and prepareMove to accept a CryptoPath; TwoPhaseMove and commit now carry cleartextDst. OpenCryptoFile and OpenCryptoFileModule store a current cleartext-path AtomicReference. CryptoFileSystemImpl and Symlinks call sites were updated. CleartextFileChannel now checks InUseManager before writes, emits FileIsInUse events via an injected Consumer, and constructors across related classes were extended to accept the new dependencies and path references.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • overheadhunter
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main feature: blocking writes when a file is marked as in use, which aligns with the changeset's primary objective.
Description check ✅ Passed The PR description directly relates to the changeset, explaining the feature to block writes on in-use files and noting that many changes pass through cleartext path data.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/prevent-write-on-in-use

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java (1)

73-107: Consider extracting shared logic to reduce duplication.

The writeCiphertextFile and readCiphertextFile method pairs are nearly identical — the only difference is whether they call getOrCreate(CryptoPath, Path) or getOrCreate(Path). The non-CryptoPath versions could delegate to the CryptoPath versions with null:

♻️ Example for writeCiphertextFile
 public void writeCiphertextFile(Path ciphertextPath, EffectiveOpenOptions openOptions, ByteBuffer contents) throws IOException {
-    try (OpenCryptoFile f = getOrCreate(ciphertextPath); FileChannel ch = f.newFileChannel(openOptions)) {
-        ch.write(contents);
-    }
+    writeCiphertextFile(null, ciphertextPath, openOptions, contents);
 }

This is optional since the current approach is clear and the duplication is minimal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java` around lines
73 - 107, The two pairs of methods writeCiphertextFile and readCiphertextFile
duplicate logic; refactor the Path-only overloads to delegate to the CryptoPath
versions by calling getOrCreate with a null CryptoPath (i.e. change
writeCiphertextFile(Path, EffectiveOpenOptions, ByteBuffer) to call
writeCiphertextFile((CryptoPath) null, ciphertextPath, openOptions, contents)
and similarly have readCiphertextFile(Path, EffectiveOpenOptions, int) call
readCiphertextFile((CryptoPath) null, ciphertextPath, openOptions,
maxBufferSize)), preserving exception signatures and behavior of
getOrCreate(CryptoPath, Path), newFileChannel and buffer size checks.
src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java (2)

44-87: Multiple testing constructors add maintenance burden.

There are now 4 constructors (1 production + 3 testing). The two "testing compatibility" constructors (lines 53-59 and 81-87) exist solely to avoid updating older test call sites. Consider cleaning these up once the PR is stable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java` around lines
44 - 87, The class OpenCryptoFile currently has four constructors including two
"testing compatibility" overloads that duplicate logic and increase maintenance;
remove the two older compatibility constructors (the ones whose signatures omit
`@CurrentOpenFileCleartextPath` and simply call the full constructor with new
AtomicReference<>(null)) and keep only the `@Inject` production constructor and a
single package-private testing constructor that accepts
`@CurrentOpenFileCleartextPath` and UseToken; then update test call sites to call
that single testing constructor (or add a small test-only factory method on
OpenCryptoFileComponent) so tests supply the currentCleartextPath explicitly
instead of relying on the deprecated overloads.

223-228: Minor TOCTOU between currentFilePath.get() and the currentCleartextPath update.

updateCurrentCleartextPath reads currentFilePath.get() inside the getAndUpdate lambda, while updateCurrentFilePath can concurrently set it to null. In the worst case, the cleartext path gets updated to a non-null value right after the ciphertext path was nulled. Given that both methods are called from controlled contexts (commit/delete flows), this is unlikely to cause real issues, but it's worth noting.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java` around lines
223 - 228, There’s a TOCTOU between currentFilePath.get() and the
currentCleartextPath update: make the check-and-update atomic by protecting both
updateCurrentCleartextPath and updateCurrentFilePath with the same lock;
introduce a shared mutex (e.g., a private final Object filePathLock) and wrap
the bodies of updateCurrentCleartextPath and updateCurrentFilePath in
synchronized(filePathLock) so the null-check of currentFilePath and the update
of currentCleartextPath happen without concurrent mutation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java`:
- Around line 174-183: The code currently skips emitting FileIsInUseEvent when
currentCleartextPath.get() returns null, causing the FileAlreadyInUseException
to be thrown without any event context; change the logic in writeLocked to
always emit a FileIsInUseEvent before throwing by using
currentCleartextPath.get() if non-null or falling back to the ciphertext path
from currentFilePath.get(), e.g. resolve UseInfo via
inUseManager.getUseInfo(path) and call eventConsumer.accept(new
FileIsInUseEvent(fallbackPath, path, useInfo.owner(), useInfo.lastUpdated(), ()
-> inUseManager.ignoreInUse(path))) so an event is always delivered prior to
throwing FileAlreadyInUseException; keep existing uses of inUseManager, UseInfo,
eventConsumer, FileIsInUseEvent, and ignoreInUse.

---

Nitpick comments:
In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java`:
- Around line 44-87: The class OpenCryptoFile currently has four constructors
including two "testing compatibility" overloads that duplicate logic and
increase maintenance; remove the two older compatibility constructors (the ones
whose signatures omit `@CurrentOpenFileCleartextPath` and simply call the full
constructor with new AtomicReference<>(null)) and keep only the `@Inject`
production constructor and a single package-private testing constructor that
accepts `@CurrentOpenFileCleartextPath` and UseToken; then update test call sites
to call that single testing constructor (or add a small test-only factory method
on OpenCryptoFileComponent) so tests supply the currentCleartextPath explicitly
instead of relying on the deprecated overloads.
- Around line 223-228: There’s a TOCTOU between currentFilePath.get() and the
currentCleartextPath update: make the check-and-update atomic by protecting both
updateCurrentCleartextPath and updateCurrentFilePath with the same lock;
introduce a shared mutex (e.g., a private final Object filePathLock) and wrap
the bodies of updateCurrentCleartextPath and updateCurrentFilePath in
synchronized(filePathLock) so the null-check of currentFilePath and the update
of currentCleartextPath happen without concurrent mutation.

In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java`:
- Around line 73-107: The two pairs of methods writeCiphertextFile and
readCiphertextFile duplicate logic; refactor the Path-only overloads to delegate
to the CryptoPath versions by calling getOrCreate with a null CryptoPath (i.e.
change writeCiphertextFile(Path, EffectiveOpenOptions, ByteBuffer) to call
writeCiphertextFile((CryptoPath) null, ciphertextPath, openOptions, contents)
and similarly have readCiphertextFile(Path, EffectiveOpenOptions, int) call
readCiphertextFile((CryptoPath) null, ciphertextPath, openOptions,
maxBufferSize)), preserving exception signatures and behavior of
getOrCreate(CryptoPath, Path), newFileChannel and buffer size checks.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e2f596 and a5bdae8.

📒 Files selected for processing (8)
  • src/main/java/org/cryptomator/cryptofs/CryptoFileSystemImpl.java
  • src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java
  • src/main/java/org/cryptomator/cryptofs/fh/CurrentOpenFileCleartextPath.java
  • src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java
  • src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFileModule.java
  • src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java
  • src/test/java/org/cryptomator/cryptofs/ch/CleartextFileChannelTest.java
  • src/test/java/org/cryptomator/cryptofs/fh/OpenCryptoFilesTest.java

@infeo infeo changed the title Feature: Feature: Block write if file is in use Feb 25, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java (1)

177-183: ⚠️ Potential issue | 🟡 Minor

Emit an in-use event even when cleartext path is unavailable.

At Line 177-183, the code throws FileAlreadyInUseException without emitting FileIsInUseEvent when currentCleartextPath is null. That can leave listeners/UI without ownership/context metadata for the rejection. Consider emitting the event with a fallback identifier before throwing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java` around
lines 177 - 183, When a file is detected in use inside CleartextFileChannel,
always emit a FileIsInUseEvent before throwing FileAlreadyInUseException: if
cleartextPath (currentCleartextPath) is non-null keep the existing event
payload, otherwise emit the event using a safe fallback identifier (e.g. the
ciphertext path or path.toString()) so listeners still receive owner/lastUpdated
and the ignore callback (inUseManager.ignoreInUse(path)); after emitting the
event via eventConsumer.accept(...) proceed to throw
FileAlreadyInUseException(path).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java`:
- Around line 177-183: When a file is detected in use inside
CleartextFileChannel, always emit a FileIsInUseEvent before throwing
FileAlreadyInUseException: if cleartextPath (currentCleartextPath) is non-null
keep the existing event payload, otherwise emit the event using a safe fallback
identifier (e.g. the ciphertext path or path.toString()) so listeners still
receive owner/lastUpdated and the ignore callback
(inUseManager.ignoreInUse(path)); after emitting the event via
eventConsumer.accept(...) proceed to throw FileAlreadyInUseException(path).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a5bdae8 and 049e8c5.

📒 Files selected for processing (2)
  • src/main/java/org/cryptomator/cryptofs/ch/CleartextFileChannel.java
  • src/test/java/org/cryptomator/cryptofs/CryptoFileSystemImplTest.java

remove OpenCryptoFiles methods without cleartext path parameter
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java (1)

115-119: Make null cleartextDst behavior explicit in TwoPhaseMove.

prepareMove(src, dst) now flows null into commit() via updateCurrentCleartextPath(cleartextDst). Please codify whether null means “clear mapping” or “leave unchanged” to avoid accidental misuse.

Optional hardening if null should mean “leave unchanged”
 public void commit() {
 	if (rolledBack) {
 		throw new IllegalStateException();
 	}
 	if (openCryptoFile != null) {
 		openCryptoFile.updateCurrentFilePath(dst);
-		openCryptoFile.updateCurrentCleartextPath(cleartextDst);
+		if (cleartextDst != null) {
+			openCryptoFile.updateCurrentCleartextPath(cleartextDst);
+		}
 	}
 	openCryptoFiles.remove(src, openCryptoFile);
 	committed = true;
 }

Also applies to: 135-147, 162-169

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java` around lines
115 - 119, Make null handling for cleartextDst explicit: change TwoPhaseMove to
accept Optional<CryptoPath> (or add an explicit enum/flag) and update its
constructor and commit()/updateCurrentCleartextPath(Optional<CryptoPath>) to
handle Optional.empty() vs Optional.of(value) deterministically (either "clear
mapping" or "leave unchanged"); then modify prepareMove(Path src, Path dst) and
other prepareMove overloads that currently pass null to pass Optional.empty() or
Optional.of(cleartextDst) and update callers (including the other prepareMove
usages noted) so behavior is unambiguous and no raw nulls flow into commit().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java`:
- Around line 115-119: Make null handling for cleartextDst explicit: change
TwoPhaseMove to accept Optional<CryptoPath> (or add an explicit enum/flag) and
update its constructor and
commit()/updateCurrentCleartextPath(Optional<CryptoPath>) to handle
Optional.empty() vs Optional.of(value) deterministically (either "clear mapping"
or "leave unchanged"); then modify prepareMove(Path src, Path dst) and other
prepareMove overloads that currently pass null to pass Optional.empty() or
Optional.of(cleartextDst) and update callers (including the other prepareMove
usages noted) so behavior is unambiguous and no raw nulls flow into commit().

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 049e8c5 and 6a8f49b.

📒 Files selected for processing (4)
  • src/main/java/org/cryptomator/cryptofs/Symlinks.java
  • src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFiles.java
  • src/test/java/org/cryptomator/cryptofs/SymlinksTest.java
  • src/test/java/org/cryptomator/cryptofs/fh/OpenCryptoFilesTest.java

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java (1)

206-211: Consider adding a brief doc comment to clarify intent.

The conditional logic is correct but subtly different from updateCurrentFilePath. The method silently ignores updates when currentFilePath is null (file deleted) or when the input is null. A short Javadoc would help maintainers understand the design:

📝 Suggested documentation
+	/**
+	 * Updates the cleartext path if the file is not deleted (i.e., currentFilePath is not null).
+	 * Null input is ignored.
+	 *
+	 * `@param` cleartextPath new cleartext path, or null to skip update
+	 */
 	public void updateCurrentCleartextPath(CryptoPath cleartextPath) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java` around lines
206 - 211, The updateCurrentCleartextPath method in OpenCryptoFile silently
ignores null inputs and any update when currentFilePath is null; add a brief
Javadoc above the updateCurrentCleartextPath(CryptoPath cleartextPath) method
explaining its intent and behavior: that null cleartextPath is ignored, and
updates are only applied if currentFilePath is non-null (to avoid resurrecting
paths for deleted files), matching the subtle difference to
updateCurrentFilePath and making maintainers aware of this design decision.
src/test/java/org/cryptomator/cryptofs/fh/OpenCryptoFileTest.java (1)

263-273: Consider adding unit tests for the new cleartext path methods.

The test testUpdateCurrentPathWithNull verifies useToken.close() but doesn't verify that currentCleartextPath is also set to null (per line 201 in the production code). Additionally, there are no unit tests for the new updateCurrentCleartextPath method and its specific behaviors:

  1. updateCurrentCleartextPath(null) should be a no-op
  2. updateCurrentCleartextPath(path) when file is deleted (currentFilePath is null) should not update
  3. updateCurrentCleartextPath(path) when file exists should update
📝 Suggested test additions
`@Test`
`@DisplayName`("Updating current cleartext path with null does nothing")
public void testUpdateCleartextPathWithNull() {
    var currentPath = mock(Path.class, "current Path");
    var currentPathWrapper = new AtomicReference<>(currentPath);
    var cleartextPath = mock(CryptoPath.class, "cleartext Path");
    var cleartextPathWrapper = new AtomicReference<>(cleartextPath);
    OpenCryptoFile openCryptoFile = new OpenCryptoFile(closeListener, cryptor, headerHolder, chunkIO, currentPathWrapper, fileSize, cleartextPathWrapper, lastModified, openCryptoFileComponent, inUseManager, useToken);

    openCryptoFile.updateCurrentCleartextPath(null);
    
    Assertions.assertSame(cleartextPath, openCryptoFile.getCurrentCleartextPath());
}

`@Test`
`@DisplayName`("Updating current cleartext path when file is deleted does not update")
public void testUpdateCleartextPathWhenDeleted() {
    var currentPathWrapper = new AtomicReference<Path>(null); // deleted
    var cleartextPath = mock(CryptoPath.class, "original cleartext");
    var cleartextPathWrapper = new AtomicReference<>(cleartextPath);
    var newCleartextPath = mock(CryptoPath.class, "new cleartext");
    OpenCryptoFile openCryptoFile = new OpenCryptoFile(closeListener, cryptor, headerHolder, chunkIO, currentPathWrapper, fileSize, cleartextPathWrapper, lastModified, openCryptoFileComponent, inUseManager, useToken);

    openCryptoFile.updateCurrentCleartextPath(newCleartextPath);
    
    Assertions.assertSame(cleartextPath, openCryptoFile.getCurrentCleartextPath());
}

`@Test`
`@DisplayName`("Updating current file path with null also nulls cleartext path")
public void testUpdateCurrentPathWithNullAlsoNullsCleartext() {
    var currentPath = mock(Path.class, "current Path");
    var currentPathWrapper = new AtomicReference<>(currentPath);
    var cleartextPath = mock(CryptoPath.class, "cleartext Path");
    var cleartextPathWrapper = new AtomicReference<>(cleartextPath);
    OpenCryptoFile openCryptoFile = new OpenCryptoFile(closeListener, cryptor, headerHolder, chunkIO, currentPathWrapper, fileSize, cleartextPathWrapper, lastModified, openCryptoFileComponent, inUseManager, useToken);
    doNothing().when(useToken).close();

    openCryptoFile.updateCurrentFilePath(null);
    
    Assertions.assertNull(openCryptoFile.getCurrentCleartextPath());
    verify(useToken).close();
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/test/java/org/cryptomator/cryptofs/fh/OpenCryptoFileTest.java` around
lines 263 - 273, Add unit assertions and new tests to cover the cleartext-path
behavior: in the existing testUpdateCurrentPathWithNull verify that
OpenCryptoFile.getCurrentCleartextPath() is null after calling
updateCurrentFilePath(null); add three tests for updateCurrentCleartextPath: (1)
testUpdateCleartextPathWithNull — construct OpenCryptoFile with non-null
currentCleartextPathWrapper, call updateCurrentCleartextPath(null) and assert
getCurrentCleartextPath() is unchanged; (2) testUpdateCleartextPathWhenDeleted —
construct OpenCryptoFile with currentPathWrapper set to null and a non-null
cleartextPathWrapper, call updateCurrentCleartextPath(newPath) and assert
getCurrentCleartextPath() remains the original; (3)
testUpdateCurrentPathWithNullAlsoNullsCleartext — similar to your suggested test
that calls updateCurrentFilePath(null) and asserts getCurrentCleartextPath() is
null and useToken.close() was invoked. Ensure each test constructs
OpenCryptoFile with the appropriate AtomicReference wrappers and uses
getCurrentCleartextPath(), updateCurrentFilePath(),
updateCurrentCleartextPath(), and verify(useToken).close() as needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java`:
- Around line 206-211: The updateCurrentCleartextPath method in OpenCryptoFile
silently ignores null inputs and any update when currentFilePath is null; add a
brief Javadoc above the updateCurrentCleartextPath(CryptoPath cleartextPath)
method explaining its intent and behavior: that null cleartextPath is ignored,
and updates are only applied if currentFilePath is non-null (to avoid
resurrecting paths for deleted files), matching the subtle difference to
updateCurrentFilePath and making maintainers aware of this design decision.

In `@src/test/java/org/cryptomator/cryptofs/fh/OpenCryptoFileTest.java`:
- Around line 263-273: Add unit assertions and new tests to cover the
cleartext-path behavior: in the existing testUpdateCurrentPathWithNull verify
that OpenCryptoFile.getCurrentCleartextPath() is null after calling
updateCurrentFilePath(null); add three tests for updateCurrentCleartextPath: (1)
testUpdateCleartextPathWithNull — construct OpenCryptoFile with non-null
currentCleartextPathWrapper, call updateCurrentCleartextPath(null) and assert
getCurrentCleartextPath() is unchanged; (2) testUpdateCleartextPathWhenDeleted —
construct OpenCryptoFile with currentPathWrapper set to null and a non-null
cleartextPathWrapper, call updateCurrentCleartextPath(newPath) and assert
getCurrentCleartextPath() remains the original; (3)
testUpdateCurrentPathWithNullAlsoNullsCleartext — similar to your suggested test
that calls updateCurrentFilePath(null) and asserts getCurrentCleartextPath() is
null and useToken.close() was invoked. Ensure each test constructs
OpenCryptoFile with the appropriate AtomicReference wrappers and uses
getCurrentCleartextPath(), updateCurrentFilePath(),
updateCurrentCleartextPath(), and verify(useToken).close() as needed.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a8f49b and 812621e.

📒 Files selected for processing (2)
  • src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java
  • src/test/java/org/cryptomator/cryptofs/fh/OpenCryptoFileTest.java

@infeo infeo self-assigned this Feb 27, 2026
@infeo infeo added this to the 2.10.0 milestone Feb 27, 2026
@infeo infeo merged commit 17c7bde into develop Mar 2, 2026
8 checks passed
@infeo infeo deleted the feature/prevent-write-on-in-use branch March 2, 2026 10:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant