diff --git a/NEWS b/NEWS
index eb3438006c0..781d72c42af 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,7 @@ PHP NEWS
- Fixed bug #32947 (Incorrect option for mysqli default password). (Georg)
- Fixed bug #32944 (Disabling session.use_cookies doesn't prevent reading
session cookies). (Jani, Tony)
+- Fixed bug #32941 (Sending structured SOAP fault kills a php). (Dmitry)
- Fixed bug #32936 (http redirects URLs are not checked for control chars). (Ilia)
- Fixed bug #32933 (Cannot extend class "SQLiteDatabase"). (Marcus)
- Fixed bug #32932 (Oracle LDAP: ldap_get_entries(), invalid pointer). (Jani)
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index b9027ddd4ea..a0b5f7aa91c 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -2297,6 +2297,9 @@ static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data)
if (tmpattr != NULL) {
type_name = tmpattr->children->content;
enc = get_encoder_from_prefix(SOAP_GLOBAL(sdl), data, tmpattr->children->content);
+ if (type == &enc->details) {
+ enc = NULL;
+ }
if (enc != NULL) {
encodePtr tmp = enc;
while (tmp &&
diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c
index b292a60862d..10119a45de3 100644
--- a/ext/soap/php_schema.c
+++ b/ext/soap/php_schema.c
@@ -88,20 +88,10 @@ static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns,
static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const char *type)
{
- encodePtr enc = NULL;
- smart_str nscat = {0};
-
- smart_str_appends(&nscat, ns);
- smart_str_appendc(&nscat, ':');
- smart_str_appends(&nscat, type);
- smart_str_0(&nscat);
-
- enc = get_encoder_ex(sdl, nscat.c, nscat.len);
+ encodePtr enc = get_encoder(sdl, ns, type);
if (enc == NULL) {
enc = create_encoder(sdl, cur_type, ns, type);
}
-
- smart_str_free(&nscat);
return enc;
}
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index ca71ce7ced1..25022c80ea3 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -50,21 +50,10 @@ encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const char *type)
parse_namespace(type, &cptype, &ns);
nsptr = xmlSearchNs(node->doc, node, ns);
if (nsptr != NULL) {
- int ns_len = strlen(nsptr->href);
- int type_len = strlen(cptype);
- int len = ns_len + type_len + 1;
- char *nscat = emalloc(len + 1);
-
- memcpy(nscat, nsptr->href, ns_len);
- nscat[ns_len] = ':';
- memcpy(nscat+ns_len+1, cptype, type_len);
- nscat[len] = '\0';
-
- enc = get_encoder_ex(sdl, nscat, len);
+ enc = get_encoder(sdl, nsptr->href, cptype);
if (enc == NULL) {
- enc = get_encoder_ex(sdl, type, type_len);
+ enc = get_encoder_ex(sdl, cptype, strlen(cptype));
}
- efree(nscat);
} else {
enc = get_encoder_ex(sdl, type, strlen(type));
}
@@ -128,8 +117,24 @@ encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
nscat[len] = '\0';
enc = get_encoder_ex(sdl, nscat, len);
-
efree(nscat);
+
+ if (enc == NULL &&
+ ((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
+ memcmp(ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
+ (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
+ memcmp(ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
+ ns_len = sizeof(XSD_NAMESPACE)-1;
+ len = ns_len + type_len + 1;
+ nscat = emalloc(len + 1);
+ memcpy(nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
+ nscat[ns_len] = ':';
+ memcpy(nscat+ns_len+1, type, type_len);
+ nscat[len] = '\0';
+
+ enc = get_encoder_ex(sdl, nscat, len);
+ efree(nscat);
+ }
return enc;
}
diff --git a/ext/soap/tests/bugs/bug32941.phpt b/ext/soap/tests/bugs/bug32941.phpt
new file mode 100755
index 00000000000..5fd17df18e0
--- /dev/null
+++ b/ext/soap/tests/bugs/bug32941.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #32941 (Sending structured exception kills a php)
+--SKIPIF--
+
+--FILE--
+
+
+
+
+ soapenv:Server.userException
+ service.EchoServiceException
+
+
+ 105
+ string param
+
+ steckovic
+
+
+
+
+EOF;
+ }
+}
+
+ini_set("soap.wsdl_cache_enabled", 1);
+$client = new TestSoapClient(dirname(__FILE__).'/bug32941.wsdl', array("trace" => 1, 'exceptions' => 0));
+$ahoj = $client->echoString('exception');
+$client = new TestSoapClient(dirname(__FILE__).'/bug32941.wsdl', array("trace" => 1, 'exceptions' => 0));
+$ahoj = $client->echoString('exception');
+echo "ok\n";
+?>
+--EXPECT--
+ok
diff --git a/ext/soap/tests/bugs/bug32941.wsdl b/ext/soap/tests/bugs/bug32941.wsdl
new file mode 100755
index 00000000000..61fd13dcbc8
--- /dev/null
+++ b/ext/soap/tests/bugs/bug32941.wsdl
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+