diff --git a/packages/react/components/Editor/lib/export/index.mjs b/packages/react/components/Editor/lib/export/index.mjs index 151474fbec3..21696d68771 100644 --- a/packages/react/components/Editor/lib/export/index.mjs +++ b/packages/react/components/Editor/lib/export/index.mjs @@ -3,7 +3,7 @@ import fileSaver from 'file-saver' import { themePlugin } from '@freesewing/plugin-theme' import { pluginI18n } from '@freesewing/plugin-i18n' import { tilerPlugin } from './plugin-tiler.mjs' -import { capitalize, formatMm, get } from '@freesewing/utils' +import { capitalize, escapeSvgText, formatMm, get } from '@freesewing/utils' import mustache from 'mustache' import he from 'he' import yaml from 'js-yaml' @@ -144,8 +144,9 @@ export const handleExport = async ({ // Save the measurement set name to pattern stores if (settings?.metadata?.setName) { - pattern.store.set('data.setName', settings.metadata.setName) - for (const store of pattern.setStores) store.set('data.setName', settings.metadata.setName) + pattern.store.set('data.setName', escapeSvgText(settings.metadata.setName)) + for (const store of pattern.setStores) + store.set('data.setName', escapeSvgText(settings.metadata.setName)) } // draft and render the pattern diff --git a/packages/utils/src/index.mjs b/packages/utils/src/index.mjs index 580bc3a249e..edddc86713b 100644 --- a/packages/utils/src/index.mjs +++ b/packages/utils/src/index.mjs @@ -62,6 +62,22 @@ export function clone(obj) { return JSON.parse(JSON.stringify(obj)) } +/** + * A method to escapte test that needs to be included in the SVG + * + * This is for user-provided text, such as the measrements set name + * + * @param {string} text - Text to escape + * @return {string} escaped - The escapted text + */ +export function escapeSvgText(text) { + return String(text) + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') +} + /* * Returns the URL of a user avatar (on cloudflare) * based on the ihash and Variant