Skip to content

Commit 3ad1f66

Browse files
committed
fix(主页): 提升主页事件安全性
1 parent 0c39c45 commit 3ad1f66

1 file changed

Lines changed: 66 additions & 42 deletions

File tree

  • ZalithLauncher/src/main/java/com/movtery/zalithlauncher/ui/activities

ZalithLauncher/src/main/java/com/movtery/zalithlauncher/ui/activities/MainActivity.kt

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -470,58 +470,82 @@ class MainActivity : BaseAppCompatActivity() {
470470
key: String,
471471
data: String?
472472
) {
473-
when (key) {
474-
//浏览器内打开指定链接
475-
"url" -> {
476-
if (data != null) {
477-
withContext(Dispatchers.Main) {
478-
this@MainActivity.openLink(data)
473+
runCatching {
474+
when (key) {
475+
//浏览器内打开指定链接
476+
"url" -> {
477+
data?.let { url ->
478+
val trimmed = url.trim()
479+
//防止 file://、intent:// 等危险 scheme
480+
if (trimmed.startsWith("http://", ignoreCase = true) ||
481+
trimmed.startsWith("https://", ignoreCase = true)
482+
) {
483+
withContext(Dispatchers.Main) {
484+
this@MainActivity.openLink(trimmed)
485+
}
486+
} else {
487+
lWarning("Blocked unsafe URL from homepage event: $trimmed")
488+
}
479489
}
480490
}
481-
}
482-
//检查启动器更新
483-
"check_update" -> checkUpdate()
484-
//启动当前选中的游戏版本
485-
"launch_game" -> {
486-
if (data != null) {
487-
runCatching {
488-
val parms = data.split("=")
489-
if (parms.size == 2 && parms[0] == "server") {
490-
//指定快速启动的服务器ip
491-
val serverIp = parms[1].trim()
491+
//检查启动器更新
492+
"check_update" -> checkUpdate()
493+
//启动当前选中的游戏版本
494+
"launch_game" -> {
495+
val serverIp = data?.let { raw ->
496+
runCatching {
497+
val parms = raw.split("=", limit = 2)
498+
if (parms.size == 2 && parms[0] == "server") {
499+
parms[1].trim()
500+
} else null
501+
}.onFailure { e ->
502+
lWarning("Failed to parse quick join server parameters: $raw", e)
503+
}.getOrNull()
504+
}
505+
if (!serverIp.isNullOrEmpty()) {
506+
//禁止控制字符与换行,防止注入命令行参数或配置文件
507+
if (serverIp.none { it.code < 32 }) {
492508
launchGameViewModel.tryPlayServer(serverIp)
493-
return
509+
} else {
510+
lWarning("Invalid server address from homepage event: $serverIp")
494511
}
495-
}.onFailure { e ->
496-
lWarning("Failed to parse quick join server parameters: $data", e)
512+
} else {
513+
launchGameViewModel.tryLaunch()
497514
}
498515
}
499-
launchGameViewModel.tryLaunch()
500-
}
501-
//复制指定文本
502-
"copy" -> {
503-
if (data != null) {
504-
withContext(Dispatchers.Main) {
505-
copyText(
506-
null,
507-
data,
508-
this@MainActivity,
509-
showToast = true
510-
)
516+
//复制指定文本
517+
"copy" -> {
518+
data?.let { text ->
519+
val trimmed = text.trim()
520+
withContext(Dispatchers.Main) {
521+
copyText(
522+
null,
523+
trimmed.take(10_000), //限制复制内容长度
524+
this@MainActivity,
525+
showToast = true
526+
)
527+
}
511528
}
512529
}
513-
}
514-
//刷新主页
515-
"refresh_page" -> homePageViewModel.reloadPage(true)
516-
//分享游戏日志
517-
"share_game_log" -> {
518-
VersionsManager.currentVersion.value?.let { version ->
519-
VersionsManager.getLatestLog(version).takeIf { it.exists() }
520-
}?.let { logFile ->
521-
logsUploadViewModel.check(logFile)
522-
logShareViewModel.openMenu(logFile)
530+
//刷新主页
531+
"refresh_page" -> homePageViewModel.reloadPage(true)
532+
//分享游戏日志
533+
"share_game_log" -> {
534+
VersionsManager.currentVersion.value?.let { version ->
535+
VersionsManager.getLatestLog(version).takeIf { it.exists() }
536+
}?.let { logFile ->
537+
withContext(Dispatchers.Main) {
538+
logsUploadViewModel.check(logFile)
539+
logShareViewModel.openMenu(logFile)
540+
}
541+
}
542+
}
543+
else -> {
544+
lWarning("Unknown homepage event: key=$key, data=$data")
523545
}
524546
}
547+
}.onFailure { e ->
548+
lWarning("Failed to handle homepage event: key=$key, data=$data", e)
525549
}
526550
}
527551

0 commit comments

Comments
 (0)