Fix malicious links that trigger a crash

This commit is contained in:
2026-07-22 15:32:43 +03:00
Unverified
parent 6b76161f80
commit aa660d9129
3 changed files with 26 additions and 2 deletions
@@ -169,6 +169,7 @@
<string name="profile_load_failed">Не получилось загрузить профиль</string>
<string name="profile_not_found">Профиль не найден</string>
<string name="profile_open_failed">Не удалось открыть профиль. Попробуйте снова.</string>
<string name="profile_invalid_link">Не удалось открыть ссылку</string>
<string name="action_open_settings">Настройки</string>
<string name="action_chat">Написать</string>
<string name="action_copy_link">Скопировать ссылку</string>
@@ -187,6 +187,7 @@
<string name="profile_load_failed">Couldnt load this profile</string>
<string name="profile_not_found">This profile could not be found</string>
<string name="profile_open_failed">Could not open this profile. Please try again.</string>
<string name="profile_invalid_link">Couldnt open the link</string>
<string name="action_open_settings">Settings</string>
<string name="action_chat">Chat</string>
<string name="action_copy_link">Copy link</string>
@@ -174,6 +174,7 @@ import ru.fromchat.profile_headline_bio
import ru.fromchat.profile_headline_member_since
import ru.fromchat.profile_headline_username
import ru.fromchat.profile_headline_verification
import ru.fromchat.profile_invalid_link
import ru.fromchat.profile_load_failed
import ru.fromchat.profile_not_found
import ru.fromchat.profile_verified_support
@@ -830,6 +831,7 @@ fun ProfileScreen(
clipboard = clipboard,
navController = navController,
scope = scope,
snackbarHostState = snackbarHostState,
openContextMenuHaptic = openContextMenuHaptic,
onBack = onBack,
onProfileUpdated = { updated ->
@@ -1045,6 +1047,7 @@ fun PublicChatProfileScreen(
labelCopy = labelCopy,
clipboard = clipboard,
scope = scope,
snackbarHostState = snackbarHostState,
)
}
}
@@ -1084,6 +1087,7 @@ private fun PublicChatProfileLoadedBody(
labelCopy: String,
clipboard: SupportClipboardManager,
scope: CoroutineScope,
snackbarHostState: SnackbarHostState,
modifier: Modifier = Modifier,
) {
Column(
@@ -1130,6 +1134,7 @@ private fun PublicChatProfileLoadedBody(
supportingSlot = {
ProfileBioMarkdown(
content = resolvedProfile.bio.orEmpty(),
snackbarHostState = snackbarHostState,
)
},
position = ListItemPosition.START,
@@ -1317,6 +1322,7 @@ private fun ProfileLoadedBody(
clipboard: SupportClipboardManager,
navController: NavController,
scope: CoroutineScope,
snackbarHostState: SnackbarHostState,
openContextMenuHaptic: () -> Unit,
onBack: () -> Unit,
onProfileUpdated: (UserProfile) -> Unit,
@@ -1498,7 +1504,10 @@ private fun ProfileLoadedBody(
headline = headlineBio,
supportingSlot = {
key(resolvedProfile.id, bioContent) {
ProfileBioMarkdown(content = bioContent)
ProfileBioMarkdown(
content = bioContent,
snackbarHostState = snackbarHostState,
)
}
},
divider = true,
@@ -1857,14 +1866,27 @@ private fun ProfileLoadedBody(
@Composable
private fun ProfileBioMarkdown(
content: String,
snackbarHostState: SnackbarHostState,
modifier: Modifier = Modifier,
) {
val uriHandler = LocalUriHandler.current
val scope = rememberCoroutineScope()
val invalidLinkMessage = stringResource(Res.string.profile_invalid_link)
MarkdownPlain(
content = content,
modifier = modifier,
onLinkClick = { uriHandler.openUri(it) },
onLinkClick = { uri ->
runCatching { uriHandler.openUri(uri) }.onFailure {
scope.launch {
snackbarHostState.showReplacingSnackbar(
message = invalidLinkMessage,
withDismissAction = false,
duration = SnackbarDuration.Short,
)
}
}
},
)
}