mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-10 07:19:02 +08:00
feat: sanitize svg before rendering
This commit is contained in:
parent
5d4a1f49d6
commit
51a5ca76ae
@ -179,6 +179,7 @@
|
|||||||
"dexie-react-hooks": "^1.1.7",
|
"dexie-react-hooks": "^1.1.7",
|
||||||
"diff": "^7.0.0",
|
"diff": "^7.0.0",
|
||||||
"docx": "^9.0.2",
|
"docx": "^9.0.2",
|
||||||
|
"dompurify": "^3.2.6",
|
||||||
"dotenv-cli": "^7.4.2",
|
"dotenv-cli": "^7.4.2",
|
||||||
"electron": "37.2.3",
|
"electron": "37.2.3",
|
||||||
"electron-builder": "26.0.15",
|
"electron-builder": "26.0.15",
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { makeSvgSizeAdaptive } from '@renderer/utils'
|
import { makeSvgSizeAdaptive } from '@renderer/utils'
|
||||||
|
import DOMPurify from 'dompurify'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders an SVG string inside a host element's Shadow DOM to ensure style encapsulation.
|
* Renders an SVG string inside a host element's Shadow DOM to ensure style encapsulation.
|
||||||
@ -14,6 +15,13 @@ export function renderSvgInShadowHost(svgContent: string, hostElement: HTMLEleme
|
|||||||
throw new Error('Host element for SVG rendering is not available.')
|
throw new Error('Host element for SVG rendering is not available.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize the SVG content
|
||||||
|
const sanitizedContent = DOMPurify.sanitize(svgContent, {
|
||||||
|
USE_PROFILES: { svg: true, svgFilters: true },
|
||||||
|
RETURN_DOM_FRAGMENT: false,
|
||||||
|
RETURN_DOM: false
|
||||||
|
})
|
||||||
|
|
||||||
const shadowRoot = hostElement.shadowRoot || hostElement.attachShadow({ mode: 'open' })
|
const shadowRoot = hostElement.shadowRoot || hostElement.attachShadow({ mode: 'open' })
|
||||||
|
|
||||||
// Base styles for the host element and the inner SVG
|
// Base styles for the host element and the inner SVG
|
||||||
@ -36,19 +44,19 @@ export function renderSvgInShadowHost(svgContent: string, hostElement: HTMLEleme
|
|||||||
shadowRoot.innerHTML = ''
|
shadowRoot.innerHTML = ''
|
||||||
shadowRoot.appendChild(style)
|
shadowRoot.appendChild(style)
|
||||||
|
|
||||||
if (svgContent.trim() === '') {
|
if (sanitizedContent.trim() === '') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const parser = new DOMParser()
|
const parser = new DOMParser()
|
||||||
const doc = parser.parseFromString(svgContent, 'image/svg+xml')
|
const doc = parser.parseFromString(sanitizedContent, 'image/svg+xml')
|
||||||
const parserError = doc.querySelector('parsererror')
|
const parserError = doc.querySelector('parsererror')
|
||||||
let svgElement: Element = doc.documentElement
|
let svgElement: Element = doc.documentElement
|
||||||
|
|
||||||
// If parsing fails or the namespace is incorrect, fall back to the more lenient HTML parser.
|
// If parsing fails or the namespace is incorrect, fall back to the more lenient HTML parser.
|
||||||
if (parserError || svgElement.namespaceURI !== 'http://www.w3.org/2000/svg') {
|
if (parserError || svgElement.namespaceURI !== 'http://www.w3.org/2000/svg') {
|
||||||
const tempDiv = document.createElement('div')
|
const tempDiv = document.createElement('div')
|
||||||
tempDiv.innerHTML = svgContent
|
tempDiv.innerHTML = sanitizedContent
|
||||||
const svgFromHtml = tempDiv.querySelector('svg')
|
const svgFromHtml = tempDiv.querySelector('svg')
|
||||||
|
|
||||||
if (svgFromHtml) {
|
if (svgFromHtml) {
|
||||||
|
|||||||
@ -8552,6 +8552,7 @@ __metadata:
|
|||||||
dexie-react-hooks: "npm:^1.1.7"
|
dexie-react-hooks: "npm:^1.1.7"
|
||||||
diff: "npm:^7.0.0"
|
diff: "npm:^7.0.0"
|
||||||
docx: "npm:^9.0.2"
|
docx: "npm:^9.0.2"
|
||||||
|
dompurify: "npm:^3.2.6"
|
||||||
dotenv-cli: "npm:^7.4.2"
|
dotenv-cli: "npm:^7.4.2"
|
||||||
electron: "npm:37.2.3"
|
electron: "npm:37.2.3"
|
||||||
electron-builder: "npm:26.0.15"
|
electron-builder: "npm:26.0.15"
|
||||||
@ -11445,7 +11446,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"dompurify@npm:^3.2.5":
|
"dompurify@npm:^3.2.5, dompurify@npm:^3.2.6":
|
||||||
version: 3.2.6
|
version: 3.2.6
|
||||||
resolution: "dompurify@npm:3.2.6"
|
resolution: "dompurify@npm:3.2.6"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user