@@ -92,6 +92,13 @@ static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlCh
9292 return enc ;
9393}
9494
95+ /* Necessary for some error paths to avoid leaking persistent memory. */
96+ static void requestify_string (xmlChar * * str ) {
97+ xmlChar * copy = (xmlChar * ) estrdup ((const char * ) * str );
98+ xmlFree (* str );
99+ * str = copy ;
100+ }
101+
95102static void schema_load_file (sdlCtx * ctx , xmlAttrPtr ns , xmlChar * location , xmlAttrPtr tns , int import ) {
96103 if (location != NULL &&
97104 !zend_hash_str_exists (& ctx -> docs , (char * )location , xmlStrlen (location ))) {
@@ -104,22 +111,35 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA
104111 sdl_restore_uri_credentials (ctx );
105112
106113 if (doc == NULL ) {
114+ requestify_string (& location );
107115 soap_error1 (E_ERROR , "Parsing Schema: can't import schema from '%s'" , location );
108116 }
109117 schema = get_node (doc -> children , "schema" );
110118 if (schema == NULL ) {
119+ requestify_string (& location );
111120 xmlFreeDoc (doc );
112121 soap_error1 (E_ERROR , "Parsing Schema: can't import schema from '%s'" , location );
113122 }
114123 new_tns = get_attribute (schema -> properties , "targetNamespace" );
115124 if (import ) {
116125 if (ns != NULL && (new_tns == NULL || xmlStrcmp (ns -> children -> content , new_tns -> children -> content ) != 0 )) {
117- xmlFreeDoc (doc );
118- soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'" , location , ns -> children -> content );
126+ requestify_string (& location );
127+ if (new_tns == NULL ) {
128+ xmlFreeDoc (doc );
129+ soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', missing 'targetNamespace', expected '%s'" , location , ns -> children -> content );
130+ } else {
131+ /* Have to make a copy to avoid a UAF after freeing `doc` */
132+ const char * target_ns_copy = estrdup ((const char * ) new_tns -> children -> content );
133+ xmlFreeDoc (doc );
134+ soap_error3 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s', expected '%s'" , location , target_ns_copy , ns -> children -> content );
135+ }
119136 }
120137 if (ns == NULL && new_tns != NULL ) {
138+ requestify_string (& location );
139+ /* Have to make a copy to avoid a UAF after freeing `doc` */
140+ const char * target_ns_copy = estrdup ((const char * ) new_tns -> children -> content );
121141 xmlFreeDoc (doc );
122- soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'" , location , new_tns -> children -> content );
142+ soap_error2 (E_ERROR , "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s', expected no 'targetNamespace' " , location , target_ns_copy );
123143 }
124144 } else {
125145 new_tns = get_attribute (schema -> properties , "targetNamespace" );
@@ -128,6 +148,7 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA
128148 xmlSetProp (schema , BAD_CAST ("targetNamespace" ), tns -> children -> content );
129149 }
130150 } else if (tns != NULL && xmlStrcmp (tns -> children -> content , new_tns -> children -> content ) != 0 ) {
151+ requestify_string (& location );
131152 xmlFreeDoc (doc );
132153 soap_error1 (E_ERROR , "Parsing Schema: can't include schema from '%s', different 'targetNamespace'" , location );
133154 }
0 commit comments