From d613c0ed3018bd381662381c048c6b7cd95e2ee8 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 14 Oct 2024 19:20:52 +0200 Subject: [PATCH] Fix GH-16429: Segmentation fault (access null pointer) in SoapClient If get_iterator() fails, we should not destroy the object. Also changes the check to a NULL check to be more defensive, and to match the VM. Closes GH-16441. --- NEWS | 4 ++++ ext/soap/php_encoding.c | 5 +++-- ext/soap/tests/bugs/gh16429.phpt | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 ext/soap/tests/bugs/gh16429.phpt diff --git a/NEWS b/NEWS index b4671fe528d..f54be6afc45 100644 --- a/NEWS +++ b/NEWS @@ -55,6 +55,10 @@ PHP NEWS . Fixed bug GH-16290 (overflow on cookie_lifetime ini value). (David Carlier) +- SOAP: + . Fixed bug GH-16429 (Segmentation fault access null pointer in SoapClient). + (nielsdos) + - Sockets: . Fixed bug with overflow socket_recvfrom $length argument. (David Carlier) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 29cf8fbc908..39cecf9848d 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -2210,8 +2210,8 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod iter = ce->get_iterator(ce, data, 0); - if (EG(exception)) { - goto iterator_done; + if (!iter) { + goto iterator_failed_to_get; } if (iter->funcs->rewind) { @@ -2251,6 +2251,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod } iterator_done: OBJ_RELEASE(&iter->std); +iterator_failed_to_get: if (EG(exception)) { zval_ptr_dtor(&array_copy); ZVAL_UNDEF(&array_copy); diff --git a/ext/soap/tests/bugs/gh16429.phpt b/ext/soap/tests/bugs/gh16429.phpt new file mode 100644 index 00000000000..24d517f96b9 --- /dev/null +++ b/ext/soap/tests/bugs/gh16429.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-16429 (Segmentation fault (access null pointer) in SoapClient) +--EXTENSIONS-- +soap +--FILE-- +send(10); +$fusion = $gen; +$client = new SoapClient(__DIR__."/../interop/Round2/GroupB/round2_groupB.wsdl",array("trace"=>1,"exceptions"=>0)); +try { + $client->echo2DStringArray($fusion); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +string(10) "xxxxxxxxxx" +Cannot traverse an already closed generator