@@ -260,12 +260,32 @@ function handleSearch(e) {
260260
261261 const titleEl = document . getElementById ( 'titleText' ) ;
262262 if ( titleEl ) {
263- titleEl . innerHTML = `Résultats pour "${ q } " <span class="text-gray-500 text-sm ml-2">(${ res . length } )</span>` ;
263+ // Safely update the title text and count without using innerHTML with untrusted input
264+ titleEl . textContent = `Résultats pour "${ q } " ` ;
265+ let countSpan = titleEl . querySelector ( '.text-gray-500.text-sm.ml-2' ) ;
266+ if ( ! countSpan ) {
267+ countSpan = document . createElement ( 'span' ) ;
268+ countSpan . className = 'text-gray-500 text-sm ml-2' ;
269+ titleEl . appendChild ( countSpan ) ;
270+ }
271+ countSpan . textContent = `(${ res . length } )` ;
264272 } else {
265273 const sectionTitle = document . getElementById ( 'sectionTitle' ) ;
266274 if ( sectionTitle ) {
267- sectionTitle . innerHTML = `<span class="w-1 h-8 bg-red-600 rounded-full shadow-[0_0_15px_#dc2626]"></span>
268- <span id="titleText" class="tracking-tight">Résultats pour "${ q } " (${ res . length } )</span>` ;
275+ // Rebuild the section title structure using DOM APIs to avoid interpreting q as HTML
276+ while ( sectionTitle . firstChild ) {
277+ sectionTitle . removeChild ( sectionTitle . firstChild ) ;
278+ }
279+
280+ const accentSpan = document . createElement ( 'span' ) ;
281+ accentSpan . className = 'w-1 h-8 bg-red-600 rounded-full shadow-[0_0_15px_#dc2626]' ;
282+ sectionTitle . appendChild ( accentSpan ) ;
283+
284+ const titleTextSpan = document . createElement ( 'span' ) ;
285+ titleTextSpan . id = 'titleText' ;
286+ titleTextSpan . className = 'tracking-tight' ;
287+ titleTextSpan . textContent = `Résultats pour "${ q } " (${ res . length } )` ;
288+ sectionTitle . appendChild ( titleTextSpan ) ;
269289 }
270290 }
271291 renderGrid ( res ) ;
0 commit comments