Skip to content

Commit 784bdc5

Browse files
committed
fix filename sanitization and stream writing in desktop downloader implementation
1 parent 44a0da8 commit 784bdc5

1 file changed

Lines changed: 17 additions & 7 deletions

File tree

core/data/src/jvmMain/kotlin/zed/rainxch/core/data/services/DesktopDownloader.kt

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,13 @@ class DesktopDownloader(
3838
val dir = File(files.userDownloadsDir())
3939
if (!dir.exists()) dir.mkdirs()
4040

41-
val safeName = (suggestedFileName?.takeIf { it.isNotBlank() }
42-
?: url.substringAfterLast('/')
43-
.ifBlank { "asset-${UUID.randomUUID()}" })
41+
val rawName = suggestedFileName?.takeIf { it.isNotBlank() }
42+
?: url.substringAfterLast('/').substringBefore('?').substringBefore('#')
43+
.ifBlank { "asset-${UUID.randomUUID()}" }
44+
val safeName = rawName.substringAfterLast('/').substringAfterLast('\\')
45+
require(safeName.isNotBlank() && safeName != "." && safeName != "..") {
46+
"Invalid file name: $rawName"
47+
}
4448
val outFile = File(dir, safeName)
4549

4650
if (outFile.exists()) {
@@ -75,7 +79,9 @@ class DesktopDownloader(
7579

7680
if (bytesRead > 0) {
7781
val byteBuffer = ByteBuffer.wrap(buffer, 0, bytesRead)
78-
fc.write(byteBuffer)
82+
while (byteBuffer.hasRemaining()) {
83+
fc.write(byteBuffer)
84+
}
7985
downloaded.addAndGet(bytesRead.toLong())
8086
}
8187
}
@@ -132,9 +138,13 @@ class DesktopDownloader(
132138
override suspend fun saveToFile(url: String, suggestedFileName: String?): String =
133139
withContext(Dispatchers.IO) {
134140
val dir = File(files.userDownloadsDir())
135-
val safeName = (suggestedFileName?.takeIf { it.isNotBlank() }
136-
?: url.substringAfterLast('/')
137-
.ifBlank { "asset-${UUID.randomUUID()}" })
141+
val rawName = suggestedFileName?.takeIf { it.isNotBlank() }
142+
?: url.substringAfterLast('/').substringBefore('?').substringBefore('#')
143+
.ifBlank { "asset-${UUID.randomUUID()}" }
144+
val safeName = rawName.substringAfterLast('/').substringAfterLast('\\')
145+
require(safeName.isNotBlank() && safeName != "." && safeName != "..") {
146+
"Invalid file name: $rawName"
147+
}
138148

139149
val outFile = File(dir, safeName)
140150

0 commit comments

Comments
 (0)