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