Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream
import java.net.URLDecoder
import java.nio.charset.StandardCharsets
import java.util.UUID
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
Expand Down Expand Up @@ -115,7 +117,7 @@ object AESCrypto {

return if (mode == "decrypt") {
// Overwrite the input file with the decrypted file
val targetPath = if (inputFile.startsWith("file://")) inputFile.substring(7) else inputFile
val targetPath = normalizeFilePath(inputFile)
FileInputStream(outputFileObj).use { inputStream ->
FileOutputStream(targetPath).use { fos ->
Comment thread
Rohit3523 marked this conversation as resolved.
Resolved
val buffer = ByteArray(BUFFER_SIZE)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
Expand Down Expand Up @@ -194,10 +196,33 @@ object AESCrypto {
val uri = Uri.parse(filePath)

return if (uri.scheme == null || uri.scheme == "file") {
FileInputStream(uri.path ?: filePath)
// Use the decoded path for FileInputStream
val normalizedPath = normalizeFilePath(filePath)
FileInputStream(normalizedPath)
} else {
reactContext.contentResolver.openInputStream(uri)
?: throw IllegalArgumentException("Cannot open input stream for URI: $uri")
}
}

/**
* Normalize file path by removing file:// prefix and decoding URL-encoded characters
* (e.g., %20 for spaces, %D0%9D for Cyrillic chars)
*/
private fun normalizeFilePath(filePath: String): String {
var path = filePath

// Remove file:// prefix if present
if (path.startsWith("file://")) {
path = path.substring(7)
}

// Decode URL-encoded characters
return try {
URLDecoder.decode(path, StandardCharsets.UTF_8.toString())
} catch (e: Exception) {
Comment thread
Rohit3523 marked this conversation as resolved.
Resolved
Comment thread
Rohit3523 marked this conversation as resolved.
Resolved
// If decoding fails, return the original path
path
}
}
}
32 changes: 21 additions & 11 deletions ios/algorithms/AESCrypto.m
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ + (nullable NSString *)processFile:(NSString *)filePath operation:(CCOperation)o
NSData *keyData = [CryptoUtils decodeBase64:keyBase64];
NSData *ivData = [CryptoUtils decodeBase64:base64Iv];

NSString *normalizedFilePath = [filePath stringByReplacingOccurrencesOfString:@"file://" withString:@""];
NSString *path = [filePath stringByReplacingOccurrencesOfString:@"file://" withString:@""];
Comment thread
Rohit3523 marked this conversation as resolved.
Resolved
NSString *normalizedFilePath = [path stringByRemovingPercentEncoding] ?: path;
NSString *outputFileName = [@"processed_" stringByAppendingString:[normalizedFilePath lastPathComponent]];
NSString *outputFilePath = [[normalizedFilePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:outputFileName];

Expand Down Expand Up @@ -149,20 +150,29 @@ + (nullable NSString *)processFile:(NSString *)filePath operation:(CCOperation)o
[outputStream close];

if (status == kCCSuccess) {
NSURL *originalFileURL = [NSURL fileURLWithPath:normalizedFilePath];
NSURL *outputFileURL = [NSURL fileURLWithPath:outputFilePath];
// For decrypt: return the temp file with sanitized name (to avoid issues with non-ASCII filenames)
NSString *originalName = [normalizedFilePath lastPathComponent];
NSString *sanitizedName = [originalName stringByReplacingOccurrencesOfString:@"[^a-zA-Z0-9._-]"
withString:@"_"
options:NSRegularExpressionSearch
range:NSMakeRange(0, originalName.length)];

// Create final file in cache directory with sanitized name
NSString *cachePath = NSTemporaryDirectory();
NSString *finalPath = [cachePath stringByAppendingPathComponent:[NSString stringWithFormat:@"decrypted_%@", sanitizedName]];
Comment thread
Rohit3523 marked this conversation as resolved.
Resolved

Comment thread
Rohit3523 marked this conversation as resolved.
Resolved
NSError *error = nil;
[[NSFileManager defaultManager] replaceItemAtURL:originalFileURL
withItemAtURL:outputFileURL
backupItemName:nil
options:NSFileManagerItemReplacementUsingNewMetadataOnly
resultingItemURL:nil
error:&error];
[[NSFileManager defaultManager] removeItemAtPath:finalPath error:nil]; // Remove if exists
[[NSFileManager defaultManager] copyItemAtPath:outputFilePath toPath:finalPath error:&error];
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];

if (error) {
NSLog(@"Failed to replace original file: %@", error);
NSLog(@"Failed to copy decrypted file: %@", error);
return nil;
}
return [NSString stringWithFormat:@"file://%@", normalizedFilePath];

NSLog(@"AESCrypto: Decrypted to temp file: %@", finalPath);
return [NSString stringWithFormat:@"file://%@", finalPath];
Comment thread
Rohit3523 marked this conversation as resolved.
Resolved
} else {
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
return nil;
Expand Down
11 changes: 8 additions & 3 deletions ios/algorithms/FileUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,15 @@ + (BOOL)verifyFileIntegrity:(NSString *)filePath expectedChecksum:(NSString *)ex
}

+ (NSString *)normalizeFilePath:(NSString *)filePath {
if ([filePath hasPrefix:@"file://"]) {
return [filePath substringFromIndex:7];
NSString *path = filePath;

if ([path hasPrefix:@"file://"]) {
path = [path substringFromIndex:7];
}
return filePath;

// Decode URL-encoded characters (e.g., %20 for spaces, %D0%9D for Cyrillic chars)
NSString *decodedPath = [path stringByRemovingPercentEncoding];
return decodedPath ?: path;
Comment thread
Rohit3523 marked this conversation as resolved.
Resolved
}

@end
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rocket.chat/mobile-crypto",
"version": "0.2.1",
"version": "0.2.2",
"description": "Rocket.Chat Mobile Crypto",
"main": "./lib/module/index.js",
"module": "./lib/module/index.js",
Expand Down
Loading