aboutsummaryrefslogtreecommitdiffstats
path: root/shared/Notify.qml
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-29 16:16:36 +0200
committerDanilo M. <danix@danix.xyz>2026-09-29 16:16:36 +0200
commit8215c7bcde3e1fcb3635059c408b4b97e42f2141 (patch)
treee994d2690e0d6ee06b28eb0976ec570d380341b1 /shared/Notify.qml
parent0da34c765da9b9c831befdab659c9eb0c79c9079 (diff)
downloadquickshell-8215c7bcde3e1fcb3635059c408b4b97e42f2141.tar.gz
quickshell-8215c7bcde3e1fcb3635059c408b4b97e42f2141.zip
feat(notifications): render bodies as Markdown
Balloon and drawer bodies switch from RichText to Qt's MarkdownText (CommonMark plus GitHub extensions). Raw HTML still goes through Qt's HTML importer, so body-markup senders keep working. Markdown images fetch their destination the same way an <img> does, which the existing sanitize filter would miss since it only inspects tags. sanitize now escapes every "![" so the syntax renders as literal text, local or remote; parsing CommonMark destinations and reference definitions to allow local ones is not worth the grammar. Verified in the shell log: before the filter reached the running shell, a test body fetched https://example.org/a.png; after, a second one did not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'shared/Notify.qml')
-rw-r--r--shared/Notify.qml9
1 files changed, 8 insertions, 1 deletions
diff --git a/shared/Notify.qml b/shared/Notify.qml
index 1abe57d..cb1e2fe 100644
--- a/shared/Notify.qml
+++ b/shared/Notify.qml
@@ -75,6 +75,13 @@ Singleton {
// not just the first, so a decoy attribute cannot shadow a remote one;
// entities are decoded before the test, so an encoded scheme cannot slip
// past.
+ //
+ // The body renders as Markdown, so the same rule covers its image syntax:
+ // `![alt](url)` and `![alt][ref]` fetch just as an <img> does, and parsing
+ // their destinations would mean reimplementing CommonMark's link grammar.
+ // Escaping the bracket turns every one into literal text instead, local or
+ // not. Raw HTML inside Markdown goes through Qt's HTML importer, so the
+ // tag filter below still applies to it.
function sanitize(body) {
function decode(s) {
return s.replace(/&(?:#x([0-9a-f]+)|#(\d+)|(amp|colon|sol|tab|quot));/gi,
@@ -84,7 +91,7 @@ Singleton {
return { amp: "&", colon: ":", sol: "/", tab: "\t", quot: "\"" }[name.toLowerCase()];
});
}
- return (body || "").replace(/<img\b[^>]*>/gi, function (tag) {
+ return (body || "").replace(/!\[/g, "!\\[").replace(/<img\b[^>]*>/gi, function (tag) {
const re = /(?:^|\s)src\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi;
let m, found = false, local = true;
while ((m = re.exec(tag))) {