Skip to content

Commit 98e2134

Browse files
committed
feat: add file type validation for import
Adds validation to check the file type before importing kernel parameters. The import now only accepts text-based files.
1 parent ef6ac49 commit 98e2134

File tree

6 files changed

+29
-3
lines changed

6 files changed

+29
-3
lines changed

app/src/main/kotlin/com/androidvip/sysctlgui/ui/presets/PresetsScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fun PresetsScreen(
6565
}
6666
)
6767
val createFileLauncher = rememberLauncherForActivityResult(
68-
contract = ActivityResultContracts.CreateDocument("*/*"),
68+
contract = ActivityResultContracts.CreateDocument("text/plain"),
6969
onResult = { uri ->
7070
viewModel.onEvent(PresetsViewEvent.BackUpFileCreated(uri))
7171
}

app/src/main/kotlin/com/androidvip/sysctlgui/ui/presets/PresetsViewModel.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.androidvip.sysctlgui.R
77
import com.androidvip.sysctlgui.data.utils.PresetsFileProcessor
88
import com.androidvip.sysctlgui.domain.StringProvider
99
import com.androidvip.sysctlgui.domain.exceptions.EmptyFileException
10+
import com.androidvip.sysctlgui.domain.exceptions.InvalidFileException
1011
import com.androidvip.sysctlgui.domain.exceptions.MalformedLineException
1112
import com.androidvip.sysctlgui.domain.exceptions.NoValidParamException
1213
import com.androidvip.sysctlgui.domain.usecase.AddUserParamsUseCase
@@ -77,6 +78,8 @@ class PresetsViewModel(
7778
setEffect { PresetsViewEffect.ShowError(stringProvider.getString(R.string.export_error_no_param)) }
7879
} catch (_: IOException) {
7980
setEffect { PresetsViewEffect.ShowError(stringProvider.getString(R.string.export_error_io)) }
81+
} catch (_: InvalidFileException) {
82+
setEffect { PresetsViewEffect.ShowError(stringProvider.getString(R.string.import_error_invalid_type)) }
8083
} catch (e: Exception) {
8184
Log.e("PresetsViewModel", "Error importing file", e)
8285
setEffect { PresetsViewEffect.ShowError(stringProvider.getString(R.string.import_error)) }

app/src/main/res/values-pt-rBR/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<string name="tile_start_app_label">Iniciar o SysctlGUI</string>
4545
<string name="export_options">Opções de exportação</string>
4646
<string name="export_error_no_param">Falha: nenhum parâmetro encontrado</string>
47+
<string name="import_error_invalid_type">Tipo de arquivo inválido</string>
4748
<string name="export_error_io">A exportação de parâmetros falhou devido a um erro do armazenamento</string>
4849
<string name="export_options_sum">Importar, exportar ou fazer backup dos parâmetros do kernel</string>
4950
<string name="browse">Nevegar</string>

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<string name="tile_toggle_start_up_label">Run Sysctl GUI at boot</string>
4343
<string name="tile_toggle_start_up_no_root_access_label">Requires root access</string>
4444
<string name="tile_toggle_start_up_no_root_access_toast">Root access required</string>
45+
<string name="import_error_invalid_type">Invalid file type</string>
4546
<string name="export_error_io">Parameter export failed due to an IO error</string>
4647
<string name="export_error_no_param">Failed: no parameter found</string>
4748
<string name="export_options">Export options</string>

data/src/main/java/com/androidvip/sysctlgui/data/utils/PresetsFileProcessor.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.androidvip.sysctlgui.data.utils
33
import android.content.ContentResolver
44
import android.net.Uri
55
import android.util.Log
6+
import android.webkit.MimeTypeMap
7+
import com.androidvip.sysctlgui.domain.exceptions.InvalidFileException
68
import com.androidvip.sysctlgui.domain.exceptions.NoParameterFoundException
79
import com.androidvip.sysctlgui.domain.models.KernelParam
810
import com.androidvip.sysctlgui.utils.isValidSysctlOutputLine
@@ -18,6 +20,7 @@ class PresetsFileProcessor(
1820
suspend fun getKernelParamsFromUri(
1921
uri: Uri
2022
): List<KernelParam> = withContext(ioDispatcher) {
23+
checkFileType(uri)
2124
contentResolver.openInputStream(uri)?.use { inputStream ->
2225
val lines = inputStream.bufferedReader().readLines()
2326
val params = lines.mapNotNull { line ->
@@ -56,4 +59,19 @@ class PresetsFileProcessor(
5659
}
5760
} ?: throw IOException("Failed to open output stream for URI: $uri")
5861
}
59-
}
62+
63+
64+
private suspend fun checkFileType(uri: Uri) = withContext(ioDispatcher) {
65+
val mimeType = contentResolver.getType(uri)
66+
if (mimeType != null && mimeType.startsWith("text/")) {
67+
return@withContext // It's likely a text file, we're good.
68+
}
69+
70+
val fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri.toString()).lowercase()
71+
val allowedExtensions = listOf("conf", "cfg", "config", "ini", "txt")
72+
73+
if (fileExtension in allowedExtensions) return@withContext
74+
75+
throw InvalidFileException("Unsupported file type. MIME type: $mimeType.")
76+
}
77+
}

domain/src/main/java/com/androidvip/sysctlgui/domain/exceptions/ImportExceptions.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.androidvip.sysctlgui.domain.exceptions
22

3-
class InvalidFileExtensionException : Exception()
3+
/**
4+
* Thrown when an invalid file type is trying to be imported.
5+
*/
6+
class InvalidFileException(message: String) : Exception(message)
47
/**
58
* Thrown when an imported file is empty
69
*/

0 commit comments

Comments
 (0)