Skip to content

Commit b7169a2

Browse files
authored
ext/soap: Don't call readfile() userland function (#17432)
* ext/soap: Add some SoapServer tests * ext/soap: Don't call readfile() userland function We can perform the operation directly, moreover there is no risk of a user disabling the readfile function and defining their own messing up what we are doing. * ext/soap: Actually throw a SOAP Fault if the WSDL has disappeared
1 parent 7512685 commit b7169a2

File tree

3 files changed

+179
-8
lines changed

3 files changed

+179
-8
lines changed

ext/soap/soap.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,19 +1307,17 @@ PHP_METHOD(SoapServer, handle)
13071307
sapi_add_header(hdr, sizeof("Location: ")+strlen(service->sdl->source)-1, 1);
13081308
efree(hdr);
13091309
*/
1310-
zval readfile, readfile_ret, param;
13111310

13121311
sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
1313-
ZVAL_STRING(&param, service->sdl->source);
1314-
ZVAL_STRING(&readfile, "readfile");
1315-
if (call_user_function(EG(function_table), NULL, &readfile, &readfile_ret, 1, &param ) == FAILURE) {
1312+
php_stream_context *context = php_stream_context_from_zval(NULL, false);
1313+
php_stream *stream = php_stream_open_wrapper_ex(service->sdl->source, "rb", REPORT_ERRORS, NULL, context);
1314+
if (stream) {
1315+
php_stream_passthru(stream);
1316+
php_stream_close(stream);
1317+
} else {
13161318
soap_server_fault("Server", "Couldn't find WSDL", NULL, NULL, NULL);
13171319
}
13181320

1319-
zval_ptr_dtor(&param);
1320-
zval_ptr_dtor_str(&readfile);
1321-
zval_ptr_dtor(&readfile_ret);
1322-
13231321
SOAP_SERVER_END_CODE();
13241322
return;
13251323
} else {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
--TEST--
2+
SoapServer handle with WSDL that has disappeared
3+
--EXTENSIONS--
4+
soap
5+
--SKIPIF--
6+
<?php
7+
if (PHP_OS_FAMILY === "Windows") {
8+
die("skip see https://github.com/php/php-src/issues/17468");
9+
}
10+
?>
11+
--GET--
12+
WSDL
13+
--FILE--
14+
<?php
15+
$wsdlFile = __DIR__ . '/test_handle_non_existent_wsdl_from_get_query.wsdl';
16+
17+
$wsdl = <<<'WSDL'
18+
<?xml version="1.0" ?>
19+
<definitions
20+
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
21+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
22+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
23+
xmlns="http://schemas.xmlsoap.org/wsdl/">
24+
25+
<types>
26+
<xsd:schema targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
27+
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
28+
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
29+
</xsd:schema>
30+
</types>
31+
32+
<message name="AddRequest">
33+
<part name="x" type="xsd:double" />
34+
<part name="y" type="xsd:double" />
35+
</message>
36+
<message name="AddResponse">
37+
<part name="result" type="xsd:double" />
38+
</message>
39+
40+
<portType name="TestServicePortType">
41+
<operation name="Add">
42+
<input message="tns:AddRequest" />
43+
<output message="tns:AddResponse" />
44+
</operation>
45+
</portType>
46+
47+
<binding name="TestServiceBinding" type="tns:TestServicePortType">
48+
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
49+
<operation name="Add">
50+
<soap:operation soapAction="Add" style="rpc" />
51+
<input>
52+
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
53+
</input>
54+
<output>
55+
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
56+
</output>
57+
</operation>
58+
</binding>
59+
60+
<service name="TestService">
61+
<port name="TestServicePort" binding="tns:TestServiceBinding">
62+
<soap:address location="http://linuxsrv.home/~dmitry/soap/soap_server.php" />
63+
</port>
64+
</service>
65+
66+
</definitions>
67+
WSDL;
68+
69+
file_put_contents($wsdlFile, $wsdl);
70+
71+
$options = [];
72+
$server = new SoapServer($wsdlFile, $options);
73+
74+
unlink($wsdlFile);
75+
76+
$server->handle();
77+
78+
?>
79+
--CLEAN--
80+
<?php
81+
$wsdlFile = __DIR__ . '/test_handle_non_existent_wsdl_from_get_query.wsdl';
82+
@unlink($wsdlFile);
83+
?>
84+
--EXPECT--
85+
<?xml version="1.0" encoding="UTF-8"?>
86+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Couldn't find WSDL</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
--TEST--
2+
SoapServer handle with WSDL that has disappeared and disabled readfile function
3+
--EXTENSIONS--
4+
soap
5+
--SKIPIF--
6+
<?php
7+
if (PHP_OS_FAMILY === "Windows") {
8+
die("skip see https://github.com/php/php-src/issues/17468");
9+
}
10+
?>
11+
--GET--
12+
WSDL
13+
--INI--
14+
disable_functions=readfile
15+
--FILE--
16+
<?php
17+
$wsdlFile = __DIR__ . '/test_handle_non_existent_wsdl_from_get_query_disable_readfile.wsdl';
18+
19+
$wsdl = <<<'WSDL'
20+
<?xml version="1.0" ?>
21+
<definitions
22+
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
23+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
24+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
25+
xmlns="http://schemas.xmlsoap.org/wsdl/">
26+
27+
<types>
28+
<xsd:schema targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
29+
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
30+
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
31+
</xsd:schema>
32+
</types>
33+
34+
<message name="AddRequest">
35+
<part name="x" type="xsd:double" />
36+
<part name="y" type="xsd:double" />
37+
</message>
38+
<message name="AddResponse">
39+
<part name="result" type="xsd:double" />
40+
</message>
41+
42+
<portType name="TestServicePortType">
43+
<operation name="Add">
44+
<input message="tns:AddRequest" />
45+
<output message="tns:AddResponse" />
46+
</operation>
47+
</portType>
48+
49+
<binding name="TestServiceBinding" type="tns:TestServicePortType">
50+
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
51+
<operation name="Add">
52+
<soap:operation soapAction="Add" style="rpc" />
53+
<input>
54+
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
55+
</input>
56+
<output>
57+
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
58+
</output>
59+
</operation>
60+
</binding>
61+
62+
<service name="TestService">
63+
<port name="TestServicePort" binding="tns:TestServiceBinding">
64+
<soap:address location="http://linuxsrv.home/~dmitry/soap/soap_server.php" />
65+
</port>
66+
</service>
67+
68+
</definitions>
69+
WSDL;
70+
71+
file_put_contents($wsdlFile, $wsdl);
72+
73+
$options = [];
74+
$server = new SoapServer($wsdlFile, $options);
75+
76+
unlink($wsdlFile);
77+
$server->handle();
78+
79+
?>
80+
--CLEAN--
81+
<?php
82+
$wsdlFile = __DIR__ . '/test_handle_non_existent_wsdl_from_get_query_disable_readfile.wsdl';
83+
@unlink($wsdlFile);
84+
?>
85+
--EXPECT--
86+
<?xml version="1.0" encoding="UTF-8"?>
87+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Couldn't find WSDL</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

0 commit comments

Comments
 (0)