@@ -17,6 +17,15 @@ function slugifyHeading(text: string) {
1717 . replace ( / - + $ / , "" ) ; // Trim - from end of text
1818}
1919
20+ function escapeHtml ( text : string ) {
21+ return text
22+ . replace ( / & / g, "&" )
23+ . replace ( / < / g, "<" )
24+ . replace ( / > / g, ">" )
25+ . replace ( / " / g, """ )
26+ . replace ( / ' / g, "'" ) ;
27+ }
28+
2029export async function processMarkdown ( content : string ) : Promise < string > {
2130 if ( ! content ) return "" ;
2231
@@ -61,9 +70,12 @@ export async function processMarkdown(content: string): Promise<string> {
6170 return `<h${ htmlDepth } id="${ id } ">${ title } </h${ htmlDepth } >` ;
6271 } ,
6372 code ( { text, lang } ) {
64- const languageClass = lang ? `language-${ lang } ` : "" ;
65- // Encode text for data attribute
66- const safeCode = text . replace ( / " / g, """ ) ;
73+ const languageClass = lang
74+ ? `language-${ escapeHtml ( lang ) } `
75+ : "" ;
76+ // Escape before sanitize-html runs — otherwise placeholders like
77+ // <IP-address> are treated as tags and stripped from <code>.
78+ const safeCode = escapeHtml ( text ) ;
6779
6880 return `
6981 <div data-copy-wrapper="true">
@@ -76,7 +88,7 @@ export async function processMarkdown(content: string): Promise<string> {
7688 >
7789 ${ copySvg }
7890 </button>
79- <pre><code class="${ languageClass } ">${ text } </code></pre>
91+ <pre><code class="${ languageClass } ">${ safeCode } </code></pre>
8092 </div>
8193 ` ;
8294 } ,
0 commit comments