@@ -34,36 +34,36 @@ qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI, xm
3434 }
3535}
3636
37+ static void start_element_emit_default (XML_Parser parser )
38+ {
39+ if (parser -> h_default ) {
40+ /* Grammar does not allow embedded '<' and '>' in elements, so we can seek to the start and end positions.
41+ * Since the parser in the current mode mode is non-progressive, it contains the entire input. */
42+ const xmlChar * cur = parser -> parser -> input -> cur ;
43+ const xmlChar * end = cur ;
44+ for (const xmlChar * base = parser -> parser -> input -> base ; cur > base && * cur != '<' ; cur -- );
45+ if (* end == '/' ) {
46+ /* BC: Keep split between start & end element.
47+ * TODO: In the future this could be aligned with expat and only emit a start event, or vice versa.
48+ * See gh20439_2.phpt */
49+ xmlChar * tmp = BAD_CAST estrndup ((const char * ) cur , end - cur + 1 );
50+ tmp [end - cur ] = '>' ;
51+ parser -> h_default (parser -> user , tmp , end - cur + 1 );
52+ efree (tmp );
53+ } else {
54+ parser -> h_default (parser -> user , cur , end - cur + 1 );
55+ }
56+ }
57+ }
58+
3759static void
3860start_element_handler (void * user , const xmlChar * name , const xmlChar * * attributes )
3961{
4062 XML_Parser parser = (XML_Parser ) user ;
4163 xmlChar * qualified_name = NULL ;
4264
4365 if (parser -> h_start_element == NULL ) {
44- if (parser -> h_default ) {
45- int attno = 0 ;
46-
47- qualified_name = xmlStrncatNew ((xmlChar * )"<" , name , xmlStrlen (name ));
48- if (attributes ) {
49- while (attributes [attno ] != NULL ) {
50- int att_len ;
51- char * att_string , * att_name , * att_value ;
52-
53- att_name = (char * )attributes [attno ++ ];
54- att_value = (char * )attributes [attno ++ ];
55-
56- att_len = spprintf (& att_string , 0 , " %s=\"%s\"" , att_name , att_value );
57-
58- qualified_name = xmlStrncat (qualified_name , (xmlChar * )att_string , att_len );
59- efree (att_string );
60- }
61-
62- }
63- qualified_name = xmlStrncat (qualified_name , (xmlChar * )">" , 1 );
64- parser -> h_default (parser -> user , (const XML_Char * ) qualified_name , xmlStrlen (qualified_name ));
65- xmlFree (qualified_name );
66- }
66+ start_element_emit_default (parser );
6767 return ;
6868 }
6969
@@ -89,65 +89,7 @@ start_element_handler_ns(void *user, const xmlChar *name, const xmlChar *prefix,
8989 }
9090
9191 if (parser -> h_start_element == NULL ) {
92- if (parser -> h_default ) {
93-
94- if (prefix ) {
95- qualified_name = xmlStrncatNew ((xmlChar * )"<" , prefix , xmlStrlen (prefix ));
96- qualified_name = xmlStrncat (qualified_name , (xmlChar * )":" , 1 );
97- qualified_name = xmlStrncat (qualified_name , name , xmlStrlen (name ));
98- } else {
99- qualified_name = xmlStrncatNew ((xmlChar * )"<" , name , xmlStrlen (name ));
100- }
101-
102- if (namespaces ) {
103- int i , j ;
104- for (i = 0 ,j = 0 ;j < nb_namespaces ;j ++ ) {
105- int ns_len ;
106- char * ns_string , * ns_prefix , * ns_url ;
107-
108- ns_prefix = (char * ) namespaces [i ++ ];
109- ns_url = (char * ) namespaces [i ++ ];
110-
111- if (ns_prefix ) {
112- ns_len = spprintf (& ns_string , 0 , " xmlns:%s=\"%s\"" , ns_prefix , ns_url );
113- } else {
114- ns_len = spprintf (& ns_string , 0 , " xmlns=\"%s\"" , ns_url );
115- }
116- qualified_name = xmlStrncat (qualified_name , (xmlChar * )ns_string , ns_len );
117-
118- efree (ns_string );
119- }
120- }
121-
122- if (attributes ) {
123- for (i = 0 ; i < nb_attributes ; i += 1 ) {
124- int att_len ;
125- char * att_string , * att_name , * att_value , * att_prefix , * att_valueend ;
126-
127- att_name = (char * ) attributes [y ++ ];
128- att_prefix = (char * )attributes [y ++ ];
129- y ++ ;
130- att_value = (char * )attributes [y ++ ];
131- att_valueend = (char * )attributes [y ++ ];
132-
133- if (att_prefix ) {
134- att_len = spprintf (& att_string , 0 , " %s:%s=\"" , att_prefix , att_name );
135- } else {
136- att_len = spprintf (& att_string , 0 , " %s=\"" , att_name );
137- }
138-
139- qualified_name = xmlStrncat (qualified_name , (xmlChar * )att_string , att_len );
140- qualified_name = xmlStrncat (qualified_name , (xmlChar * )att_value , att_valueend - att_value );
141- qualified_name = xmlStrncat (qualified_name , (xmlChar * )"\"" , 1 );
142-
143- efree (att_string );
144- }
145-
146- }
147- qualified_name = xmlStrncat (qualified_name , (xmlChar * )">" , 1 );
148- parser -> h_default (parser -> user , (const XML_Char * ) qualified_name , xmlStrlen (qualified_name ));
149- xmlFree (qualified_name );
150- }
92+ start_element_emit_default (parser );
15193 return ;
15294 }
15395 qualify_namespace (parser , name , URI , & qualified_name );
0 commit comments