From: Dmitry Stogov Date: Tue, 3 Oct 2006 07:00:35 +0000 (+0000) Subject: Fixed possible crash with default namespaces X-Git-Tag: php-5.2.0RC5~40 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=99356595df98edac0bcb45c9168ca94d481c585a;p=php Fixed possible crash with default namespaces --- diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index b0ecba3467..6b41b61482 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -3035,6 +3035,43 @@ static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type) smart_str_free(&nstype); } +static xmlNsPtr xmlSearchNsPrefixByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href) +{ + xmlNsPtr cur; + xmlNodePtr orig = node; + + while (node) { + if (node->type == XML_ENTITY_REF_NODE || + node->type == XML_ENTITY_NODE || + node->type == XML_ENTITY_DECL) { + return NULL; + } + if (node->type == XML_ELEMENT_NODE) { + cur = node->nsDef; + while (cur != NULL) { + if (cur->prefix && cur->href && xmlStrEqual(cur->href, href)) { + if (xmlSearchNs(doc, node, cur->prefix) == cur) { + return cur; + } + } + cur = cur->next; + } + if (orig != node) { + cur = node->ns; + if (cur != NULL) { + if (cur->prefix && cur->href && xmlStrEqual(cur->href, href)) { + if (xmlSearchNs(doc, node, cur->prefix) == cur) { + return cur; + } + } + } + } + } + node = node->parent; + } + return NULL; +} + xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns) { xmlNsPtr xmlns; @@ -3044,6 +3081,9 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns) } xmlns = xmlSearchNsByHref(node->doc, node, BAD_CAST(ns)); + if (xmlns != NULL && xmlns->prefix == NULL) { + xmlns = xmlSearchNsPrefixByHref(node->doc, node, BAD_CAST(ns)); + } if (xmlns == NULL) { xmlChar* prefix; TSRMLS_FETCH(); @@ -3054,9 +3094,19 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns) smart_str prefix = {0}; int num = ++SOAP_GLOBAL(cur_uniq_ns); - smart_str_appendl(&prefix, "ns", 2); - smart_str_append_long(&prefix, num); - smart_str_0(&prefix); + while (1) { + smart_str_appendl(&prefix, "ns", 2); + smart_str_append_long(&prefix, num); + smart_str_0(&prefix); + if (xmlSearchNs(node->doc, node, BAD_CAST(prefix.c)) == NULL) { + break; + } + smart_str_free(&prefix); + prefix.c = NULL; + prefix.len = 0; + num = ++SOAP_GLOBAL(cur_uniq_ns); + } + xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), BAD_CAST(prefix.c)); smart_str_free(&prefix); } diff --git a/ext/soap/tests/typemap013.phpt b/ext/soap/tests/typemap013.phpt new file mode 100755 index 0000000000..99003c8dc1 --- /dev/null +++ b/ext/soap/tests/typemap013.phpt @@ -0,0 +1,56 @@ +--TEST-- +SOAP typemap 13: SoapServer support for typemap's to_xml() with default ns +--SKIPIF-- + +--FILE-- + + + +??? + + + +"; + +function book_to_xml($book) { + return ''.$book->a.'!'.$book->b.'!'; +} + +class test{ + function dotest2($str){ + $book = new book; + $book->a = "foo"; + $book->b = "bar"; + return $book; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} + +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "to_xml" => "book_to_xml")) + ); + +$server = new SoapServer(dirname(__FILE__)."/classmap.wsdl",$options); +$server->setClass("test"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +foo!bar! +ok