Skip to content

Commit 138cdc9

Browse files
committed
Fix bug #62900: Wrong namespace on xsd import error message
The one error message indeed had a wrong namespace, and in general they weren't very descriptive, this also makes them more descriptive. Furthermore, two additional bugs were fixed: - Persistent memory leak of `location`. - UAF issues when printing the error message.
1 parent 7e722e3 commit 138cdc9

File tree

3 files changed

+114
-3
lines changed

3 files changed

+114
-3
lines changed

ext/soap/php_schema.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
95102
static 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
}

ext/soap/tests/bugs/bug62900.phpt

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
--TEST--
2+
Bug #62900 (Wrong namespace on xsd import error message)
3+
--EXTENSIONS--
4+
soap
5+
--INI--
6+
soap.wsdl_cache_enabled=0
7+
--FILE--
8+
<?php
9+
10+
$wsdl_with_ns = <<<XML
11+
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test-uri">
12+
<types>
13+
<xs:schema targetNamespace="http://test-uri" elementFormDefault="qualified">
14+
<import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="bug62900.xsd" />
15+
</xs:schema>
16+
</types>
17+
</definitions>
18+
XML;
19+
20+
$wsdl_without_ns = <<<XML
21+
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test-uri">
22+
<types>
23+
<xs:schema elementFormDefault="qualified">
24+
<import schemaLocation="bug62900.xsd" />
25+
</xs:schema>
26+
</types>
27+
</definitions>
28+
XML;
29+
30+
$xsd_with_wrong_ns = <<<XML
31+
<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd">
32+
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespacex" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en"/>
33+
XML;
34+
35+
$xsd_without_ns = <<<XML
36+
<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd">
37+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en"/>
38+
XML;
39+
40+
$combinations = [
41+
[$wsdl_with_ns, $xsd_with_wrong_ns],
42+
[$wsdl_with_ns, $xsd_without_ns],
43+
[$wsdl_without_ns, $xsd_with_wrong_ns],
44+
[$wsdl_without_ns, $xsd_without_ns],
45+
];
46+
47+
chdir(__DIR__);
48+
49+
foreach ($combinations as list($wsdl, $xsd)) {
50+
file_put_contents(__DIR__."/bug62900.wsdl", $wsdl);
51+
file_put_contents(__DIR__."/bug62900.xsd", $xsd);
52+
53+
$proc = proc_open([PHP_BINARY, __DIR__.'/bug62900_run'], [1 => ["pipe", "w"]], $pipes);
54+
echo stream_get_contents($pipes[1]);
55+
fclose($pipes[1]);
56+
proc_close($proc);
57+
}
58+
59+
?>
60+
--CLEAN--
61+
<?php
62+
@unlink(__DIR__."/bug62900.wsdl");
63+
@unlink(__DIR__."/bug62900.xsd");
64+
?>
65+
--EXPECTF--
66+
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing Schema: can't import schema from '%sbug62900.xsd', unexpected 'targetNamespace'='http://www.w3.org/XML/1998/namespacex', expected 'http://www.w3.org/XML/1998/namespace' in %s:%d
67+
Stack trace:
68+
#0 %s(%d): SoapClient->__construct(%s)
69+
#1 {main}
70+
thrown in %s on line %d
71+
72+
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing Schema: can't import schema from '%sbug62900.xsd', missing 'targetNamespace', expected 'http://www.w3.org/XML/1998/namespace' in %s:%d
73+
Stack trace:
74+
#0 %s(%d): SoapClient->__construct(%s)
75+
#1 {main}
76+
thrown in %s on line %d
77+
78+
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing Schema: can't import schema from '%sbug62900.xsd', unexpected 'targetNamespace'='http://www.w3.org/XML/1998/namespacex', expected no 'targetNamespace' in %s:%d
79+
Stack trace:
80+
#0 %s(%d): SoapClient->__construct(%s)
81+
#1 {main}
82+
thrown in %s on line %d
83+
84+
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't bind to service in %s:%d
85+
Stack trace:
86+
#0 %s(%d): SoapClient->__construct(%s)
87+
#1 {main}
88+
thrown in %s on line %d

ext/soap/tests/bugs/bug62900_run

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
new SoapClient(__DIR__."/bug62900.wsdl");

0 commit comments

Comments
 (0)