dmitry          Tue Dec  7 12:29:42 2004 EDT

  Modified files:              
    /php-src/ext/soap   php_encoding.c 
    /php-src/ext/soap/tests/bugs        bug30928.phpt bug30928.wsdl 
  Log:
  Fixed bug #30928 (When Using WSDL, SoapServer doesn't handle private or 
protected properties)
  
  
http://cvs.php.net/diff.php/php-src/ext/soap/php_encoding.c?r1=1.84&r2=1.85&ty=u
Index: php-src/ext/soap/php_encoding.c
diff -u php-src/ext/soap/php_encoding.c:1.84 
php-src/ext/soap/php_encoding.c:1.85
--- php-src/ext/soap/php_encoding.c:1.84        Tue Nov 16 08:51:09 2004
+++ php-src/ext/soap/php_encoding.c     Tue Dec  7 12:29:42 2004
@@ -17,7 +17,7 @@
   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
   +----------------------------------------------------------------------+
 */
-/* $Id: php_encoding.c,v 1.84 2004/11/16 13:51:09 dmitry Exp $ */
+/* $Id: php_encoding.c,v 1.85 2004/12/07 17:29:42 dmitry Exp $ */
 
 #include <time.h>
 
@@ -864,6 +864,45 @@
        return ret;
 }
 
+static void set_zval_property(zval* object, char* name, zval* val TSRMLS_DC)
+{
+       zend_class_entry *old_scope;
+
+       old_scope = EG(scope);
+       EG(scope) = Z_OBJCE_P(object);
+#ifdef ZEND_ENGINE_2
+       val->refcount--;
+#endif
+       add_property_zval(object, name, val);
+       EG(scope) = old_scope;
+}
+
+static zval* get_zval_property(zval* object, char* name TSRMLS_DC)
+{
+       if (Z_TYPE_P(object) == IS_OBJECT) {
+               zval member;
+               zval *data;
+               zend_class_entry *old_scope;
+
+               ZVAL_STRING(&member, name, 0);
+               old_scope = EG(scope);
+         EG(scope) = Z_OBJCE_P(object);
+               data = Z_OBJ_HT_P(object)->read_property(object, &member, 
BP_VAR_IS TSRMLS_CC);
+               EG(scope) = old_scope;
+               if (data == EG(uninitialized_zval_ptr)) {
+                       return NULL;
+               }
+               return data;
+       } else if (Z_TYPE_P(object) == IS_ARRAY) {
+               zval **data_ptr;
+
+               if (zend_hash_find(Z_ARRVAL_P(object), name, strlen(name)+1, 
(void**)&data_ptr) == SUCCESS) {
+                 return *data_ptr;
+               }
+       }
+  return NULL;
+}
+
 static void model_to_zval_object(zval *ret, sdlContentModelPtr model, 
xmlNodePtr data, sdlPtr sdl TSRMLS_DC)
 {
        switch (model->kind) {
@@ -920,10 +959,7 @@
                                                } while ((node = 
get_node(node->next, model->u.element->name)) != NULL);
                                                val = array;
                                        }
-#ifdef ZEND_ENGINE_2
-                                       val->refcount--;
-#endif
-                                       add_property_zval(ret, 
model->u.element->name, val);
+                                       set_zval_property(ret, 
model->u.element->name, val TSRMLS_CC);
                                }
                        }
                        break;
@@ -965,7 +1001,7 @@
                if (zend_hash_find(SOAP_GLOBAL(class_map), type->type_str, 
strlen(type->type_str)+1, (void**)&classname) == SUCCESS &&
                    Z_TYPE_PP(classname) == IS_STRING &&
                    (tmp = zend_fetch_class(Z_STRVAL_PP(classname), 
Z_STRLEN_PP(classname), ZEND_FETCH_CLASS_AUTO TSRMLS_CC)) != NULL) {
-                       ce = tmp; 
+                       ce = tmp;
                }
        }
        sdl = SOAP_GLOBAL(sdl);
@@ -988,10 +1024,7 @@
 
                                object_init_ex(ret, ce);
                                base = master_to_zval_int(enc, data);
-#ifdef ZEND_ENGINE_2
-                               base->refcount--;
-#endif
-                               add_property_zval(ret, "_", base);
+                               set_zval_property(ret, "_", base TSRMLS_CC);
                        } else {
                                MAKE_STD_ZVAL(ret);
                                FIND_XML_NULL(data, ret);
@@ -1013,10 +1046,7 @@
 
                                object_init_ex(ret, ce);
                                base = master_to_zval_int(sdlType->encode, 
data);
-#ifdef ZEND_ENGINE_2
-                               base->refcount--;
-#endif
-                               add_property_zval(ret, "_", base);
+                               set_zval_property(ret, "_", base TSRMLS_CC);
                        }
                } else {
                        MAKE_STD_ZVAL(ret);
@@ -1054,10 +1084,7 @@
                                                xmlNodeSetContent(dummy, 
str_val);
                                                data = 
master_to_zval((*attr)->encode, dummy);
                                                xmlFreeNode(dummy);
-#ifdef ZEND_ENGINE_2
-                                               data->refcount--;
-#endif
-                                               add_property_zval(ret, 
(*attr)->name, data);
+                                               set_zval_property(ret, 
(*attr)->name, data TSRMLS_CC);
                                        }
                                }
                                zend_hash_move_forward_ex(sdlType->attributes, 
&pos);
@@ -1074,30 +1101,28 @@
                while (trav != NULL) {
                        if (trav->type == XML_ELEMENT_NODE) {
                                zval  *tmpVal;
-                               zval **prop;
-                               int    key_len;
+                               zval *prop;
 
                                tmpVal = master_to_zval(NULL, trav);
-                               key_len = strlen(trav->name) + 1;
 
-                               if (zend_hash_find(Z_OBJPROP_P(ret), 
(char*)trav->name, key_len, (void **) &prop) == FAILURE) {
-#ifdef ZEND_ENGINE_2
-                                       tmpVal->refcount--;
-#endif
-                                       add_property_zval_ex(ret, 
(char*)trav->name, key_len, tmpVal TSRMLS_CC);
+                               prop = get_zval_property(ret, (char*)trav->name 
TSRMLS_CC);
+                               if (!prop) {
+          set_zval_property(ret, (char*)trav->name, tmpVal TSRMLS_CC);
                                } else {
                                  /* Property already exist - make array */
-                                 if (Z_TYPE_PP(prop) != IS_ARRAY) {
+                                 if (Z_TYPE_P(prop) != IS_ARRAY) {
                                    /* Convert into array */
                                    zval *arr;
 
                                    MAKE_STD_ZVAL(arr);
                                    array_init(arr);
-                                         add_next_index_zval(arr, *prop);
-                                         *prop = arr;
+                                   prop->refcount++;
+                                         add_next_index_zval(arr, prop);
+                 set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC);
+                                         prop = arr;
                                  }
                                  /* Add array element */
-                                 add_next_index_zval(*prop, tmpVal);
+                                 add_next_index_zval(prop, tmpVal);
                                }
                        }
                        trav = trav->next;
@@ -1106,18 +1131,19 @@
        return ret;
 }
 
-static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, 
HashTable *prop, int style, int strict)
+static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval 
*object, int style, int strict TSRMLS_DC)
 {
        switch (model->kind) {
                case XSD_CONTENT_ELEMENT: {
-                       zval **data;
+                       zval *data;
                        xmlNodePtr property;
                        encodePtr enc;
 
-                       if (zend_hash_find(prop, model->u.element->name, 
strlen(model->u.element->name)+1, (void**)&data) == SUCCESS) {
+                       data = get_zval_property(object, model->u.element->name 
TSRMLS_CC);
+                       if (data) {
                                enc = model->u.element->encode;
-                               if ((model->max_occurs == -1 || 
model->max_occurs > 1) && Z_TYPE_PP(data) == IS_ARRAY) {
-                                       HashTable *ht = Z_ARRVAL_PP(data);
+                               if ((model->max_occurs == -1 || 
model->max_occurs > 1) && Z_TYPE_P(data) == IS_ARRAY) {
+                                       HashTable *ht = Z_ARRVAL_P(data);
                                        zval **val;
 
                                        zend_hash_internal_pointer_reset(ht);
@@ -1146,7 +1172,7 @@
                                                zend_hash_move_forward(ht);
                                        }
                                } else {
-                                       if (Z_TYPE_PP(data) == IS_NULL && 
model->u.element->nillable) {
+                                       if (Z_TYPE_P(data) == IS_NULL && 
model->u.element->nillable) {
                                                property = 
xmlNewNode(NULL,"BOGUS");
                                                xmlAddChild(node, property);
                                                if (style == SOAP_ENCODED) {
@@ -1156,7 +1182,7 @@
                                                        xmlSetNsProp(property, 
xsi, "nil", "1");
                                                }
                                        } else {
-                                               property = master_to_xml(enc, 
*data, style, node);
+                                               property = master_to_xml(enc, 
data, style, node);
                                                if (property->children && 
property->children->content &&
                                                    model->u.element->fixed && 
strcmp(model->u.element->fixed,property->children->content) != 0) {
                                                        soap_error3(E_ERROR, 
"Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", 
model->u.element->name, model->u.element->fixed, property->children->content);
@@ -1186,7 +1212,7 @@
 
                        zend_hash_internal_pointer_reset_ex(model->u.content, 
&pos);
                        while (zend_hash_get_current_data_ex(model->u.content, 
(void**)&tmp, &pos) == SUCCESS) {
-                               if (!model_to_xml_object(node, *tmp, prop, 
style, model->min_occurs > 0)) {
+                               if (!model_to_xml_object(node, *tmp, object, 
style, model->min_occurs > 0 TSRMLS_CC)) {
                                        return 0;
                                }
                                zend_hash_move_forward_ex(model->u.content, 
&pos);
@@ -1200,7 +1226,7 @@
 
                        zend_hash_internal_pointer_reset_ex(model->u.content, 
&pos);
                        while (zend_hash_get_current_data_ex(model->u.content, 
(void**)&tmp, &pos) == SUCCESS) {
-                               int tmp_ret = model_to_xml_object(node, *tmp, 
prop, style, 0);
+                               int tmp_ret = model_to_xml_object(node, *tmp, 
object, style, 0 TSRMLS_CC);
                                if (tmp_ret == 1) {
                                        return 1;
                                } else if (tmp_ret != 0) {
@@ -1211,7 +1237,7 @@
                        return ret;
                }
                case XSD_CONTENT_GROUP: {
-                       return model_to_xml_object(node, model->u.group->model, 
prop, style, model->min_occurs > 0);
+                       return model_to_xml_object(node, model->u.group->model, 
object, style, model->min_occurs > 0 TSRMLS_CC);
                }
                default:
                  break;
@@ -1287,9 +1313,9 @@
                                enc = enc->details.sdl_type->encode;
                        }
                        if (enc) {
-                               zval **tmp;
-                               if (prop && zend_hash_find(prop, "_", 
sizeof("_"), (void**)&tmp) == SUCCESS) {
-                                       xmlParam = master_to_xml(enc, *tmp, 
style, parent);
+                               zval *tmp = get_zval_property(data, "_" 
TSRMLS_CC);
+                               if (tmp) {
+                                       xmlParam = master_to_xml(enc, tmp, 
style, parent);
                                } else if (prop == NULL) {
                                        xmlParam = master_to_xml(enc, data, 
style, parent);
                                } else {
@@ -1308,10 +1334,10 @@
                            sdlType->encode->details.sdl_type->kind != 
XSD_TYPEKIND_UNION) {
                                xmlParam = master_to_xml(sdlType->encode, data, 
style, parent);
                        } else {
-                               zval **tmp;
+                               zval *tmp = get_zval_property(data, "_" 
TSRMLS_CC);
 
-                               if (prop && zend_hash_find(prop, "_", 
sizeof("_"), (void**)&tmp) == SUCCESS) {
-                                       xmlParam = 
master_to_xml(sdlType->encode, *tmp, style, parent);
+                               if (tmp) {
+                                       xmlParam = 
master_to_xml(sdlType->encode, tmp, style, parent);
                                } else if (prop == NULL) {
                                        xmlParam = 
master_to_xml(sdlType->encode, data, style, parent);
                                } else {
@@ -1358,25 +1384,26 @@
                                        zend_hash_move_forward(prop);
                                }
                        } else if (sdlType->model) {
-                               model_to_xml_object(xmlParam, sdlType->model, 
prop, style, 1);
+                               model_to_xml_object(xmlParam, sdlType->model, 
data, style, 1 TSRMLS_CC);
                        }
                        if (sdlType->attributes) {
                                sdlAttributePtr *attr;
-                               zval **data;
+                               zval *zattr;
                                HashPosition pos;
 
                                
zend_hash_internal_pointer_reset_ex(sdlType->attributes, &pos);
                                while 
(zend_hash_get_current_data_ex(sdlType->attributes, (void**)&attr, &pos) == 
SUCCESS) {
                                        if ((*attr)->name) {
-                                               if (zend_hash_find(prop, 
(*attr)->name, strlen((*attr)->name)+1, (void**)&data) == SUCCESS) {
+                                               zattr = get_zval_property(data, 
(*attr)->name TSRMLS_CC);
+                                               if (zattr) {
                                                        xmlNodePtr dummy;
 
-                                                       dummy = 
master_to_xml((*attr)->encode, *data, SOAP_LITERAL, xmlParam);
+                                                       dummy = 
master_to_xml((*attr)->encode, zattr, SOAP_LITERAL, xmlParam);
                                                        if (dummy->children && 
dummy->children->content) {
                                                                if 
((*attr)->fixed && strcmp((*attr)->fixed,dummy->children->content) != 0) {
                                                                        
soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' 
is not allowed)", (*attr)->name, (*attr)->fixed, dummy->children->content);
                                                                }
-                                                               if 
((*attr)->namens && 
+                                                               if 
((*attr)->namens &&
                                                                    (type->ns 
== NULL || strcmp((*attr)->namens, type->ns))) {
                                                                        
xmlNsPtr nsp = encode_add_ns(xmlParam, (*attr)->namens);
 
http://cvs.php.net/diff.php/php-src/ext/soap/tests/bugs/bug30928.phpt?r1=1.1&r2=1.2&ty=u
Index: php-src/ext/soap/tests/bugs/bug30928.phpt
diff -u /dev/null php-src/ext/soap/tests/bugs/bug30928.phpt:1.2
--- /dev/null   Tue Dec  7 12:29:42 2004
+++ php-src/ext/soap/tests/bugs/bug30928.phpt   Tue Dec  7 12:29:42 2004
@@ -0,0 +1,63 @@
+--TEST--
+Bug #30928 When Using WSDL, SoapServer doesn't handle private or protected 
properties 
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ini_set("soap.wsdl_cache_enabled", 0);
+
+class foo {
+       public    $a="a";
+       private   $b="b";
+       protected $c="c";
+}
+
+function test($x) {
+  return $x;
+}
+
+class LocalSoapClient extends SoapClient {
+
+  function __construct($wsdl, $options) {
+    parent::__construct($wsdl, $options);
+    $this->server = new SoapServer($wsdl, $options);
+    $this->server->addFunction('test');
+  }
+
+  function __doRequest($request, $location, $action, $version) {
+    ob_start();
+    $this->server->handle($request);
+    $response = ob_get_contents();
+    ob_end_clean();
+    return $response;
+  }
+}
+
+$x = new LocalSoapClient(dirname(__FILE__)."/bug30928.wsdl", 
+                         array());
+var_dump($x->test(new foo()));
+
+$x = new LocalSoapClient(dirname(__FILE__)."/bug30928.wsdl", 
+                         array("classmap" => array('testType'=>'foo')));
+var_dump($x->test(new foo()));
+
+echo "ok\n";
+?>
+--EXPECTF--
+object(stdClass)#%d (3) {
+  ["a"]=>
+  string(1) "a"
+  ["b"]=>
+  string(1) "b"
+  ["c"]=>
+  string(1) "c"
+}
+object(foo)#%d (3) {
+  ["a"]=>
+  string(1) "a"
+  ["b:private"]=>
+  string(1) "b"
+  ["c:protected"]=>
+  string(1) "c"
+}
+ok
http://cvs.php.net/diff.php/php-src/ext/soap/tests/bugs/bug30928.wsdl?r1=1.1&r2=1.2&ty=u
Index: php-src/ext/soap/tests/bugs/bug30928.wsdl
diff -u /dev/null php-src/ext/soap/tests/bugs/bug30928.wsdl:1.2
--- /dev/null   Tue Dec  7 12:29:42 2004
+++ php-src/ext/soap/tests/bugs/bug30928.wsdl   Tue Dec  7 12:29:42 2004
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<definitions name="InteropTest"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/";
+    xmlns:tns="http://test-uri/";
+    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/";
+    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/";
+    xmlns="http://schemas.xmlsoap.org/wsdl/";
+    targetNamespace="http://test-uri/";>
+  <types>
+  <schema xmlns="http://www.w3.org/2001/XMLSchema"; 
targetNamespace="http://test-uri/";>
+   <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"; />
+   <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/"; />
+        <complexType name="testType">
+               <sequence>
+                       <element name="a" type="string"/>
+                       <element name="b" type="string"/>
+               </sequence>
+               <attribute name="c" type="string"/>
+        </complexType>
+  </schema>
+  </types>
+  <message name="testMessage">
+       <part name="testParam" type="tns:testType"/>
+  </message>
+       <portType name="testPortType">
+               <operation name="test">
+                       <input message="testMessage"/>
+                       <output message="testMessage"/>
+               </operation>
+       </portType>
+       <binding name="testBinding" type="testPortType">
+               <soap:binding style="rpc" 
transport="http://schemas.xmlsoap.org/soap/http"/>
+               <operation name="test">
+                       <soap:operation soapAction="#test" style="rpc"/>
+                       <input>
+                               <soap:body parts="body" use="encoded" 
namespace="http://test-uri/"; 
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+                       </input>
+                       <output>
+                               <soap:body parts="body" use="encoded" 
namespace="http://test-uri/"; 
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+                       </output>
+               </operation>
+       </binding>
+       <service name="testService">
+   <port name="testPort" binding="tns:testBinding">
+     <soap:address location="test://" /> 
+   </port>
+ </service>
+</definitions>

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to