diff --git a/NEWS b/NEWS
index f9e6193c701..a695fb6e8e4 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ PHP NEWS
- Added tidyNode::getParent() method (John, Nuno)
- Fixed zend_llist_remove_tail (Michael Wallner, Dmitry)
- Fixed bug #40621 (Crash when constructor called inappropriately). (Tony)
+- Fixed bug #40609 (Segfaults when using more than one SoapVar in a request).
+ (Rob, Dmitry)
- Fixed bug #40606 (umask is not being restored when request is finished).
(Tony)
- Fixed bug #40598 (libxml segfault). (Rob)
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index f86b9d6045e..53b7fa1f3f6 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -2888,8 +2888,18 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP
ret = xmlNewTextLen(BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp));
zval_dtor(&tmp);
}
+
ret->name = xmlStringTextNoenc;
- xmlAddChild(parent, ret);
+ ret->parent = parent;
+ ret->doc = parent->doc;
+ ret->prev = parent->last;
+ ret->next = NULL;
+ if (parent->last) {
+ parent->last->next = ret;
+ } else {
+ parent->children = ret;
+ }
+ parent->last = ret;
return ret;
}
diff --git a/ext/soap/tests/bugs/bug40609.phpt b/ext/soap/tests/bugs/bug40609.phpt
new file mode 100755
index 00000000000..b6349c21f32
--- /dev/null
+++ b/ext/soap/tests/bugs/bug40609.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #40609 (Segfaults when using more than one SoapVar in a request)
+--SKIPIF--
+
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+ 1,' exceptions' => 0));
+
+$c->update(array('symbol' => new SoapVar("MSFT", XSD_ANYXML),
+ 'price' => new SoapVar("1000", XSD_ANYXML)));
+echo $c->__getLastRequest();
+echo "ok\n";
+?>
+--EXPECT--
+
+MSFT1000
+ok
diff --git a/ext/soap/tests/bugs/bug40609.wsdl b/ext/soap/tests/bugs/bug40609.wsdl
new file mode 100755
index 00000000000..d396d06f32b
--- /dev/null
+++ b/ext/soap/tests/bugs/bug40609.wsdl
@@ -0,0 +1,26 @@
+
+ Stock Quote Service
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file