@@ -37,36 +37,35 @@ qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI)
3737 }
3838}
3939
40+ static void start_element_emit_default (XML_Parser parser )
41+ {
42+ if (parser -> h_default ) {
43+ /* Grammar does not allow embedded '<' and '>' in elements, so we can seek to the start and end positions.
44+ * Since the parser in the current mode mode is non-progressive, it contains the entire input. */
45+ const xmlChar * cur = parser -> parser -> input -> cur ;
46+ const xmlChar * end = cur ;
47+ for (const xmlChar * base = parser -> parser -> input -> base ; cur > base && * cur != '<' ; cur -- );
48+ if (* end == '/' ) {
49+ /* BC: Keep split between start & end element.
50+ * TODO: In the future this could be aligned with expat and only emit a start event, or vice versa.
51+ * See gh20439_2.phpt */
52+ xmlChar * tmp = BAD_CAST estrndup ((const char * ) cur , end - cur + 1 );
53+ tmp [end - cur ] = '>' ;
54+ parser -> h_default (parser -> user , tmp , end - cur + 1 );
55+ efree (tmp );
56+ } else {
57+ parser -> h_default (parser -> user , cur , end - cur + 1 );
58+ }
59+ }
60+ }
61+
4062static void
4163start_element_handler (void * user , const xmlChar * name , const xmlChar * * attributes )
4264{
4365 XML_Parser parser = (XML_Parser ) user ;
4466
4567 if (parser -> h_start_element == NULL ) {
46- if (parser -> h_default ) {
47- int attno = 0 ;
48- smart_string qualified_name = {0 };
49-
50- smart_string_appendc (& qualified_name , '<' );
51- smart_string_appends (& qualified_name , (const char * ) name );
52-
53- if (attributes ) {
54- while (attributes [attno ] != NULL ) {
55- const char * att_name = (const char * ) attributes [attno ++ ];
56- const char * att_value = (const char * ) attributes [attno ++ ];
57-
58- smart_string_appendc (& qualified_name , ' ' );
59- smart_string_appends (& qualified_name , att_name );
60- smart_string_appends (& qualified_name , "=\"" );
61- smart_string_appends (& qualified_name , att_value );
62- smart_string_appendc (& qualified_name , '"' );
63- }
64- }
65- smart_string_appendc (& qualified_name , '>' );
66- smart_string_0 (& qualified_name );
67- parser -> h_default (parser -> user , (const XML_Char * ) qualified_name .c , qualified_name .len );
68- smart_string_free (& qualified_name );
69- }
68+ start_element_emit_default (parser );
7069 return ;
7170 }
7271
@@ -92,59 +91,7 @@ start_element_handler_ns(void *user, const xmlChar *name, const xmlChar *prefix,
9291 }
9392
9493 if (parser -> h_start_element == NULL ) {
95- if (parser -> h_default ) {
96- smart_string qualified_name = {0 };
97- smart_string_appendc (& qualified_name , '<' );
98- if (prefix ) {
99- smart_string_appends (& qualified_name , (const char * ) prefix );
100- smart_string_appendc (& qualified_name , ':' );
101- }
102- smart_string_appends (& qualified_name , (const char * ) name );
103-
104- if (namespaces ) {
105- int i , j ;
106- for (i = 0 ,j = 0 ;j < nb_namespaces ;j ++ ) {
107- const char * ns_prefix = (const char * ) namespaces [i ++ ];
108- const char * ns_url = (const char * ) namespaces [i ++ ];
109-
110- if (ns_prefix ) {
111- smart_string_appends (& qualified_name , " xmlns:" );
112- smart_string_appends (& qualified_name , ns_prefix );
113- smart_string_appends (& qualified_name , "=\"" );
114- } else {
115- smart_string_appends (& qualified_name , " xmlns=\"" );
116- }
117-
118- smart_string_appends (& qualified_name , ns_url );
119- smart_string_appendc (& qualified_name , '"' );
120- }
121- }
122-
123- if (attributes ) {
124- for (i = 0 ; i < nb_attributes ; i += 1 ) {
125- const char * att_name = (const char * ) attributes [y ++ ];
126- const char * att_prefix = (const char * )attributes [y ++ ];
127- y ++ ;
128- const char * att_value = (const char * )attributes [y ++ ];
129- const char * att_valueend = (const char * )attributes [y ++ ];
130-
131- smart_string_appendc (& qualified_name , ' ' );
132- if (att_prefix ) {
133- smart_string_appends (& qualified_name , att_prefix );
134- smart_string_appendc (& qualified_name , ':' );
135- }
136- smart_string_appends (& qualified_name , att_name );
137- smart_string_appends (& qualified_name , "=\"" );
138-
139- smart_string_appendl (& qualified_name , att_value , att_valueend - att_value );
140- smart_string_appendc (& qualified_name , '"' );
141- }
142-
143- }
144- smart_string_appendc (& qualified_name , '>' );
145- parser -> h_default (parser -> user , (const XML_Char * ) qualified_name .c , qualified_name .len );
146- smart_string_free (& qualified_name );
147- }
94+ start_element_emit_default (parser );
14895 return ;
14996 }
15097 qualified_name = qualify_namespace (parser , name , URI );
0 commit comments