@@ -84,60 +84,6 @@ pub(super) struct ReaderState {
8484}
8585
8686impl ReaderState {
87- /// Wraps content of `buf` into the [`Event::End`] event. Does the check that
88- /// end name matches the last opened start name if `self.config.check_end_names` is set.
89- pub fn emit_end < ' b > ( & mut self , buf : & ' b [ u8 ] ) -> Result < Event < ' b > > {
90- // Strip the `/` character. `content` contains data between `</` and `>`
91- let content = & buf[ 1 ..] ;
92- // XML standard permits whitespaces after the markup name in closing tags.
93- // Let's strip them from the buffer before comparing tag names.
94- let name = if self . config . trim_markup_names_in_closing_tags {
95- if let Some ( pos_end_name) = content. iter ( ) . rposition ( |& b| !is_whitespace ( b) ) {
96- & content[ ..pos_end_name + 1 ]
97- } else {
98- content
99- }
100- } else {
101- content
102- } ;
103-
104- let decoder = self . decoder ( ) ;
105-
106- // Get the index in self.opened_buffer of the name of the last opened tag
107- match self . opened_starts . pop ( ) {
108- Some ( start) => {
109- if self . config . check_end_names {
110- let expected = & self . opened_buffer [ start..] ;
111- if name != expected {
112- let expected = decoder. decode ( expected) . unwrap_or_default ( ) . into_owned ( ) ;
113- // #513: In order to allow error recovery we should drop content of the buffer
114- self . opened_buffer . truncate ( start) ;
115-
116- // Report error at start of the end tag at `<` character
117- // -2 for `<` and `>`
118- self . last_error_offset = self . offset - buf. len ( ) - 2 ;
119- return Err ( Error :: IllFormed ( IllFormedError :: MismatchedEndTag {
120- expected,
121- found : decoder. decode ( name) . unwrap_or_default ( ) . into_owned ( ) ,
122- } ) ) ;
123- }
124- }
125-
126- self . opened_buffer . truncate ( start) ;
127- }
128- None => {
129- // Report error at start of the end tag at `<` character
130- // -2 for `<` and `>`
131- self . last_error_offset = self . offset - buf. len ( ) - 2 ;
132- return Err ( Error :: IllFormed ( IllFormedError :: UnmatchedEndTag (
133- decoder. decode ( name) . unwrap_or_default ( ) . into_owned ( ) ,
134- ) ) ) ;
135- }
136- }
137-
138- Ok ( Event :: End ( BytesEnd :: wrap ( name. into ( ) ) ) )
139- }
140-
14187 /// Get the decoder, used to decode bytes, read by this reader, to the strings.
14288 ///
14389 /// If [`encoding`] feature is enabled, the used encoding may change after
@@ -384,7 +330,56 @@ impl ReaderState {
384330 debug_assert ! ( content. starts_with( b"</" ) , "{:?}" , Bytes ( content) ) ;
385331 debug_assert ! ( content. ends_with( b">" ) , "{:?}" , Bytes ( content) ) ;
386332
387- self . emit_end ( & content[ 1 ..content. len ( ) - 1 ] )
333+ let buf = & content[ 1 ..content. len ( ) - 1 ] ;
334+ // Strip the `/` character. `content` contains data between `</` and `>`
335+ let content = & buf[ 1 ..] ;
336+ // XML standard permits whitespaces after the markup name in closing tags.
337+ // Let's strip them from the buffer before comparing tag names.
338+ let name = if self . config . trim_markup_names_in_closing_tags {
339+ if let Some ( pos_end_name) = content. iter ( ) . rposition ( |& b| !is_whitespace ( b) ) {
340+ & content[ ..pos_end_name + 1 ]
341+ } else {
342+ content
343+ }
344+ } else {
345+ content
346+ } ;
347+
348+ let decoder = self . decoder ( ) ;
349+
350+ // Get the index in self.opened_buffer of the name of the last opened tag
351+ match self . opened_starts . pop ( ) {
352+ Some ( start) => {
353+ if self . config . check_end_names {
354+ let expected = & self . opened_buffer [ start..] ;
355+ if name != expected {
356+ let expected = decoder. decode ( expected) . unwrap_or_default ( ) . into_owned ( ) ;
357+ // #513: In order to allow error recovery we should drop content of the buffer
358+ self . opened_buffer . truncate ( start) ;
359+
360+ // Report error at start of the end tag at `<` character
361+ // -2 for `<` and `>`
362+ self . last_error_offset = self . offset - buf. len ( ) - 2 ;
363+ return Err ( Error :: IllFormed ( IllFormedError :: MismatchedEndTag {
364+ expected,
365+ found : decoder. decode ( name) . unwrap_or_default ( ) . into_owned ( ) ,
366+ } ) ) ;
367+ }
368+ }
369+
370+ self . opened_buffer . truncate ( start) ;
371+ }
372+ None => {
373+ // Report error at start of the end tag at `<` character
374+ // -2 for `<` and `>`
375+ self . last_error_offset = self . offset - buf. len ( ) - 2 ;
376+ return Err ( Error :: IllFormed ( IllFormedError :: UnmatchedEndTag (
377+ decoder. decode ( name) . unwrap_or_default ( ) . into_owned ( ) ,
378+ ) ) ) ;
379+ }
380+ }
381+
382+ Ok ( Event :: End ( BytesEnd :: wrap ( name. into ( ) ) ) )
388383 }
389384 FeedResult :: EncodingUtf8Like ( _)
390385 | FeedResult :: EncodingUtf16BeLike ( _)
0 commit comments