@@ -247,6 +247,7 @@ fn is_valid_for_html_tag_name(c: char, is_empty: bool) -> bool {
247247}
248248
249249/// Parse html tags to ensure they are well-formed
250+ #[ derive( Debug , Clone ) ]
250251struct TagParser {
251252 tags : Vec < ( String , Range < usize > ) > ,
252253 /// Name of the tag that is being parsed, if we are within a tag.
@@ -347,9 +348,8 @@ impl TagParser {
347348 None if self . tag_name . is_empty ( ) => ( prev_pos, '\0' ) ,
348349 None => break ,
349350 } ;
350- dbg ! ( pos, c, & self . in_attrs, & self . tag_name) ;
351351 prev_pos = pos;
352- if ! self . in_attrs && c == '/' && self . tag_name . is_empty ( ) {
352+ if c == '/' && self . tag_name . is_empty ( ) {
353353 // Checking if this is a closing tag (like `</a>` for `<a>`).
354354 self . is_closing = true ;
355355 } else if !self . in_attrs && is_valid_for_html_tag_name ( c, self . tag_name . is_empty ( ) ) {
@@ -364,6 +364,7 @@ impl TagParser {
364364 r. end += 1 ;
365365 }
366366 if self . is_closing {
367+ assert ! ( self . quote. is_none( ) && self . quote_pos. is_none( ) && !self . after_eq, "inconsistent state for closing tag: {self:?}" ) ;
367368 // In case we have "</div >" or even "</div >".
368369 if c != '>' {
369370 if !c. is_whitespace ( ) {
@@ -416,6 +417,7 @@ impl TagParser {
416417 ' parse_til_gt: {
417418 for ( i, c) in text[ pos..] . char_indices ( ) {
418419 if !c. is_whitespace ( ) {
420+ assert_eq ! ( self . quote_pos. is_some( ) , self . quote. is_some( ) ) ;
419421 if let Some ( q) = self . quote {
420422 if c == q {
421423 self . quote = None ;
@@ -486,7 +488,7 @@ impl TagParser {
486488 let mut prev_pos = 0 ;
487489 loop {
488490 if self . quote . is_some ( ) {
489- assert ! ( self . in_attrs) ;
491+ assert ! ( self . in_attrs && self . quote_pos . is_some ( ) ) ;
490492 }
491493 if self . in_attrs &&
492494 let Some ( & ( start_pos, _) ) = iter. peek ( )
@@ -593,3 +595,24 @@ fn test_extract_tags_taglike_in_multievent_attr() {
593595 p ( split_point..dox. len ( ) ) ;
594596 assert_eq ! ( diags. borrow( ) . len( ) , 0 , "unexpected diagnostics: {diags:?}" ) ;
595597}
598+
599+ #[ test]
600+ fn test_extract_tags_taglike_in_multiline_multievent_attr ( ) {
601+ use std:: cell:: RefCell ;
602+
603+ let mut tagp = TagParser :: new ( ) ;
604+ let diags = RefCell :: new ( Vec :: new ( ) ) ;
605+ let dox = "<img src='\n foo:\n </div>\n <p/>\n <div>\n '>" ;
606+ let mut p = |range : Range < usize > | {
607+ tagp. extract_tags ( & dox[ range. clone ( ) ] , range, & mut None , & |s, r, b| {
608+ diags. borrow_mut ( ) . push ( ( s, r. clone ( ) , b) ) ;
609+ } ) } ;
610+ let mut offset = 0 ;
611+ for ln in dox. split_inclusive ( '\n' ) {
612+ let new_offset = offset + ln. len ( ) ;
613+ p ( offset..new_offset) ;
614+ offset = new_offset;
615+ }
616+ assert_eq ! ( diags. borrow( ) . len( ) , 0 , "unexpected diagnostics: {diags:?}" ) ;
617+ assert_eq ! ( tagp. tags. len( ) , 1 ) ;
618+ }
0 commit comments