@@ -87,6 +87,14 @@ function measureDefaultTextWidth(text: string): number {
8787 return Math . max ( MIN_BADGE_TEXT_WIDTH , Math . round ( text . length * CHAR_WIDTH ) + BADGE_PADDING_X * 2 )
8888}
8989
90+ function escapeXML ( str : string ) : string {
91+ return str
92+ . replace ( / & / g, '&' )
93+ . replace ( / < / g, '<' )
94+ . replace ( / > / g, '>' )
95+ . replace ( / " / g, '"' )
96+ }
97+
9098function measureShieldsTextLength ( text : string ) : number {
9199 const measuredWidth = measureTextWidth ( text , SHIELDS_FONT_SHORTHAND )
92100
@@ -108,9 +116,11 @@ function renderDefaultBadgeSvg(params: {
108116 const rightWidth = measureDefaultTextWidth ( finalValue )
109117 const totalWidth = leftWidth + rightWidth
110118 const height = 20
119+ const escapedLabel = escapeXML ( finalLabel )
120+ const escapedValue = escapeXML ( finalValue )
111121
112122 return `
113- <svg xmlns="http://www.w3.org/2000/svg" width="${ totalWidth } " height="${ height } " role="img" aria-label="${ finalLabel } : ${ finalValue } ">
123+ <svg xmlns="http://www.w3.org/2000/svg" width="${ totalWidth } " height="${ height } " role="img" aria-label="${ escapedLabel } : ${ escapedValue } ">
114124 <clipPath id="r">
115125 <rect width="${ totalWidth } " height="${ height } " rx="3" fill="#fff"/>
116126 </clipPath>
@@ -119,8 +129,8 @@ function renderDefaultBadgeSvg(params: {
119129 <rect x="${ leftWidth } " width="${ rightWidth } " height="${ height } " fill="${ finalColor } "/>
120130 </g>
121131 <g text-anchor="middle" font-family="Geist, system-ui, -apple-system, sans-serif" font-size="11">
122- <text x="${ leftWidth / 2 } " y="14" fill="#ffffff">${ finalLabel } </text>
123- <text x="${ leftWidth + rightWidth / 2 } " y="14" fill="#ffffff">${ finalValue } </text>
132+ <text x="${ leftWidth / 2 } " y="14" fill="#ffffff">${ escapedLabel } </text>
133+ <text x="${ leftWidth + rightWidth / 2 } " y="14" fill="#ffffff">${ escapedValue } </text>
124134 </g>
125135 </svg>
126136 ` . trim ( )
@@ -141,7 +151,9 @@ function renderShieldsBadgeSvg(params: {
141151 const rightWidth = rightTextLength + SHIELDS_LABEL_PADDING_X * 2
142152 const totalWidth = leftWidth + rightWidth
143153 const height = 20
144- const title = `${ finalLabel } : ${ finalValue } `
154+ const escapedLabel = escapeXML ( finalLabel )
155+ const escapedValue = escapeXML ( finalValue )
156+ const title = `${ escapedLabel } : ${ escapedValue } `
145157
146158 const leftCenter = Math . round ( ( leftWidth / 2 ) * 10 )
147159 const rightCenter = Math . round ( ( leftWidth + rightWidth / 2 ) * 10 )
@@ -163,10 +175,10 @@ function renderShieldsBadgeSvg(params: {
163175 <rect width="${ totalWidth } " height="${ height } " fill="url(#s)"/>
164176 </g>
165177 <g fill="#fff" text-anchor="middle" font-family="Verdana, Geneva, DejaVu Sans, sans-serif" text-rendering="geometricPrecision" font-size="110">
166- <text aria-hidden="true" x="${ leftCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ leftTextLengthAttr } ">${ finalLabel } </text>
167- <text x="${ leftCenter } " y="140" transform="scale(.1)" fill="#fff" textLength="${ leftTextLengthAttr } ">${ finalLabel } </text>
168- <text aria-hidden="true" x="${ rightCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ rightTextLengthAttr } ">${ finalValue } </text>
169- <text x="${ rightCenter } " y="140" transform="scale(.1)" fill="#fff" textLength="${ rightTextLengthAttr } ">${ finalValue } </text>
178+ <text aria-hidden="true" x="${ leftCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ leftTextLengthAttr } ">${ escapedLabel } </text>
179+ <text x="${ leftCenter } " y="140" transform="scale(.1)" fill="#fff" textLength="${ leftTextLengthAttr } ">${ escapedLabel } </text>
180+ <text aria-hidden="true" x="${ rightCenter } " y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${ rightTextLengthAttr } ">${ escapedValue } </text>
181+ <text x="${ rightCenter } " y="140" transform="scale(.1)" fill="#fff" textLength="${ rightTextLengthAttr } ">${ escapedValue } </text>
170182 </g>
171183 </svg>
172184 ` . trim ( )
0 commit comments