From ddcc61044aa5291d2f6233de161ce0039a77d908 Mon Sep 17 00:00:00 2001 From: Lynn Date: Mon, 5 Jun 2023 13:14:25 +0800 Subject: [PATCH] fix: Should escape specific content (#506) --- package.json | 1 + pnpm-lock.yaml | 6 ++++++ src/builder/text.ts | 5 +++-- ...e-html-when-embed-font-is-false-1-snap.png | Bin 0 -> 1644 bytes test/font.test.tsx | 20 ++++++++++++++++++ 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 test/__image_snapshots__/font-test-tsx-test-font-test-tsx-font-should-handle-escape-html-when-embed-font-is-false-1-snap.png diff --git a/package.json b/package.json index 33f1bd57..39d85e7b 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,7 @@ "css-box-shadow": "1.0.0-3", "css-to-react-native": "^3.0.0", "emoji-regex": "^10.2.1", + "escape-html": "^1.0.3", "linebreak": "^1.1.0", "parse-css-color": "^0.2.1", "postcss-value-parser": "^4.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7d5d42e..e11f4525 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,6 +18,7 @@ importers: css-to-react-native: ^3.0.0 emoji-regex: ^10.2.1 esbuild-plugin-replace: ^1.2.0 + escape-html: ^1.0.3 eslint: ^8.25.0 eslint-plugin-react: ^7.31.10 eslint-plugin-react-hooks: ^4.6.0 @@ -41,6 +42,7 @@ importers: css-box-shadow: 1.0.0-3 css-to-react-native: 3.0.0 emoji-regex: 10.2.1 + escape-html: 1.0.3 linebreak: 1.1.0 parse-css-color: 0.2.1 postcss-value-parser: 4.2.0 @@ -1851,6 +1853,10 @@ packages: engines: {node: '>=6'} dev: true + /escape-html/1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + /escape-string-regexp/1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} diff --git a/src/builder/text.ts b/src/builder/text.ts index 09ad31a0..26eddbae 100644 --- a/src/builder/text.ts +++ b/src/builder/text.ts @@ -1,3 +1,4 @@ +import escapeHTML from 'escape-html' import type { ParsedTransformOrigin } from '../transform-origin.js' import transform from './transform.js' import { buildXMLString } from '../utils.js' @@ -141,11 +142,11 @@ export default function buildText( fill: style.color, opacity: opacity !== 1 ? opacity : undefined, }, - content + escapeHTML(content) ) + (decorationShape || '') + (filter ? '' : '') + extra, - shape ? buildXMLString('text', shapeProps, content) : '', + shape ? buildXMLString('text', shapeProps, escapeHTML(content)) : '', ] } diff --git a/test/__image_snapshots__/font-test-tsx-test-font-test-tsx-font-should-handle-escape-html-when-embed-font-is-false-1-snap.png b/test/__image_snapshots__/font-test-tsx-test-font-test-tsx-font-should-handle-escape-html-when-embed-font-is-false-1-snap.png new file mode 100644 index 0000000000000000000000000000000000000000..60261d236bc3970a053bae3ab73c4ad6eabda1a4 GIT binary patch literal 1644 zcmds2`BPJ86a|`uB?br#iy$GEA`FX;rLu*fPe28!0r}_KGDa^7EMIvE54UsYy+|t+)rx@@uof zBX^h($EO_L*solIuiJkSyc(~Qlr6)Z56guzgezE1E6srgU}{wA63#{kbGriYfVQ%q zD1@VR&)@_AT*NcAwXR1_ZP;xWn~SyiVquk0JzhUEL9+xLj7kw~&B_+K2=Pj_X15%e zTkKcf(kEI;tMP!YAYo3JTK@XpN?K0@*one;1~2rek4}g}xaRm>aG&O=u}hBy85C3* z$%W)*o9o{@hB*%-;C<^Tab@$g8>SK>=x?3xMQ@4+XYa3FhfA#5wKE7O#&H%=Ck&8# z(RF4uI(stbrAQWVBAlmBU)ItZ3lJ8Yyt3C@)Cw+{`JnY8LLY4PS@1=2Fhwt zsV59Fkwk#&J%{BCMLIO|NBuD>*PE$&F15SNiPlYCxy>!NY$WG>1-5WPyinkp&0j1rRG9%fiD_nesJL~=fKy)UtGHXViJ!e-ftQuEZ zh+uiLCHrb=o;~HLDU#zzF`iU-JV_BuCh+DYyFX4S@GM8Tjf!1jQUrA$U4 zFYy71JLZ(FRLAnQ9gepGlUSL#osYI0+N9iU4?QzBx{}VGnSOJ}U*_J(Ptu`TS{*8X z00Aw`B_u{odp0Zgs}v`2{Y(VjH*xXgnA)mUd#DH*F(&m}MIc|ribC0A*PT+^BdNTH zor&JKu?TPrBSARUAfS~PYw+fCsYXyvxpQdErI9>ZFTjt~t>n<+iYux=`Q6iEx+&;p zt1yjcC5g}_GL1<7}kN}Lyw>3AQ;9-Kv!f5@K8U#T{8UGVIElECnG`^osv~4>nprLyduNpMHMg4G`g?CCxjbgwG5 zBwBawOZjUSSVy@pCiiqZz@VKWpWzo%4wAg`sK>#iDKiui!Y+;a(a|>k%}>=+F?F^%pJ(s S_pAPj7=(wN32i=}!u%J|_!Uq9 literal 0 HcmV?d00001 diff --git a/test/font.test.tsx b/test/font.test.tsx index 33cdcd98..f49e9188 100644 --- a/test/font.test.tsx +++ b/test/font.test.tsx @@ -146,4 +146,24 @@ describe('Font', () => { expect(toImage(svg, 100)).toMatchImageSnapshot() }) }) + + it('should handle escape html when embedFont is false', async () => { + const svg = await satori( +
+ {`Hello<>&'" world`} +
, + { + width: 100, + height: 100, + fonts, + embedFont: false, + } + ) + + expect(toImage(svg)).toMatchImageSnapshot() + }) })