Sanitize user input to prevent shell escape
This commit is contained in:
@@ -76,9 +76,10 @@ fun CreateImgDialog(
|
|||||||
|
|
||||||
val fullFileName = if (fileName.isNotBlank()) "$fileName.img" else ""
|
val fullFileName = if (fileName.isNotBlank()) "$fileName.img" else ""
|
||||||
val fileExists = fullFileName.isNotEmpty() && existingFiles.contains(fullFileName)
|
val fileExists = fullFileName.isNotEmpty() && existingFiles.contains(fullFileName)
|
||||||
|
val hasInvalidChars = fileName.any { !it.isLetterOrDigit() && it !in "-_. ()[]+," }
|
||||||
|
|
||||||
val isValidInput = fileName.isNotBlank() &&
|
val isValidInput = fileName.isNotBlank() &&
|
||||||
!fileName.contains("/") &&
|
!hasInvalidChars &&
|
||||||
sizeValue.toLongOrNull()?.let { it > 0 } == true &&
|
sizeValue.toLongOrNull()?.let { it > 0 } == true &&
|
||||||
!fileExists
|
!fileExists
|
||||||
|
|
||||||
@@ -135,11 +136,11 @@ fun CreateImgDialog(
|
|||||||
// File name input
|
// File name input
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = fileName,
|
value = fileName,
|
||||||
onValueChange = { fileName = it.replace("/", "") },
|
onValueChange = { fileName = it },
|
||||||
label = { Text("File Name") },
|
label = { Text("File Name") },
|
||||||
suffix = { Text(".img") },
|
suffix = { Text(".img") },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
isError = fileExists,
|
isError = fileExists || hasInvalidChars,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -153,6 +154,16 @@ fun CreateImgDialog(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show error if invalid characters
|
||||||
|
if (hasInvalidChars) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "Invalid file name",
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
// Size input
|
// Size input
|
||||||
|
|||||||
@@ -170,7 +170,8 @@ private fun RenameDialog(
|
|||||||
val nameWithoutExtension = currentName.removeSuffix(extension)
|
val nameWithoutExtension = currentName.removeSuffix(extension)
|
||||||
|
|
||||||
var newName by remember { mutableStateOf(nameWithoutExtension) }
|
var newName by remember { mutableStateOf(nameWithoutExtension) }
|
||||||
val isValid = newName.isNotBlank() && !newName.contains("/")
|
val hasInvalidChars = newName.any { !it.isLetterOrDigit() && it !in "-_. ()[]+," }
|
||||||
|
val isValid = newName.isNotBlank() && !hasInvalidChars
|
||||||
|
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismiss,
|
onDismissRequest = onDismiss,
|
||||||
@@ -179,12 +180,22 @@ private fun RenameDialog(
|
|||||||
Column {
|
Column {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = newName,
|
value = newName,
|
||||||
onValueChange = { newName = it.replace("/", "") },
|
onValueChange = { newName = it },
|
||||||
label = { Text("File Name") },
|
label = { Text("File Name") },
|
||||||
suffix = { Text(extension) },
|
suffix = { Text(extension) },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
|
isError = hasInvalidChars,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (hasInvalidChars) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "Invalid file name",
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.error
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
|
|||||||
@@ -489,6 +489,7 @@ private fun DirectoryBrowserDialog(
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
val trimmedName = name.trim()
|
val trimmedName = name.trim()
|
||||||
if (trimmedName.isEmpty()) return@launch
|
if (trimmedName.isEmpty()) return@launch
|
||||||
|
|
||||||
val newPath = "$currentPath/$trimmedName"
|
val newPath = "$currentPath/$trimmedName"
|
||||||
RootManager.executeCommand("mkdir -p \"$newPath\"")
|
RootManager.executeCommand("mkdir -p \"$newPath\"")
|
||||||
// Create marker file to indicate this folder was created by the app
|
// Create marker file to indicate this folder was created by the app
|
||||||
@@ -716,6 +717,9 @@ private fun DirectoryBrowserDialog(
|
|||||||
|
|
||||||
// Create folder dialog
|
// Create folder dialog
|
||||||
if (showCreateFolderDialog) {
|
if (showCreateFolderDialog) {
|
||||||
|
val hasInvalidChars = newFolderName.any { !it.isLetterOrDigit() && it !in "-_. ()[]+," }
|
||||||
|
val isValidInput = newFolderName.isNotBlank() && !hasInvalidChars
|
||||||
|
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
showCreateFolderDialog = false
|
showCreateFolderDialog = false
|
||||||
@@ -723,24 +727,36 @@ private fun DirectoryBrowserDialog(
|
|||||||
},
|
},
|
||||||
title = { Text("Create Directory") },
|
title = { Text("Create Directory") },
|
||||||
text = {
|
text = {
|
||||||
OutlinedTextField(
|
Column {
|
||||||
value = newFolderName,
|
OutlinedTextField(
|
||||||
onValueChange = { newFolderName = it },
|
value = newFolderName,
|
||||||
label = { Text("Directory name") },
|
onValueChange = { newFolderName = it },
|
||||||
singleLine = true,
|
label = { Text("Directory name") },
|
||||||
modifier = Modifier.fillMaxWidth()
|
singleLine = true,
|
||||||
)
|
isError = hasInvalidChars,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
if (hasInvalidChars) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
Text(
|
||||||
|
text = "Invalid directory name",
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (newFolderName.isNotBlank()) {
|
if (isValidInput) {
|
||||||
createFolder(newFolderName)
|
createFolder(newFolderName)
|
||||||
showCreateFolderDialog = false
|
showCreateFolderDialog = false
|
||||||
newFolderName = ""
|
newFolderName = ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = newFolderName.isNotBlank()
|
enabled = isValidInput
|
||||||
) {
|
) {
|
||||||
Text("Create")
|
Text("Create")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user