@@ -98,6 +98,13 @@ static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlCh
9898 return enc ;
9999}
100100
101+ /* Necessary for some error paths to avoid leaking persistent memory. */
102+ static void requestify_string (xmlChar * * str ) {
103+ xmlChar * copy = (xmlChar * ) estrdup ((const char * ) * str );
104+ xmlFree (* str );
105+ * str = copy ;
106+ }
107+
101108static void schema_load_file (sdlCtx * ctx , xmlAttrPtr ns , xmlChar * location , xmlAttrPtr tns , int import ) {
102109 if (location != NULL &&
103110 !zend_hash_str_exists (& ctx -> docs , (char * )location , xmlStrlen (location ))) {
@@ -110,22 +117,35 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA
110117 sdl_restore_uri_credentials (ctx );
111118
112119 if (doc == NULL ) {
120+ requestify_string (& location );
113121 soap_error1 (E_ERROR , "Parsing Schema: can't import schema from '%s'" , location );
114122 }
115123 schema = get_node (doc -> children , "schema" );
116124 if (schema == NULL ) {
125+ requestify_string (& location );
117126 xmlFreeDoc (doc );
118127 soap_error1 (E_ERROR , "Parsing Schema: can't import schema from '%s'" , location );
119128 }
120129 new_tns = get_attribute (schema -> properties , "targetNamespace" );
121130 if (import ) {
122131 if (ns != NULL && (new_tns == NULL || xmlStrcmp (ns -> children -> content , new_tns -> children -> content ) != 0 )) {
123- xmlFreeDoc (doc );
124- soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'" , location , ns -> children -> content );
132+ requestify_string (& location );
133+ if (new_tns == NULL ) {
134+ xmlFreeDoc (doc );
135+ soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', missing 'targetNamespace', expected '%s'" , location , ns -> children -> content );
136+ } else {
137+ /* Have to make a copy to avoid a UAF after freeing `doc` */
138+ const char * target_ns_copy = estrdup ((const char * ) new_tns -> children -> content );
139+ xmlFreeDoc (doc );
140+ soap_error3 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s', expected '%s'" , location , target_ns_copy , ns -> children -> content );
141+ }
125142 }
126143 if (ns == NULL && new_tns != NULL ) {
144+ requestify_string (& location );
145+ /* Have to make a copy to avoid a UAF after freeing `doc` */
146+ const char * target_ns_copy = estrdup ((const char * ) new_tns -> children -> content );
127147 xmlFreeDoc (doc );
128- soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'" , location , new_tns -> children -> content );
148+ soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s', expected no 'targetNamespace' " , location , target_ns_copy );
129149 }
130150 } else {
131151 new_tns = get_attribute (schema -> properties , "targetNamespace" );
@@ -134,6 +154,7 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA
134154 xmlSetProp (schema , BAD_CAST ("targetNamespace" ), tns -> children -> content );
135155 }
136156 } else if (tns != NULL && xmlStrcmp (tns -> children -> content , new_tns -> children -> content ) != 0 ) {
157+ requestify_string (& location );
137158 xmlFreeDoc (doc );
138159 soap_error1 (E_ERROR , "Parsing Schema: can't include schema from '%s', different 'targetNamespace'" , location );
139160 }
0 commit comments