From b1fa4de3888102b7b756cebfb8d352c567285acc Mon Sep 17 00:00:00 2001 From: Vincent Guillebaud Date: Sun, 6 Oct 2024 15:29:58 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20URISyntaxException:=20Ille?= =?UTF-8?q?gal=20character=20in=20path=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/platform/xdg/XdgFilePickerPortal.kt | 33 ++++++++++++++++--- .../filekit/core/platform/xdg/URITest.kt | 32 +++++++++--------- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/filekit-core/src/jvmMain/kotlin/io/github/vinceglb/filekit/core/platform/xdg/XdgFilePickerPortal.kt b/filekit-core/src/jvmMain/kotlin/io/github/vinceglb/filekit/core/platform/xdg/XdgFilePickerPortal.kt index 2fb589c..e36e267 100644 --- a/filekit-core/src/jvmMain/kotlin/io/github/vinceglb/filekit/core/platform/xdg/XdgFilePickerPortal.kt +++ b/filekit-core/src/jvmMain/kotlin/io/github/vinceglb/filekit/core/platform/xdg/XdgFilePickerPortal.kt @@ -23,6 +23,7 @@ import java.awt.Window import java.io.File import java.net.URI import java.net.URLEncoder +import java.nio.charset.StandardCharsets import java.util.UUID //https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.FileChooser.html @@ -179,7 +180,7 @@ internal class XdgFilePickerPortal : PlatformFilePicker { if (response.toInt() == 0) { val uris = (results["uris"]!!.value as List).map { path -> - path.URI() + path.toURI() } onComplete(uris, this) } else { @@ -227,7 +228,29 @@ internal class Pair( @field:Position(1) val b: B ) : Tuple() -private fun String.URI(): URI = URLEncoder - .encode(this, "UTF-8") - .replace("+", "%20") - .let { URI(it) } +private fun splitUrl(url: String): kotlin.Pair { + val schemeEndIndex = url.indexOf("://") + + return if (schemeEndIndex != -1) { + // If "://" is found, split the string into scheme and rest + val scheme = url.substring(0, schemeEndIndex + 3) + val rest = url.substring(schemeEndIndex + 3) + kotlin.Pair(scheme, rest) + } else { + // If no scheme is found, return null for scheme and the entire string as the rest + kotlin.Pair(null, url) + } +} + +internal fun String.toURI(): URI { + // Split the URL into scheme and the rest of the path + val (_, rest) = splitUrl(this) + + // Encode the rest of the path + val encodedRest = URLEncoder + .encode(rest, StandardCharsets.UTF_8.toString()) + .replace("+", "%20") // URLEncoder encodes spaces as '+', so replace with %20 + + // Reconstruct the toURI with the encoded path + return URI(encodedRest) +} diff --git a/filekit-core/src/jvmTest/kotlin/io/github/vinceglb/filekit/core/platform/xdg/URITest.kt b/filekit-core/src/jvmTest/kotlin/io/github/vinceglb/filekit/core/platform/xdg/URITest.kt index 3e493b4..281314c 100644 --- a/filekit-core/src/jvmTest/kotlin/io/github/vinceglb/filekit/core/platform/xdg/URITest.kt +++ b/filekit-core/src/jvmTest/kotlin/io/github/vinceglb/filekit/core/platform/xdg/URITest.kt @@ -1,34 +1,34 @@ package io.github.vinceglb.filekit.core.platform.xdg -import java.net.URI -import java.net.URLEncoder import kotlin.test.Test import kotlin.test.assertEquals class URITest { - private fun String.URI(): URI = URLEncoder - .encode(this, "UTF-8") - .replace("+", "%20") - .let { URI(it) } - @Test fun testSimpleURI() { - val path = "/home/user/file.txt" - val uri = path.URI() - assertEquals(path, uri.path) + val path = "image:///home/user/file.txt" + val uri = path.toURI() + assertEquals("/home/user/file.txt", uri.path) } @Test fun testURIWithSpaces() { - val path = "/home/user/file with spaces.txt" - val uri = path.URI() - assertEquals(path, uri.path) + val path = "file:///home/user/file with spaces.txt" + val uri = path.toURI() + assertEquals("/home/user/file with spaces.txt", uri.path) } @Test fun testURIWithSpecialCharacters() { - val path = "/home/user/Ubuntu [24.04].file" - val uri = path.URI() - assertEquals(path, uri.path) + val path = "file:///home/user/Ubuntu [24.04].file" + val uri = path.toURI() + assertEquals("/home/user/Ubuntu [24.04].file", uri.path) + } + + @Test + fun testURIWithoutScheme() { + val path = "/home/user/file.txt" + val uri = path.toURI() + assertEquals("/home/user/file.txt", uri.path) } }