]> granicus.if.org Git - php/commitdiff
Fixed possible crash with default namespaces
authorDmitry Stogov <dmitry@php.net>
Tue, 3 Oct 2006 07:00:35 +0000 (07:00 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 3 Oct 2006 07:00:35 +0000 (07:00 +0000)
ext/soap/php_encoding.c
ext/soap/tests/typemap013.phpt [new file with mode: 0755]

index b0ecba34676de23d91f67162e610926fe787557b..6b41b61482ad44bc9ecf680d5e1c74ed60ebb15c 100644 (file)
@@ -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 (executable)
index 0000000..99003c8
--- /dev/null
@@ -0,0 +1,56 @@
+--TEST--
+SOAP typemap 13: SoapServer support for typemap's to_xml() with default ns
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$GLOBALS['HTTP_RAW_POST_DATA']="
+<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" 
+       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
+       xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" 
+       xmlns:enc=\"http://schemas.xmlsoap.org/soap/encoding/\"
+       xmlns:ns1=\"http://schemas.nothing.com\"
+>
+  <env:Body>
+<ns1:dotest2>
+<dotest2 xsi:type=\"xsd:string\">???</dotest2>
+</ns1:dotest2>
+ </env:Body>
+<env:Header/>
+</env:Envelope>";      
+
+function book_to_xml($book) {
+       return '<book xmlns="http://schemas.nothing.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><a xsi:type="xsd:string">'.$book->a.'!</a><b xsi:type="xsd:string">'.$book->b.'!</b></book>';
+}
+
+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--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.nothing.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:dotest2Response><book xmlns="http://schemas.nothing.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns1:book"><a xsi:type="xsd:string">foo!</a><b xsi:type="xsd:string">bar!</b></book></ns1:dotest2Response></SOAP-ENV:Body></SOAP-ENV:Envelope>
+ok