From: Dmitry Stogov Date: Tue, 3 Oct 2006 07:00:57 +0000 (+0000) Subject: Fixed possible crash with default namespaces X-Git-Tag: RELEASE_1_0_0RC1~1465 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0bc5b98d2e7867c85260509c9c6331754ba67a8c;p=php Fixed possible crash with default namespaces --- diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 4f8c53c08c..d5c2ee6840 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -3023,6 +3023,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; @@ -3032,6 +3069,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(); @@ -3042,9 +3082,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