From 231b06f3fd4a3e8dfa35d9a8a14034304ca923a0 Mon Sep 17 00:00:00 2001 From: Mohamad Jaara Date: Fri, 1 Sep 2023 10:56:29 +0200 Subject: [PATCH] fix: normalize asset file name when exporting to external storage (#2161) --- app/src/main/kotlin/com/wire/android/util/FileManager.kt | 2 +- app/src/main/kotlin/com/wire/android/util/FileUtil.kt | 6 ++++-- app/src/main/kotlin/com/wire/android/util/StringUtil.kt | 2 ++ .../test/kotlin/com/wire/android/util/StringUtilTest.kt | 8 ++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/util/FileManager.kt b/app/src/main/kotlin/com/wire/android/util/FileManager.kt index 8198c807f59..3729e402227 100644 --- a/app/src/main/kotlin/com/wire/android/util/FileManager.kt +++ b/app/src/main/kotlin/com/wire/android/util/FileManager.kt @@ -24,9 +24,9 @@ import android.content.Context import android.net.Uri import com.wire.android.appLogger import com.wire.android.ui.home.conversations.model.AssetBundle -import com.wire.kalium.logic.data.asset.AttachmentType import com.wire.android.util.dispatchers.DefaultDispatcherProvider import com.wire.android.util.dispatchers.DispatcherProvider +import com.wire.kalium.logic.data.asset.AttachmentType import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.withContext import okio.Path diff --git a/app/src/main/kotlin/com/wire/android/util/FileUtil.kt b/app/src/main/kotlin/com/wire/android/util/FileUtil.kt index 4102af04b45..cc18cf9d8d2 100644 --- a/app/src/main/kotlin/com/wire/android/util/FileUtil.kt +++ b/app/src/main/kotlin/com/wire/android/util/FileUtil.kt @@ -160,6 +160,8 @@ fun ContentResolver.copyFile(destinationUri: Uri, sourcePath: Path) { } private fun Context.saveFileDataToMediaFolder(assetName: String, downloadedDataPath: Path, fileSize: Long, mimeType: String): Uri? { + val normalizedFileName = assetName.normalizeFileName() + val resolver = contentResolver val directory = Environment.getExternalStoragePublicDirectory( when { @@ -171,7 +173,7 @@ private fun Context.saveFileDataToMediaFolder(assetName: String, downloadedDataP ) directory.mkdirs() val contentValues = ContentValues().apply { - val availableAssetName = findFirstUniqueName(directory, assetName.ifEmpty { ATTACHMENT_FILENAME }) + val availableAssetName = findFirstUniqueName(directory, normalizedFileName.ifEmpty { ATTACHMENT_FILENAME }) put(DISPLAY_NAME, availableAssetName) put(MIME_TYPE, mimeType) put(SIZE, fileSize) @@ -189,7 +191,7 @@ private fun Context.saveFileDataToMediaFolder(assetName: String, downloadedDataP val insertedUri = resolver.insert(externalContentUri, contentValues) ?: run { val authority = getProviderAuthority() // we need to find the next available name with copy counter by ourselves before copying - val availableAssetName = findFirstUniqueName(directory, assetName.ifEmpty { ATTACHMENT_FILENAME }) + val availableAssetName = findFirstUniqueName(directory, normalizedFileName.ifEmpty { ATTACHMENT_FILENAME }) val destinationFile = File(directory, availableAssetName) FileProvider.getUriForFile(this, authority, destinationFile) } diff --git a/app/src/main/kotlin/com/wire/android/util/StringUtil.kt b/app/src/main/kotlin/com/wire/android/util/StringUtil.kt index 5b90b729017..78d9136e3e3 100644 --- a/app/src/main/kotlin/com/wire/android/util/StringUtil.kt +++ b/app/src/main/kotlin/com/wire/android/util/StringUtil.kt @@ -47,3 +47,5 @@ fun String.toTitleCase(delimiter: String = " ", separator: String = " "): String } fun String.capitalizeFirstLetter(): String = lowercase().replaceFirstChar(Char::titlecaseChar) + +fun String.normalizeFileName(): String = this.replace("/", "") diff --git a/app/src/test/kotlin/com/wire/android/util/StringUtilTest.kt b/app/src/test/kotlin/com/wire/android/util/StringUtilTest.kt index 3ea9e977736..e441a3306ad 100644 --- a/app/src/test/kotlin/com/wire/android/util/StringUtilTest.kt +++ b/app/src/test/kotlin/com/wire/android/util/StringUtilTest.kt @@ -36,4 +36,12 @@ class StringUtilTest { val actual = input.toTitleCase() assert(expected == actual) } + + @Test + fun givenString_whenNormalizingAsFileName_thenAllSlashesAreRemoved() { + val input = "this/is/a/test" + val expected = "thisisatest" + val actual = input.normalizeFileName() + assert(expected == actual) + } }