惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
罗磊的独立博客
S
SegmentFault 最新的问题
V
V2EX
V
Visual Studio Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
博客园 - 三生石上(FineUI控件)
Stack Overflow Blog
Stack Overflow Blog
Y
Y Combinator Blog
MyScale Blog
MyScale Blog
D
Docker
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
M
Microsoft Research Blog - Microsoft Research
Martin Fowler
Martin Fowler
S
Secure Thoughts
B
Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Recent Announcements
Recent Announcements
MongoDB | Blog
MongoDB | Blog
C
Cisco Blogs
C
CERT Recently Published Vulnerability Notes
T
True Tiger Recordings
GbyAI
GbyAI
P
Proofpoint News Feed
P
Privacy International News Feed
Jina AI
Jina AI
The Cloudflare Blog
I
Intezer
AWS News Blog
AWS News Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Security Archives - TechRepublic
NISL@THU
NISL@THU
The Register - Security
The Register - Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
P
Palo Alto Networks Blog
S
Schneier on Security
L
LINUX DO - 热门话题
C
CXSECURITY Database RSS Feed - CXSecurity.com
Security Latest
Security Latest
C
Cybersecurity and Infrastructure Security Agency CISA

Recent Commits to openclaw:main

暂无文章

fix(android): filter unsafe markdown links · openclaw/openclaw@4712931
obviyus · 2026-05-18 · via Recent Commits to openclaw:main

File tree

  • apps/android/app/src

    • main/java/ai/openclaw/app/ui/chat

    • test/java/ai/openclaw/app/ui/chat

Original file line numberDiff line numberDiff line change

@@ -75,6 +75,8 @@ import org.commonmark.node.SoftLineBreak

7575

import org.commonmark.node.StrongEmphasis

7676

import org.commonmark.node.ThematicBreak

7777

import org.commonmark.parser.Parser

78+

import java.net.URI

79+

import java.util.Locale

7880

import org.commonmark.node.Image as MarkdownImage

7981

import org.commonmark.node.Text as MarkdownTextNode

8082

@@ -548,15 +550,13 @@ private fun AnnotatedString.Builder.appendLinkNode(

548550

color = linkColor,

549551

textDecoration = TextDecoration.Underline,

550552

)

551-

if (destination.isEmpty()) {

552-

withStyle(linkStyle) {

553-

appendInlineNode(

554-

link.firstChild,

555-

inlineCodeBg = inlineCodeBg,

556-

inlineCodeColor = inlineCodeColor,

557-

linkColor = linkColor,

558-

)

559-

}

553+

if (destination.isEmpty() || !isSafeMarkdownLinkDestination(destination)) {

554+

appendInlineNode(

555+

link.firstChild,

556+

inlineCodeBg = inlineCodeBg,

557+

inlineCodeColor = inlineCodeColor,

558+

linkColor = linkColor,

559+

)

560560

return

561561

}

562562

@@ -570,6 +570,14 @@ private fun AnnotatedString.Builder.appendLinkNode(

570570

}

571571

}

572572
573+

private fun isSafeMarkdownLinkDestination(destination: String): Boolean {

574+

val scheme =

575+

runCatching { URI(destination).scheme?.lowercase(Locale.US) }

576+

.getOrNull()

577+

?: return false

578+

return scheme == "http" || scheme == "https"

579+

}

580+
573581

internal fun buildChatInlineMarkdown(

574582

text: String,

575583

linkColor: Color = Color.Blue,

Original file line numberDiff line numberDiff line change

@@ -33,6 +33,22 @@ class ChatMarkdownTest {

3333

assertEquals("https://docs.openclaw.ai/help/testing", (links.single().item as LinkAnnotation.Url).url)

3434

}

3535
36+

@Test

37+

fun markdownLinksDropUnsafeDestinations() {

38+

listOf(

39+

"intent://example/#Intent;scheme=openclaw;end",

40+

"file:///sdcard/Download/x",

41+

"content://downloads/public_downloads/1",

42+

"tel:+15551234567",

43+

"javascript:alert(1)",

44+

).forEach { destination ->

45+

val annotated = buildChatInlineMarkdown("Open [settings]($destination)")

46+
47+

assertEquals("Open settings", annotated.text)

48+

assertTrue(annotated.getLinkAnnotations(0, annotated.length).isEmpty())

49+

}

50+

}

51+
3652

@Test

3753

fun plainTextDoesNotAddLinkAnnotations() {

3854

val annotated = buildChatInlineMarkdown("No link here")