From 84a5cef71acea5f4e7e35b9425d42ffed1b4d35e Mon Sep 17 00:00:00 2001 From: yue4u Date: Sun, 24 Sep 2023 16:35:41 +0900 Subject: [PATCH 1/3] feat: skip dom purify for trusted content --- packages/icons/src/PixivIcon.ts | 32 ++++++++++++------- .../src/loaders/CharcoalIconFilesLoader.ts | 4 +++ .../icons/src/loaders/CustomIconLoader.ts | 4 +++ packages/icons/src/loaders/Loadable.ts | 1 + packages/icons/src/loaders/index.ts | 17 ++++++---- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/packages/icons/src/PixivIcon.ts b/packages/icons/src/PixivIcon.ts index 19f42780b..d41189755 100644 --- a/packages/icons/src/PixivIcon.ts +++ b/packages/icons/src/PixivIcon.ts @@ -3,7 +3,6 @@ import warning from 'warning' import { KnownIconFile } from './charcoalIconFiles' import { getIcon, addCustomIcon } from './loaders' import { __SERVER__ } from './ssr' -import DOMPurify from 'dompurify' const attributes = ['name', 'scale', 'unsafe-non-guideline-scale'] as const @@ -179,8 +178,14 @@ export class PixivIcon extends HTMLElement { render() { const size = this.forceResizedSize ?? this.scaledSize - const style = DOMPurify.sanitize( - ``, - { ALLOWED_TAGS: ['style'], FORCE_BODY: true } - ) +` - const svg = DOMPurify.sanitize( + const svg = this.svgContent !== undefined ? this.svgContent - : ``, - { USE_PROFILES: { svg: true, svgFilters: true } } - ) + : `` // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.shadowRoot!.innerHTML = style + svg } private async loadSvg(name: string) { - this.svgContent = await getIcon(name) + const iconResult = await getIcon(name) + + if (iconResult.trusted) { + this.svgContent = iconResult.svgContent + } else { + const { default: DOMPurify } = await import('dompurify') + this.svgContent = DOMPurify.sanitize(iconResult.svgContent, { + USE_PROFILES: { svg: true, svgFilters: true }, + }) + } this.render() } diff --git a/packages/icons/src/loaders/CharcoalIconFilesLoader.ts b/packages/icons/src/loaders/CharcoalIconFilesLoader.ts index c5bcc6303..53f7ccc9c 100644 --- a/packages/icons/src/loaders/CharcoalIconFilesLoader.ts +++ b/packages/icons/src/loaders/CharcoalIconFilesLoader.ts @@ -14,6 +14,10 @@ export class CharcoalIconFilesLoader implements Loadable { this._name = name } + get trusted() { + return true + } + get importIconFile() { return charcoalIconFiles[this._name] } diff --git a/packages/icons/src/loaders/CustomIconLoader.ts b/packages/icons/src/loaders/CustomIconLoader.ts index 680cd0b82..2828d42df 100644 --- a/packages/icons/src/loaders/CustomIconLoader.ts +++ b/packages/icons/src/loaders/CustomIconLoader.ts @@ -15,6 +15,10 @@ export class CustomIconLoader implements Loadable { this._filePathOrUrl = filePathOrUrl } + get trusted() { + return false + } + async fetch(): Promise { if (this._resultSvg !== undefined) { return this._resultSvg diff --git a/packages/icons/src/loaders/Loadable.ts b/packages/icons/src/loaders/Loadable.ts index 0e598e9aa..dafc16b3e 100644 --- a/packages/icons/src/loaders/Loadable.ts +++ b/packages/icons/src/loaders/Loadable.ts @@ -1,3 +1,4 @@ export interface Loadable { + readonly trusted: boolean fetch(): Promise } diff --git a/packages/icons/src/loaders/index.ts b/packages/icons/src/loaders/index.ts index 4bdcedb29..302242ddc 100644 --- a/packages/icons/src/loaders/index.ts +++ b/packages/icons/src/loaders/index.ts @@ -21,13 +21,16 @@ export async function getIcon(name: string) { throw new PixivIconLoadError(name, 'Loader was not found') } - return loader.fetch().catch((e) => { - if (e instanceof PixivIconLoadError) { - throw e - } - - throw new PixivIconLoadError(name, e) - }) + return loader + .fetch() + .then((svgContent) => ({ trusted: loader.trusted, svgContent })) + .catch((e) => { + if (e instanceof PixivIconLoadError) { + throw e + } + + throw new PixivIconLoadError(name, e) + }) } function resolveIconLoader(name: string) { From 37c224550fafe54e2a02b65034ab6ba473c2798e Mon Sep 17 00:00:00 2001 From: yue Date: Fri, 6 Oct 2023 15:21:00 +0900 Subject: [PATCH 2/3] fix: check size via isFinite --- packages/icons/src/PixivIcon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/icons/src/PixivIcon.ts b/packages/icons/src/PixivIcon.ts index d41189755..bf8200d23 100644 --- a/packages/icons/src/PixivIcon.ts +++ b/packages/icons/src/PixivIcon.ts @@ -181,7 +181,7 @@ export class PixivIcon extends HTMLElement { if (typeof size !== 'number') { throw new TypeError(`icon size must be number but found ${typeof size}`) } - if (Number.isNaN(size)) { + if (!Number.isFinite(size)) { throw new TypeError(`icon size must not be NaN`) } From 4eb112c976b6b86b4a0bdf493e914ce7dc183c1e Mon Sep 17 00:00:00 2001 From: yue Date: Tue, 10 Oct 2023 11:05:47 +0900 Subject: [PATCH 3/3] fix: remove typeof number check --- packages/icons/src/PixivIcon.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/icons/src/PixivIcon.ts b/packages/icons/src/PixivIcon.ts index bf8200d23..19c0a430f 100644 --- a/packages/icons/src/PixivIcon.ts +++ b/packages/icons/src/PixivIcon.ts @@ -178,9 +178,6 @@ export class PixivIcon extends HTMLElement { render() { const size = this.forceResizedSize ?? this.scaledSize - if (typeof size !== 'number') { - throw new TypeError(`icon size must be number but found ${typeof size}`) - } if (!Number.isFinite(size)) { throw new TypeError(`icon size must not be NaN`) }