Skip to content

fix: decode URL-encoded characters in E2E file paths#13

Merged
Rohit3523 merged 11 commits intomainfrom
file-name-url-encoding
Mar 19, 2026
Merged

fix: decode URL-encoded characters in E2E file paths#13
Rohit3523 merged 11 commits intomainfrom
file-name-url-encoding

Conversation

@Rohit3523
Copy link
Contributor

@Rohit3523 Rohit3523 commented Mar 16, 2026

Issue

When decrypting E2E (end-to-end encrypted) files, file names containing non-ASCII characters (spaces, Cyrillic, etc.) would display URL-encoded literals instead of the actual characters.

Example:

  • Expected: Наименование.txt
  • Actual: Наименование.txt (or %D0%9D%D0%B0...)

http://rocketchat.atlassian.net/browse/SUP-1007

Root Cause

File URIs (file://) from the Android/iOS file system contain URL-encoded paths (e.g., %20 for spaces, %D0%9D for Cyrillic). The native decryption code was not decoding these paths before using them, resulting in the encoded literals appearing in file names.

Summary by CodeRabbit

  • New Features

    • AES encryption/decryption for base64 strings and files, including GCM and CTR modes.
  • Bug Fixes

    • Safer cross-platform file handling: normalized and URL-decoded paths, input existence and stream checks, write validation, support for non-file URIs, and atomic replacement on successful decrypts.
  • Chores

    • Version bumped to 0.2.2.

@Rohit3523 Rohit3523 marked this pull request as ready for review March 17, 2026 13:37
@Rohit3523 Rohit3523 requested a review from diegolmello March 17, 2026 13:44
@diegolmello diegolmello requested a review from Copilot March 17, 2026 13:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to fix incorrect display/handling of non-ASCII E2E file names by decoding URL-encoded characters in file:// paths coming from mobile file systems.

Changes:

  • Bump package version to 0.2.2.
  • iOS: decode percent-encoded characters when normalizing file paths in FileUtils.
  • iOS/Android: add percent-decoding in AES file processing paths (with additional iOS behavior changes around output naming/return value).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
package.json Version bump to ship the fix.
ios/algorithms/FileUtils.m Normalize file:// URIs by stripping scheme and decoding percent-encoding.
ios/algorithms/AESCrypto.m Decode percent-encoding for AES file processing; adds temp-file + sanitized-name handling.
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt Normalize file paths for file I/O by stripping file:// and decoding percent-encoding.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Rohit3523 Rohit3523 force-pushed the file-name-url-encoding branch 3 times, most recently from a29a13e to eaed78f Compare March 17, 2026 16:25
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes URL-encoded filenames showing up during E2E file decrypt/encrypt flows by normalizing file URIs/paths before they’re used by native file I/O.

Changes:

  • Bump package version to 0.2.2.
  • iOS: decode percent-encoded characters in FileUtils.normalizeFilePath and improve file processing path handling in AESCrypto.
  • Android: normalize file:// paths for decrypt overwrite and file input stream creation by decoding URL-encoded characters.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
package.json Version bump for the release containing the path-decoding fix.
ios/algorithms/FileUtils.m normalizeFilePath now percent-decodes URL-encoded characters after stripping file://.
ios/algorithms/AESCrypto.m Updates file-path normalization and adds additional stream/file handling around AES-CTR file processing.
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt Introduces a normalizeFilePath helper and uses it in decrypt overwrite + file stream creation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 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
  • 🔍 Trigger review

Walkthrough

Normalize file paths (strip file://, URL-decode) on Android and iOS; Android I/O now uses parsed URIs and content resolver for non-file URIs. Add AES encrypt/decrypt base64 and file APIs on iOS and harden processFile with validation, write verification, cryptor error handling, and atomic replace on decrypt; bump package version.

Changes

Cohort / File(s) Summary
Android Path & I/O
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt
Added normalizeFilePath(filePath) to strip file:// and URL-decode. getInputStream and decrypt-overwrite use normalized paths. Decrypt output selection now uses Uri.parse(...) to choose FileOutputStream for file URIs or content resolver for others.
iOS AES File Operations
ios/algorithms/AESCrypto.m
Added new public APIs for AES (base64/GCM and file): encryptBase64, decryptBase64, encryptGcmBase64, decryptGcmBase64, encryptFile, decryptFile. Rewrote processFile:operation:base64UrlKey:base64Iv: to normalize paths, validate input/existence/streams, verify per-write bytes, manage cryptor lifecycle/errors, use loop success gating, atomically replace original file on decrypt, and return file:// URLs on success.
iOS File Utilities
ios/algorithms/FileUtils.m
normalizeFilePath updated to remove file:// prefix and apply URL-decoding (stringByRemovingPercentEncoding), returning decoded path when available.
Version Update
package.json
Bumped package version from 0.2.1 to 0.2.2.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant FileUtils
    participant AESCrypto
    participant FileSystem
    participant Cryptor

    Caller->>AESCrypto: encryptFile/decryptFile(filePath, base64Key, base64Iv)
    AESCrypto->>FileUtils: normalizeFilePath(filePath)
    FileUtils-->>AESCrypto: decodedPath
    AESCrypto->>FileSystem: check exists(decodedPath)
    FileSystem-->>AESCrypto: exists / error
    AESCrypto->>FileSystem: open inputStream(decodedPath), create temp output
    FileSystem-->>AESCrypto: input/output handles
    AESCrypto->>Cryptor: create/init cryptor(key, iv, operation)
    Cryptor-->>AESCrypto: cryptor handle / error
    loop read-chunks
      AESCrypto->>FileSystem: read chunk
      FileSystem-->>AESCrypto: chunk bytes
      AESCrypto->>Cryptor: update(chunk)
      Cryptor-->>AESCrypto: processed bytes
      AESCrypto->>FileSystem: write bytes to output
      FileSystem-->>AESCrypto: bytesWritten
      AESCrypto-->>AESCrypto: verify bytesWritten == bytesOutMoved
    end
    AESCrypto->>Cryptor: finalize
    Cryptor-->>AESCrypto: final bytes / status
    alt success
      AESCrypto->>FileSystem: if decrypt -> atomically replace original with output
      FileSystem-->>Caller: return file://URL
    else failure
      AESCrypto->>FileSystem: remove temp output
      FileSystem-->>Caller: return null
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: decoding URL-encoded characters in E2E file paths across Android and iOS implementations.
Linked Issues check ✅ Passed The PR implements URL-decoding for file paths in both Android and iOS crypto implementations, directly addressing SUP-1007's requirement to handle Cyrillic and non-ASCII filenames by decoding file:// URIs before use.
Out of Scope Changes check ✅ Passed All changes are scoped to URL-decoding file paths and related error handling improvements in crypto algorithms. The version bump is a standard accompanying change. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can generate a title for your PR based on the changes with custom instructions.

Set the reviews.auto_title_instructions setting to generate a title for your PR based on the changes in the PR with custom instructions.

Copy link

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt`:
- Around line 210-224: The normalizeFilePath function is decoding every path
which corrupts plain filesystem filenames containing '%' characters; change it
to only decode when the input is a file:// URI. Specifically, in
normalizeFilePath(filePath: String) keep the existing removal of the "file://"
prefix and then call Uri.decode(...) only in that branch (or check
Uri.parse(filePath).scheme == "file"), otherwise return the original path
unchanged; ensure the catch block still returns the original path on decode
errors.

In `@ios/algorithms/AESCrypto.m`:
- Around line 90-97: The current normalization uses [NSURL
URLWithString:filePath] which treats '#' and '?' as URL syntax and truncates
filenames (variables: filePath, fileURL, normalizedFilePath); replace that block
to parse paths as file paths (use [NSURL fileURLWithPath:] or mirror the logic
from FileUtils.m that strips "file://" and decodes percent escapes) so filenames
containing '#' or '?' are preserved; update the import if needed to reuse
FileUtils helpers, and add a quick test/verification for filenames like
"report#1.pdf" and "file?name.txt" to confirm existence checks succeed before
merging.

In `@ios/algorithms/FileUtils.m`:
- Around line 223-231: The normalizeFilePath: helper currently percent-decodes
every input which corrupts paths containing literal '%' (e.g., "budget%20.pdf");
change normalizeFilePath: so it only calls stringByRemovingPercentEncoding when
the input begins with the "file://" scheme: detect and strip the "file://"
prefix from path (as currently done), then call stringByRemovingPercentEncoding
on that stripped path and return the decoded result; for inputs that do not
start with "file://", return the original path unchanged (no percent-decoding)
to preserve literal '%' characters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7f35a958-1971-4429-a304-9711659480a3

📥 Commits

Reviewing files that changed from the base of the PR and between b75e261 and 98d987b.

📒 Files selected for processing (4)
  • android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt
  • ios/algorithms/AESCrypto.m
  • ios/algorithms/FileUtils.m
  • package.json
📜 Review details
🧰 Additional context used
🪛 detekt (1.23.8)
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt

[warning] 221-221: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

🔇 Additional comments (1)
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt (1)

116-130: Verify the decrypt result is no longer leaking the encoded URI.

Line 130 still returns inputFile unchanged, and android/src/main/java/chat/rocket/mobilecrypto/MobileCryptoModule.kt:113-129 resolves that exact string back to JS. If the caller derives the visible filename from the returned path, %20 / %D0%9D will still survive even though the bytes were written to targetPath.

💡 Possible adjustment
-            outputFileObj.delete()
-            inputFile
+            outputFileObj.delete()
+            "file://$targetPath"

@Rohit3523
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt`:
- Around line 118-121: The decrypt path currently assumes file system paths by
calling FileOutputStream(targetPath) which breaks for content:// URIs; update
the write-back logic in AESCrypto (around normalizeFilePath, targetPath, and the
decrypt routine that currently uses FileOutputStream(targetPath)) to detect when
targetPath is a content URI and, in that case, open an OutputStream via the
Android ContentResolver (e.g.,
context.contentResolver.openOutputStream(Uri.parse(targetPath))) and copy bytes
from the decryption InputStream into that OutputStream; keep the existing
FileOutputStream(File(targetPath)) behavior for regular file paths so both
file:// and content:// outputs are supported.

In `@ios/algorithms/AESCrypto.m`:
- Around line 113-118: The code currently returns early after opening
outputStream or failing cryptor initialization and leaves the truncated
destination file and temp artifacts behind; update the failure branches that
check [inputStream streamStatus] and [outputStream streamStatus] and the cryptor
init error path (where CCCryptorRef is created) to perform cleanup: close
inputStream and outputStream, and delete the destination/processed file(s)
(e.g., processedFilePath / processedFileURL or whatever processed_* variables
are used) using NSFileManager before returning, ensuring the same cleanup logic
that exists at the later cleanup point (the code around the existing cleanup at
line 172) is applied in these early-return paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c424573-f937-4627-a801-23446b3a3d85

📥 Commits

Reviewing files that changed from the base of the PR and between 98d987b and 01f5e40.

📒 Files selected for processing (3)
  • android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt
  • ios/algorithms/AESCrypto.m
  • ios/algorithms/FileUtils.m
🚧 Files skipped from review as they are similar to previous changes (1)
  • ios/algorithms/FileUtils.m
📜 Review details
🧰 Additional context used
🪛 detekt (1.23.8)
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt

[warning] 218-218: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

🔇 Additional comments (5)
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt (2)

197-199: Nice fix: local/file input now uses normalized path before opening stream.

This is a good change for %-encoded filenames in file:// paths.


210-224: Path normalization behavior is now scoped correctly.

Decoding only in the file:// branch avoids altering plain filesystem names that legitimately contain %.

ios/algorithms/AESCrypto.m (3)

3-3: Nice reuse of centralized path normalization.

Pulling FileUtils normalizeFilePath: into processFile keeps the existence and stream setup checks pointed at the decoded filesystem path instead of the URI form.

Also applies to: 91-107


131-153: Good fail-closed handling in the streaming loop.

Checking bytesWritten against dataOutMoved is a solid guard against silent truncation on the hot path.


157-195: The temp-file cleanup and atomic replace flow looks solid.

Cleaning the temp output on failure and only swapping it into place after a full decrypt completes avoids in-place corruption of the source file.

Copy link

@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)
ios/algorithms/AESCrypto.m (2)

173-191: Consider reusing the existing fileManager instance.

A fileManager variable is already defined at line 94, but lines 174, 183, and 191 create new instances via [NSFileManager defaultManager]. While defaultManager returns a singleton and this is functionally correct, reusing the local variable improves consistency.

♻️ Proposed fix
     if (status != kCCSuccess || !loopSuccess) {
-        [[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
+        [fileManager removeItemAtPath:outputFilePath error:nil];
         return nil;
     }
 
     if (operation == kCCDecrypt) {
         // For decrypt: atomically replace the original file with decrypted content
         NSURL *originalFileURL = [NSURL fileURLWithPath:normalizedFilePath];
         NSURL *outputFileURL = [NSURL fileURLWithPath:outputFilePath];
         NSError *error = nil;
-        NSURL *replacedURL = [[NSFileManager defaultManager] replaceItemAtURL:originalFileURL
+        NSURL *replacedURL = [fileManager replaceItemAtURL:originalFileURL
                                              withItemAtURL:outputFileURL
                                             backupItemName:nil
                                                    options:NSFileManagerItemReplacementUsingNewMetadataOnly
                                           resultingItemURL:nil
                                                      error:&error];
         if (!replacedURL) {
             NSLog(@"Failed to replace original file: %@", error);
-            [[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
+            [fileManager removeItemAtPath:outputFilePath error:nil];
             return nil;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ios/algorithms/AESCrypto.m` around lines 173 - 191, Replace the inline uses
of [NSFileManager defaultManager] with the existing local fileManager variable
to improve consistency: in the conditional after the status check (around the
block that removes the temp file and the decrypt replacement logic), use
fileManager for removeItemAtPath: and for replaceItemAtURL:withItemAtURL:...
instead of calling [NSFileManager defaultManager] so the calls around
normalizedFilePath, outputFilePath and the replaceItemAtURL invocation all reuse
the same fileManager instance.

162-163: Consider verifying the final write for consistency.

The write at line 163 doesn't verify bytesWritten against finalBytesOut, unlike the check at lines 142-146. While finalBytesOut is typically 0 for CTR mode (no padding), verifying the write would maintain consistent error handling.

♻️ Proposed fix
         if (status == kCCSuccess && finalBytesOut > 0) {
-            [outputStream write:buffer maxLength:finalBytesOut];
+            NSInteger finalWritten = [outputStream write:buffer maxLength:finalBytesOut];
+            if (finalWritten != (NSInteger)finalBytesOut) {
+                loopSuccess = NO;
+            }
         } else if (status != kCCSuccess) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ios/algorithms/AESCrypto.m` around lines 162 - 163, The final write in
AESCrypto.m (inside the method performing encryption/decryption where it checks
status == kCCSuccess && finalBytesOut > 0) should verify the return value of
[outputStream write:buffer maxLength:finalBytesOut] just like the earlier write
check; capture the bytesWritten, compare it to finalBytesOut, and if they
differ, perform the same error handling/cleanup path (log the failure and
return/propagate error) to ensure consistent error handling for the final write
in methods like the one using CCCryptorFinal/stream writes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@ios/algorithms/AESCrypto.m`:
- Around line 173-191: Replace the inline uses of [NSFileManager defaultManager]
with the existing local fileManager variable to improve consistency: in the
conditional after the status check (around the block that removes the temp file
and the decrypt replacement logic), use fileManager for removeItemAtPath: and
for replaceItemAtURL:withItemAtURL:... instead of calling [NSFileManager
defaultManager] so the calls around normalizedFilePath, outputFilePath and the
replaceItemAtURL invocation all reuse the same fileManager instance.
- Around line 162-163: The final write in AESCrypto.m (inside the method
performing encryption/decryption where it checks status == kCCSuccess &&
finalBytesOut > 0) should verify the return value of [outputStream write:buffer
maxLength:finalBytesOut] just like the earlier write check; capture the
bytesWritten, compare it to finalBytesOut, and if they differ, perform the same
error handling/cleanup path (log the failure and return/propagate error) to
ensure consistent error handling for the final write in methods like the one
using CCCryptorFinal/stream writes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6fab81f3-5822-443b-82d7-1a5ab7b29496

📥 Commits

Reviewing files that changed from the base of the PR and between 01f5e40 and 659cb24.

📒 Files selected for processing (1)
  • ios/algorithms/AESCrypto.m
📜 Review details
🔇 Additional comments (5)
ios/algorithms/AESCrypto.m (5)

3-3: LGTM!

The FileUtils.h import is correctly added to support the path normalization at line 91.


52-58: LGTM!

The encryptFile and decryptFile wrappers correctly delegate to processFile with the appropriate CCOperation type, matching the header declarations.


91-97: LGTM! Path normalization issue addressed.

Using [FileUtils normalizeFilePath:] correctly handles URL-encoded characters and the file:// prefix, addressing the previous issue with URLWithString: mishandling special characters like # and ? in filenames.


113-131: LGTM! Stream and cryptor failure cleanup addressed.

The cleanup logic at lines 117 and 129 properly removes the truncated output file on early failures, addressing the previous review concern about orphaned processed_* files.


178-198: LGTM! Atomic file replacement and return path handling.

The decrypt operation correctly uses replaceItemAtURL:withItemAtURL: for atomic replacement, and both operations return properly formatted file:// URLs consistent with the MobileCrypto.mm caller expectations.

Copy link

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt (1)

119-136: ⚠️ Potential issue | 🟡 Minor

Ensure temp file cleanup also happens on decrypt write-back failure.

If copy-back to the target URI/path fails, outputFileObj is not deleted (Line 135 is success-only), leaving cache artifacts behind.

Proposed hardening
         return if (mode == "decrypt") {
             // Overwrite the input file with the decrypted file
             val targetUri = Uri.parse(inputFile)
-            FileInputStream(outputFileObj).use { inputStream ->
-                val outputStream = if (targetUri.scheme == null || targetUri.scheme == "file") {
-                    FileOutputStream(normalizeFilePath(inputFile))
-                } else {
-                    reactContext.contentResolver.openOutputStream(targetUri)
-                        ?: throw IllegalArgumentException("Cannot open output stream for URI: $targetUri")
-                }
-                outputStream.use { fos ->
-                    val buffer = ByteArray(BUFFER_SIZE)
-                    var numBytesRead: Int
-                    
-                    while (inputStream.read(buffer).also { numBytesRead = it } != -1) {
-                        fos.write(buffer, 0, numBytesRead)
-                    }
-                }
-            }
-            outputFileObj.delete()
-            inputFile
+            try {
+                FileInputStream(outputFileObj).use { inputStream ->
+                    val outputStream = if (targetUri.scheme == null || targetUri.scheme == "file") {
+                        FileOutputStream(normalizeFilePath(inputFile))
+                    } else {
+                        reactContext.contentResolver.openOutputStream(targetUri)
+                            ?: throw IllegalArgumentException("Cannot open output stream for URI: $targetUri")
+                    }
+                    outputStream.use { fos ->
+                        val buffer = ByteArray(BUFFER_SIZE)
+                        var numBytesRead: Int
+                        while (inputStream.read(buffer).also { numBytesRead = it } != -1) {
+                            fos.write(buffer, 0, numBytesRead)
+                        }
+                    }
+                }
+                inputFile
+            } finally {
+                outputFileObj.delete()
+            }
         } else {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt`
around lines 119 - 136, The copy-back block that writes from outputFileObj to
the target (using FileInputStream(outputFileObj) and outputStream/fos) can throw
and currently only deletes outputFileObj on the success path; wrap the whole
copy operation in a try/finally (or use Kotlin's runCatching/also) so that
outputFileObj.delete() is executed in the finally block regardless of success,
rethrowing the original exception after cleanup; refer to the variables/output
objects outputFileObj, inputFile, targetUri and the
FileInputStream/FileOutputStream/reactContext.contentResolver.openOutputStream
usage to locate and modify the copy-back section.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt`:
- Around line 119-136: The copy-back block that writes from outputFileObj to the
target (using FileInputStream(outputFileObj) and outputStream/fos) can throw and
currently only deletes outputFileObj on the success path; wrap the whole copy
operation in a try/finally (or use Kotlin's runCatching/also) so that
outputFileObj.delete() is executed in the finally block regardless of success,
rethrowing the original exception after cleanup; refer to the variables/output
objects outputFileObj, inputFile, targetUri and the
FileInputStream/FileOutputStream/reactContext.contentResolver.openOutputStream
usage to locate and modify the copy-back section.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5dc0e814-6d66-467f-9d30-027ee9491452

📥 Commits

Reviewing files that changed from the base of the PR and between 659cb24 and 336bcba.

📒 Files selected for processing (1)
  • android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt
📜 Review details
🧰 Additional context used
🪛 detekt (1.23.8)
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt

[warning] 224-224: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

🔇 Additional comments (1)
android/src/main/java/chat/rocket/mobilecrypto/algorithms/AESCrypto.kt (1)

203-205: Good path-normalization scope and URI handling.

Nice fix: decoding is now limited to file:// paths, and plain filesystem paths are preserved as-is. This directly addresses the encoded-filename issue without breaking literal % filenames.

Also applies to: 216-230

Copy link

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ios/algorithms/AESCrypto.m`:
- Around line 159-164: The final write in the CCCryptorFinal block (inside
function handling the cryptor/CCCryptorFinal call) currently ignores the return
value of [outputStream write:buffer maxLength:finalBytesOut]; update this to
validate the number of bytes written equals finalBytesOut (and detect
negative/error return), mirror the checks used in the main write loop (lines
handling bytesWritten and loopSuccess), and on short write or error set
loopSuccess = NO and set an appropriate non-kCCSuccess status (or return an
error) so the method does not silently succeed when the final write fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fcd1302b-05e7-4cd8-b1c9-8a0c7373a9e3

📥 Commits

Reviewing files that changed from the base of the PR and between 336bcba and 159d5f3.

📒 Files selected for processing (1)
  • ios/algorithms/AESCrypto.m
📜 Review details
🔇 Additional comments (1)
ios/algorithms/AESCrypto.m (1)

91-97: Path normalization + early cleanup changes look correct.

Using FileUtils normalization before file access and deleting outputFilePath on stream-open failure is a solid fix for encoded-path handling and temp-file hygiene.

Also applies to: 113-119

@Rohit3523 Rohit3523 merged commit 57deaff into main Mar 19, 2026
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants