From fb3fe489ef21d4213b812df1f3b36606d3a3f106 Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Mon, 30 Nov 2020 16:55:27 -0500 Subject: [PATCH] Closes #9073 remove unwanted dots in the file name --- .../browser/engine/gecko/GeckoEngineSession.kt | 3 ++- .../browser/engine/gecko/GeckoEngineSession.kt | 3 ++- .../browser/engine/gecko/GeckoEngineSession.kt | 3 ++- .../feature/downloads/ext/DownloadState.kt | 12 +++++++----- .../mozilla/components/support/ktx/kotlin/String.kt | 8 +++++++- .../components/support/ktx/kotlin/StringTest.kt | 12 +++++++++++- docs/changelog.md | 1 + 7 files changed, 32 insertions(+), 10 deletions(-) diff --git a/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt b/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt index bbe437d381c..e150bb53a68 100644 --- a/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +++ b/components/browser/engine-gecko-beta/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt @@ -44,6 +44,7 @@ import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isExtensionUrl import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone +import mozilla.components.support.ktx.kotlin.sanitizeFileName import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import mozilla.components.support.utils.DownloadUtils import org.json.JSONObject @@ -811,7 +812,7 @@ class GeckoEngineSession( url = url, contentLength = contentLength, contentType = contentType, - fileName = fileName, + fileName = fileName.sanitizeFileName(), response = response, isPrivate = privateMode ) diff --git a/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt b/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt index bbe437d381c..e150bb53a68 100644 --- a/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +++ b/components/browser/engine-gecko-nightly/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt @@ -44,6 +44,7 @@ import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isExtensionUrl import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone +import mozilla.components.support.ktx.kotlin.sanitizeFileName import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import mozilla.components.support.utils.DownloadUtils import org.json.JSONObject @@ -811,7 +812,7 @@ class GeckoEngineSession( url = url, contentLength = contentLength, contentType = contentType, - fileName = fileName, + fileName = fileName.sanitizeFileName(), response = response, isPrivate = privateMode ) diff --git a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt index 1dad644ab6a..4a7649b8965 100644 --- a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt +++ b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt @@ -44,6 +44,7 @@ import mozilla.components.support.ktx.kotlin.isEmail import mozilla.components.support.ktx.kotlin.isExtensionUrl import mozilla.components.support.ktx.kotlin.isGeoLocation import mozilla.components.support.ktx.kotlin.isPhone +import mozilla.components.support.ktx.kotlin.sanitizeFileName import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import mozilla.components.support.utils.DownloadUtils import org.json.JSONObject @@ -804,7 +805,7 @@ class GeckoEngineSession( url = url, contentLength = contentLength, contentType = contentType, - fileName = fileName, + fileName = fileName.sanitizeFileName(), response = response, isPrivate = privateMode ) diff --git a/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/ext/DownloadState.kt b/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/ext/DownloadState.kt index 53cff70a32b..f65796d04cb 100644 --- a/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/ext/DownloadState.kt +++ b/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/ext/DownloadState.kt @@ -10,6 +10,7 @@ import mozilla.components.concept.fetch.Headers import mozilla.components.concept.fetch.Headers.Names.CONTENT_DISPOSITION import mozilla.components.concept.fetch.Headers.Names.CONTENT_LENGTH import mozilla.components.concept.fetch.Headers.Names.CONTENT_TYPE +import mozilla.components.support.ktx.kotlin.sanitizeFileName import mozilla.components.support.utils.DownloadUtils import java.io.InputStream import java.net.URLConnection @@ -35,12 +36,13 @@ internal fun DownloadState.withResponse(headers: Headers, stream: InputStream?): contentType = headers[CONTENT_TYPE] } + val newFileName = if (fileName.isNullOrBlank()) { + DownloadUtils.guessFileName(contentDisposition, destinationDirectory, url, contentType) + } else { + fileName + } return copy( - fileName = if (fileName.isNullOrBlank()) { - DownloadUtils.guessFileName(contentDisposition, destinationDirectory, url, contentType) - } else { - fileName - }, + fileName = newFileName?.sanitizeFileName(), contentType = contentType, contentLength = contentLength ?: headers[CONTENT_LENGTH]?.toLongOrNull() ) diff --git a/components/support/ktx/src/main/java/mozilla/components/support/ktx/kotlin/String.kt b/components/support/ktx/src/main/java/mozilla/components/support/ktx/kotlin/String.kt index ca9e36fef72..2b50cd03365 100644 --- a/components/support/ktx/src/main/java/mozilla/components/support/ktx/kotlin/String.kt +++ b/components/support/ktx/src/main/java/mozilla/components/support/ktx/kotlin/String.kt @@ -146,7 +146,13 @@ fun String.sanitizeURL(): String { * For example for an input of "/../../../../../../directory/file.txt" you will get "file.txt" */ fun String.sanitizeFileName(): String { - return this.substringAfterLast(File.separatorChar) + val file = File(this.substringAfterLast(File.separatorChar)) + // Remove unwanted subsequent dots in the file name. + return if (file.extension.trim().isNotEmpty()) { + file.name.replace("\\.\\.+".toRegex(), ".") + } else { + file.name.replace("\\.\\.?+".toRegex(), "") + }.removePrefix(".") } /** diff --git a/components/support/ktx/src/test/java/mozilla/components/support/ktx/kotlin/StringTest.kt b/components/support/ktx/src/test/java/mozilla/components/support/ktx/kotlin/StringTest.kt index 198d447d037..8b47cd3c56a 100644 --- a/components/support/ktx/src/test/java/mozilla/components/support/ktx/kotlin/StringTest.kt +++ b/components/support/ktx/src/test/java/mozilla/components/support/ktx/kotlin/StringTest.kt @@ -172,7 +172,7 @@ class StringTest { @Test fun sanitizeFileName() { - var file = "/../../../../../../../../../../directory/file.txt" + var file = "/../../../../../../../../../../directory/file.......txt" val fileName = "file.txt" assertEquals(fileName, file.sanitizeFileName()) @@ -180,5 +180,15 @@ class StringTest { file = "/root/directory/file.txt" assertEquals(fileName, file.sanitizeFileName()) + + assertEquals("file", "file".sanitizeFileName()) + + assertEquals("file", "file..".sanitizeFileName()) + + assertEquals("file", "file.".sanitizeFileName()) + + assertEquals("file", ".file".sanitizeFileName()) + + assertEquals("test.2020.12.01.txt", "test.2020.12.01.txt".sanitizeFileName()) } } diff --git a/docs/changelog.md b/docs/changelog.md index f7fe4c59cec..bd108f1741c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -17,6 +17,7 @@ permalink: /changelog/ * **feature-downloads** * 🚒 Bug fixed [issue #9033](https://github.com/mozilla-mobile/android-components/issues/9033) - Fix resuming downloads in slow networks more details see the [Fenix issue](https://github.com/mozilla-mobile/fenix/issues/9354#issuecomment-731267368). + * 🚒 Bug fixed [issue #9073](https://github.com/mozilla-mobile/android-components/issues/9073) - Fix crash downloading a file with multiple dots on it, for more details see the [Fenix issue](https://github.com/mozilla-mobile/fenix/issues/16443). * **feature-app-links** * Added handling of PackageItemInfo.packageName NullPointerException on some Xiaomi and TCL devices