@@ -92,6 +92,13 @@ static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlCh
92
92
return enc ;
93
93
}
94
94
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
+
95
102
static void schema_load_file (sdlCtx * ctx , xmlAttrPtr ns , xmlChar * location , xmlAttrPtr tns , int import ) {
96
103
if (location != NULL &&
97
104
!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
104
111
sdl_restore_uri_credentials (ctx );
105
112
106
113
if (doc == NULL ) {
114
+ requestify_string (& location );
107
115
soap_error1 (E_ERROR , "Parsing Schema: can't import schema from '%s'" , location );
108
116
}
109
117
schema = get_node (doc -> children , "schema" );
110
118
if (schema == NULL ) {
119
+ requestify_string (& location );
111
120
xmlFreeDoc (doc );
112
121
soap_error1 (E_ERROR , "Parsing Schema: can't import schema from '%s'" , location );
113
122
}
114
123
new_tns = get_attribute (schema -> properties , "targetNamespace" );
115
124
if (import ) {
116
125
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
+ }
119
136
}
120
137
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 );
121
141
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 );
123
143
}
124
144
} else {
125
145
new_tns = get_attribute (schema -> properties , "targetNamespace" );
@@ -128,6 +148,7 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA
128
148
xmlSetProp (schema , BAD_CAST ("targetNamespace" ), tns -> children -> content );
129
149
}
130
150
} else if (tns != NULL && xmlStrcmp (tns -> children -> content , new_tns -> children -> content ) != 0 ) {
151
+ requestify_string (& location );
131
152
xmlFreeDoc (doc );
132
153
soap_error1 (E_ERROR , "Parsing Schema: can't include schema from '%s', different 'targetNamespace'" , location );
133
154
}
0 commit comments