Skip to content

Commit c9862ba

Browse files
committed
Merge branch 'PHP-8.3'
* PHP-8.3: Fix bug #62900: Wrong namespace on xsd import error message
2 parents 3665ab0 + a0749bb commit c9862ba

File tree

4 files changed

+126
-3
lines changed

4 files changed

+126
-3
lines changed

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ PHP NEWS
55
- Opcache:
66
. Fixed bug GH-15657 (Segmentation fault in dasm_x86.h). (nielsdos)
77

8+
- SOAP:
9+
. Fixed bug #73182 (PHP SOAPClient does not support stream context HTTP
10+
headers in array form). (nielsdos)
11+
. Fixed bug #62900 (Wrong namespace on xsd import error message). (nielsdos)
12+
813
12 Sep 2024, PHP 8.4.0beta5
914

1015
- BCMath:

ext/soap/php_schema.c

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

ext/soap/tests/bugs/bug62900.phpt

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
$args = ["-d", "display_startup_errors=0", "-d", "extension_dir=" . ini_get("extension_dir"), "-d", "extension=" . (substr(PHP_OS, 0, 3) == "WIN" ? "php_" : "") . "soap." . PHP_SHLIB_SUFFIX];
50+
if (php_ini_loaded_file()) {
51+
// Necessary such that it works from a development directory in which case extension_dir might not be the real extension dir
52+
$args[] = "-c";
53+
$args[] = php_ini_loaded_file();
54+
}
55+
56+
foreach ($combinations as list($wsdl, $xsd)) {
57+
file_put_contents(__DIR__."/bug62900.wsdl", $wsdl);
58+
file_put_contents(__DIR__."/bug62900.xsd", $xsd);
59+
60+
$proc = proc_open([PHP_BINARY, ...$args, __DIR__.'/bug62900_run'], [1 => ["pipe", "w"], 2 => ["pipe", "w"]], $pipes);
61+
echo stream_get_contents($pipes[1]);
62+
fclose($pipes[1]);
63+
proc_close($proc);
64+
}
65+
66+
?>
67+
--CLEAN--
68+
<?php
69+
@unlink(__DIR__."/bug62900.wsdl");
70+
@unlink(__DIR__."/bug62900.xsd");
71+
?>
72+
--EXPECTF--
73+
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
74+
Stack trace:
75+
#0 %s(%d): SoapClient->__construct(%s)
76+
#1 {main}
77+
thrown in %s on line %d
78+
79+
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
80+
Stack trace:
81+
#0 %s(%d): SoapClient->__construct(%s)
82+
#1 {main}
83+
thrown in %s on line %d
84+
85+
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
86+
Stack trace:
87+
#0 %s(%d): SoapClient->__construct(%s)
88+
#1 {main}
89+
thrown in %s on line %d
90+
91+
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't bind to service in %s:%d
92+
Stack trace:
93+
#0 %s(%d): SoapClient->__construct(%s)
94+
#1 {main}
95+
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)