@@ -6,7 +6,7 @@ use super::{
66} ;
77use crate :: { html:: ElementStyleMap , parser, InlineError } ;
88use html5ever:: { local_name, ns, tendril:: StrTendril , LocalName , QualName } ;
9- use memchr:: memchr_iter;
9+ use memchr:: { memchr3_iter , memchr_iter} ;
1010use smallvec:: { smallvec, SmallVec } ;
1111use std:: io:: Write ;
1212
@@ -216,27 +216,33 @@ impl<'a, W: Write> HtmlSerializer<'a, W> {
216216 Ok ( ( ) )
217217 }
218218
219+ #[ allow( clippy:: arithmetic_side_effects) ]
219220 fn write_attributes ( & mut self , text : & str ) -> Result < ( ) , InlineError > {
221+ let bytes = text. as_bytes ( ) ;
220222 let mut last_end = 0 ;
221- for ( start, part) in text. match_indices ( [ '&' , '\u{00A0}' , '"' ] ) {
222- self . writer . write_all (
223- text. get ( last_end..start)
224- . expect ( "Invalid substring" )
225- . as_bytes ( ) ,
226- ) ?;
227- match part {
228- "&" => self . writer . write_all ( b"&" ) ?,
229- "\u{00A0} " => self . writer . write_all ( b" " ) ?,
230- "\" " => self . writer . write_all ( b""" ) ?,
231- _ => unreachable ! ( "Only the variants above are searched" ) ,
223+
224+ // Scan for '&' (0x26), '"' (0x22), and 0xC2 (first byte of \u{00A0})
225+ for idx in memchr3_iter ( b'&' , b'"' , 0xC2 , bytes) {
226+ match bytes[ idx] {
227+ b'&' => {
228+ self . writer . write_all ( & bytes[ last_end..idx] ) ?;
229+ self . writer . write_all ( b"&" ) ?;
230+ last_end = idx + 1 ;
231+ }
232+ b'"' => {
233+ self . writer . write_all ( & bytes[ last_end..idx] ) ?;
234+ self . writer . write_all ( b""" ) ?;
235+ last_end = idx + 1 ;
236+ }
237+ 0xC2 if bytes. get ( idx + 1 ) == Some ( & 0xA0 ) => {
238+ self . writer . write_all ( & bytes[ last_end..idx] ) ?;
239+ self . writer . write_all ( b" " ) ?;
240+ last_end = idx + 2 ; // Skip both bytes of \u{00A0}
241+ }
242+ _ => { } // False positive for 0xC2 not followed by 0xA0
232243 }
233- last_end = start. checked_add ( part. len ( ) ) . expect ( "Size overflow" ) ;
234244 }
235- self . writer . write_all (
236- text. get ( last_end..text. len ( ) )
237- . expect ( "Invalid substring" )
238- . as_bytes ( ) ,
239- ) ?;
245+ self . writer . write_all ( & bytes[ last_end..] ) ?;
240246 Ok ( ( ) )
241247 }
242248
0 commit comments