From fb2788b86406813d5dd1c8b370d6dd551e88bf42 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 9 Nov 2026 06:41:52 +0000 Subject: [PATCH] ext/soap: integer-keyed 'any' element emitted as . Follow-up to GH-25267. An element at an integer key of 'any' content has no accessor name, and the fix only skipped the rename, leaking the encoder's BOGUS placeholder into the request. Raise an encoding error instead, unless the value names itself through SoapVar's nodeName or is raw XML. --- ext/soap/php_encoding.c | 13 +++++++++---- ext/soap/tests/gh25267.phpt | 18 ++++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 56317abf4ab7..976195605afe 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -3234,13 +3234,18 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP zval *el; encodePtr enc = get_conversion(XSD_ANYXML); zend_string *name; + zend_ulong idx; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(data), name, el) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), idx, name, el) { ret = master_to_xml(enc, el, style, parent); - if (ret && name && - ret->name != xmlStringTextNoenc) { + if (!ret || ret->name == xmlStringTextNoenc) { + continue; + } + if (name) { xmlNodeSetName(ret, BAD_CAST(ZSTR_VAL(name))); - } + } else if (ret->type == XML_ELEMENT_NODE && xmlStrEqual(ret->name, BAD_CAST("BOGUS"))) { + soap_error1(E_ERROR, "Encoding: Element at index " ZEND_ULONG_FMT " of 'any' content has no name", idx); + } } ZEND_HASH_FOREACH_END(); return ret; } diff --git a/ext/soap/tests/gh25267.phpt b/ext/soap/tests/gh25267.phpt index c67411828d18..e604d7393bc6 100644 --- a/ext/soap/tests/gh25267.phpt +++ b/ext/soap/tests/gh25267.phpt @@ -8,13 +8,23 @@ YuanchengJiang (.*)#', $request, $m); + echo $m[1], PHP_EOL; return ""; } } $c = new C(null, ["location" => "test://", "uri" => "test://"]); -$c->foo(new SoapVar([new SoapVar("y", XSD_STRING), "a" => new SoapVar("x", XSD_STRING)], XSD_ANYXML)); + +try { + $c->foo(new SoapVar([new SoapVar("y", XSD_STRING), "a" => new SoapVar("x", XSD_STRING)], XSD_ANYXML)); +} catch (SoapFault $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$c->foo(new SoapVar([new SoapVar("y", XSD_STRING, nodeName: "b"), "a" => new SoapVar("x", XSD_STRING)], XSD_ANYXML)); +$c->foo(new SoapVar(["y", "a" => new SoapVar("x", XSD_STRING)], XSD_ANYXML)); ?> --EXPECT-- - -yx +SoapFault: SOAP-ERROR: Encoding: Element at index 0 of 'any' content has no name +yx +yx