@@ -828,6 +828,14 @@ function pickValue<T>(values: NonEmptyReadonlyArray<T>, generateRandomNumber: ()
828828 return selectedValue
829829}
830830
831+ function escapeSvgAttribute ( value : string ) : string {
832+ return value
833+ . replace ( / & / g, '&' )
834+ . replace ( / " / g, '"' )
835+ . replace ( / < / g, '<' )
836+ . replace ( / > / g, '>' )
837+ }
838+
831839function createLineElement (
832840 x1 : number ,
833841 y1 : number ,
@@ -837,7 +845,8 @@ function createLineElement(
837845 strokeWidth : number ,
838846 opacity : number ,
839847) : string {
840- return `<line x1="${ x1 } " y1="${ y1 } " x2="${ x2 } " y2="${ y2 } " stroke="${ stroke } " stroke-width="${ strokeWidth } " opacity="${ opacity } " shape-rendering="crispEdges" stroke-linecap="round" stroke-linejoin="round" />`
848+ const safeStroke = escapeSvgAttribute ( stroke )
849+ return `<line x1="${ x1 } " y1="${ y1 } " x2="${ x2 } " y2="${ y2 } " stroke="${ safeStroke } " stroke-width="${ strokeWidth } " opacity="${ opacity } " shape-rendering="crispEdges" stroke-linecap="round" stroke-linejoin="round" />`
841850}
842851
843852function createCircleElement (
@@ -847,7 +856,8 @@ function createCircleElement(
847856 fill : string ,
848857 opacity : number ,
849858) : string {
850- return `<circle cx="${ centerX } " cy="${ centerY } " r="${ radius } " fill="${ fill } " opacity="${ opacity } " />`
859+ const safeFill = escapeSvgAttribute ( fill )
860+ return `<circle cx="${ centerX } " cy="${ centerY } " r="${ radius } " fill="${ safeFill } " opacity="${ opacity } " />`
851861}
852862
853863function createPathElement (
@@ -857,7 +867,9 @@ function createPathElement(
857867 strokeWidth : number ,
858868 opacity : number ,
859869) : string {
860- return `<path d="${ pathData } " fill="${ fill } " stroke="${ stroke } " stroke-width="${ strokeWidth } " opacity="${ opacity } " stroke-linecap="round" stroke-linejoin="round" />`
870+ const safeFill = escapeSvgAttribute ( fill )
871+ const safeStroke = escapeSvgAttribute ( stroke )
872+ return `<path d="${ pathData } " fill="${ safeFill } " stroke="${ safeStroke } " stroke-width="${ strokeWidth } " opacity="${ opacity } " stroke-linecap="round" stroke-linejoin="round" />`
861873}
862874
863875function toNonEmptyReadonlyArray < T > ( values : readonly T [ ] ) : NonEmptyReadonlyArray < T > {
@@ -1025,7 +1037,8 @@ export function createSeededSvgPattern(
10251037 }
10261038
10271039 if ( backgroundColor !== 'transparent' ) {
1028- contentMarkup = `<rect x="0" y="0" width="${ tileSize } " height="${ tileSize } " fill="${ backgroundColor } " />${ contentMarkup } `
1040+ const safeBackgroundColor = escapeSvgAttribute ( backgroundColor )
1041+ contentMarkup = `<rect x="0" y="0" width="${ tileSize } " height="${ tileSize } " fill="${ safeBackgroundColor } " />${ contentMarkup } `
10291042 }
10301043
10311044 return {
0 commit comments