cvs: php-src /ext/soap php_encoding.c php_http.c php_soap.h soap.c /ext/soap/tests cookie.phpt /ext/soap/tests/bugs bug32941.phpt

From: Date: Tue, 01 Aug 2006 16:10:25 +0000
Subject: cvs: php-src /ext/soap php_encoding.c php_http.c php_soap.h soap.c /ext/soap/tests cookie.phpt /ext/soap/tests/bugs bug32941.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-39703@lists.php.net to get a copy of this message
dmitry Tue Aug 1 16:10:25 2006 UTC Added files: /php-src/ext/soap/tests cookie.phpt Modified files: /php-src/ext/soap php_encoding.c php_http.c php_soap.h soap.c /php-src/ext/soap/tests/bugs bug32941.phpt Log: Unicode support

http://cvs.php.net/viewvc.cgi/php-src/ext/soap/php_encoding.c?r1=1.139&r2=1.140&diff_format=u Index: php-src/ext/soap/php_encoding.c diff -u php-src/ext/soap/php_encoding.c:1.139 php-src/ext/soap/php_encoding.c:1.140 --- php-src/ext/soap/php_encoding.c:1.139 Thu Jul 27 15:23:04 2006 +++ php-src/ext/soap/php_encoding.c Tue Aug 1 16:10:25 2006 @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.c,v 1.139 2006/07/27 15:23:04 dmitry Exp $ */ +/* $Id: php_encoding.c,v 1.140 2006/08/01 16:10:25 dmitry Exp $ */ #include <time.h> @@ -284,26 +284,15 @@ encodePtr enc = NULL; HashTable *ht = Z_OBJPROP_P(data); char *stype_str = NULL, *ns_str = NULL; - int free_stype = 0, free_ns = 0; if (zend_hash_find(ht, "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) { soap_error0(E_ERROR, "Encoding: SoapVar hasn't 'enc_type' propery"); } if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) { - if (Z_TYPE_PP(zstype) == IS_STRING) { - stype_str = Z_STRVAL_PP(zstype); - } else if (Z_TYPE_PP(zstype) == IS_UNICODE) { - stype_str = soap_unicode_to_string(Z_USTRVAL_PP(zstype), Z_USTRLEN_PP(zstype) TSRMLS_CC); - free_stype = 1; - } + stype_str = soap_encode_string(*zstype, NULL TSRMLS_CC); if (stype_str && zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) { - if (Z_TYPE_PP(zns) == IS_STRING) { - ns_str = Z_STRVAL_PP(zns); - } else if (Z_TYPE_PP(zns) == IS_UNICODE) { - ns_str = soap_unicode_to_string(Z_USTRVAL_PP(zns), Z_USTRLEN_PP(zns) TSRMLS_CC); - free_ns = 1; - } + ns_str = soap_encode_string(*zns, NULL TSRMLS_CC); } } @@ -334,35 +323,26 @@ set_ns_and_type_ex(node, ns_str, stype_str); } } - - if (free_stype) { + + if (stype_str) { efree(stype_str); } - if (free_ns) { + if (ns_str) { efree(ns_str); } if (zend_hash_find(ht, "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) { - if (Z_TYPE_PP(zname) == IS_STRING) { - xmlNodeSetName(node, BAD_CAST(Z_STRVAL_PP(zname))); - } else if (Z_TYPE_PP(zname) == IS_UNICODE) { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(zname), Z_USTRLEN_PP(zname) TSRMLS_CC); + char *str = soap_encode_string(*zname, NULL TSRMLS_CC); - xmlNodeSetName(node, BAD_CAST(str)); - efree(str); - } + xmlNodeSetName(node, BAD_CAST(str)); + efree(str); } if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) { - if (Z_TYPE_PP(znamens) == IS_STRING) { - xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens)); - xmlSetNs(node, nsp); - } if (Z_TYPE_PP(znamens) == IS_UNICODE) { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(znamens), Z_USTRLEN_PP(znamens) TSRMLS_CC); - - xmlNsPtr nsp = encode_add_ns(node, str); - efree(str); - xmlSetNs(node, nsp); - } + char *str = soap_encode_string(*znamens, NULL TSRMLS_CC); + xmlNsPtr nsp = encode_add_ns(node, str); + + efree(str); + xmlSetNs(node, nsp); } } else { if (SOAP_GLOBAL(class_map) && data && @@ -392,9 +372,8 @@ if (utype == HASH_KEY_IS_STRING || utype == HASH_KEY_IS_UNICODE) { encodePtr enc; - if (utype == HASH_KEY_IS_UNICODE) { - type_name.s = soap_unicode_to_string(type_name.u, type_len TSRMLS_CC); - } + type_name.s = soap_encode_string_ex(utype, type_name, type_len TSRMLS_CC); + /* TODO: namespace isn't stored */ enc = get_encoder(SOAP_GLOBAL(sdl), SOAP_GLOBAL(sdl)->target_ns, type_name.s); if (enc) { @@ -405,9 +384,7 @@ encode = enc; } } - if (utype == HASH_KEY_IS_UNICODE) { - efree(type_name.v); - } + efree(type_name.v); break; } } @@ -612,25 +589,7 @@ if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { TSRMLS_FETCH(); - if (UG(unicode)) { - /* TODO: unicode support */ - ZVAL_STRING(ret, (char*)data->children->content, 1); - zval_string_to_unicode_ex(ret, UG(utf8_conv) TSRMLS_CC); - } else if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content)); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } + soap_decode_string(ret, (char*)data->children->content TSRMLS_CC); } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { ZVAL_STRING(ret, (char*)data->children->content, 1); } else { @@ -652,25 +611,7 @@ TSRMLS_FETCH(); whiteSpace_replace(data->children->content); - if (UG(unicode)) { - /* TODO: unicode support */ - ZVAL_STRING(ret, (char*)data->children->content, 1); - zval_string_to_unicode_ex(ret, UG(utf8_conv) TSRMLS_CC); - } else if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content)); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } + soap_decode_string(ret, (char*)data->children->content TSRMLS_CC); } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { ZVAL_STRING(ret, (char*)data->children->content, 1); } else { @@ -692,25 +633,7 @@ TSRMLS_FETCH(); whiteSpace_collapse(data->children->content); - if (UG(unicode)) { - /* TODO: unicode support */ - ZVAL_STRING(ret, (char*)data->children->content, 1); - zval_string_to_unicode_ex(ret, UG(utf8_conv) TSRMLS_CC); - } else if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content)); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } + soap_decode_string(ret, (char*)data->children->content TSRMLS_CC); } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { ZVAL_STRING(ret, (char*)data->children->content, 1); } else { @@ -802,41 +725,7 @@ xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); - if (Z_TYPE_P(data) == IS_UNICODE) { - str = soap_unicode_to_string(Z_USTRVAL_P(data), Z_USTRLEN_P(data) TSRMLS_CC); - new_len = strlen(str); - } else { - if (Z_TYPE_P(data) == IS_STRING) { - str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data)); - new_len = Z_STRLEN_P(data); - } else { - zval tmp = *data; - - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); - new_len = Z_STRLEN(tmp); - zval_dtor(&tmp); - } - - if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(str, new_len); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncInFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - efree(str); - str = estrdup((char*)xmlBufferContent(out)); - new_len = n; - } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { - soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { - soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); - } - } + str = soap_encode_string(data, &new_len TSRMLS_CC); text = xmlNewTextLen(BAD_CAST(str), new_len); xmlAddChild(ret, text); efree(str); @@ -1836,9 +1725,7 @@ if (key_type != HASH_KEY_IS_LONG) { char *prop_name; - if (key_type == IS_UNICODE) { - key.s = soap_unicode_to_string(key.u, key_len TSRMLS_CC); - } + key.s = soap_encode_string_ex(key_type, key, key_len TSRMLS_CC); if (Z_TYPE_P(data) == IS_OBJECT) { char *class_name; @@ -1849,9 +1736,7 @@ if (prop_name) { xmlNodeSetName(property, BAD_CAST(prop_name)); } - if (key_type == IS_UNICODE) { - efree(key.v); - } + efree(key.s); } zend_hash_move_forward(prop); } @@ -2490,19 +2375,14 @@ key = xmlNewNode(NULL, BAD_CAST("key")); xmlAddChild(item,key); key_type = zend_hash_get_current_key_ex(data->value.ht, &key_val, &key_len, &int_val, FALSE, NULL); - if (key_type == HASH_KEY_IS_STRING) { - if (style == SOAP_ENCODED) { - set_xsi_type(key, "xsd:string"); - } - xmlNodeSetContent(key, BAD_CAST(key_val.s)); - } else if (key_type == HASH_KEY_IS_UNICODE) { + if (key_type == HASH_KEY_IS_STRING || key_type == HASH_KEY_IS_UNICODE) { char *str; TSRMLS_FETCH(); if (style == SOAP_ENCODED) { set_xsi_type(key, "xsd:string"); } - str = soap_unicode_to_string(key_val.u, key_len TSRMLS_CC); + str = soap_encode_string_ex(key_type, key_val, key_len TSRMLS_CC); xmlNodeSetContent(key, BAD_CAST(str)); efree(str); } else { @@ -2610,9 +2490,9 @@ } else if (data->properties && get_attribute_ex(data->properties, "nil", XSI_NAMESPACE)) { enc = get_conversion(IS_NULL); } else { - tmpattr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE); + tmpattr = get_attribute_ex(data->properties, "type", XSI_NAMESPACE); if (tmpattr != NULL) { - type_name = tmpattr->children->content; + type_name = tmpattr->children->content; enc = get_encoder_from_prefix(SOAP_GLOBAL(sdl), data, tmpattr->children->content); if (enc && type == &enc->details) { enc = NULL; @@ -2669,12 +2549,12 @@ parse_namespace(type_name, &cptype, &ns); nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns)); MAKE_STD_ZVAL(tmp); - ZVAL_STRING(tmp, cptype, 1); + soap_decode_string(tmp, cptype TSRMLS_CC); tmp->refcount--; add_property_zval(soapvar, "enc_stype", tmp); if (nsptr) { MAKE_STD_ZVAL(tmp); - ZVAL_STRING(tmp, (char*)nsptr->href, 1); + soap_decode_string(tmp, (char*)nsptr->href TSRMLS_CC); tmp->refcount--; add_property_zval(soapvar, "enc_ns", tmp); } @@ -2737,13 +2617,11 @@ xmlNodeSetContent(xmlParam, BAD_CAST(buf)); efree(buf); - } else if (Z_TYPE_P(data) == IS_STRING) { - xmlNodeSetContentLen(xmlParam, BAD_CAST(Z_STRVAL_P(data)), Z_STRLEN_P(data)); - } else if (Z_TYPE_P(data) == IS_UNICODE) { + } else if (Z_TYPE_P(data) == IS_STRING || Z_TYPE_P(data) == IS_UNICODE) { char *str; TSRMLS_FETCH(); - str = soap_unicode_to_string(Z_USTRVAL_P(data), Z_USTRLEN_P(data) TSRMLS_CC); + str = soap_encode_string(data, NULL TSRMLS_CC); xmlNodeSetContent(xmlParam, BAD_CAST(str)); efree(str); } @@ -2915,10 +2793,7 @@ buf = xmlBufferCreate(); xmlNodeDump(buf, NULL, data, 0, 0); MAKE_STD_ZVAL(ret); - ZVAL_STRING(ret, (char*)xmlBufferContent(buf), 1); - if (UG(unicode)) { - zval_string_to_unicode_ex(ret, UG(utf8_conv) TSRMLS_CC); - } + soap_decode_string(ret, (char*)xmlBufferContent(buf) TSRMLS_CC); xmlBufferFree(buf); return ret; } http://cvs.php.net/viewvc.cgi/php-src/ext/soap/php_http.c?r1=1.94&r2=1.95&diff_format=u Index: php-src/ext/soap/php_http.c diff -u php-src/ext/soap/php_http.c:1.94 php-src/ext/soap/php_http.c:1.95 --- php-src/ext/soap/php_http.c:1.94 Mon Jul 31 16:02:04 2006 +++ php-src/ext/soap/php_http.c Tue Aug 1 16:10:25 2006 @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_http.c,v 1.94 2006/07/31 16:02:04 dmitry Exp $ */ +/* $Id: php_http.c,v 1.95 2006/08/01 16:10:25 dmitry Exp $ */ #include "php_soap.h" #include "ext/standard/base64.h" @@ -602,7 +602,9 @@ if (client->cookies) { zval **data; zstr key; + uint key_len; int i, n; + zend_uchar key_type; n = zend_hash_num_elements(Z_ARRVAL_P(client->cookies)); if (n > 0) { @@ -610,23 +612,42 @@ smart_str_append_const(&soap_headers, "Cookie: "); for (i = 0; i < n; i++) { zend_hash_get_current_data(Z_ARRVAL_P(client->cookies), (void **)&data); - /* TODO: unicode support */ - zend_hash_get_current_key(Z_ARRVAL_P(client->cookies), &key, NULL, FALSE); + key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(client->cookies), &key, &key_len, NULL, FALSE, NULL); if (Z_TYPE_PP(data) == IS_ARRAY) { zval** value; if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&value) == SUCCESS && - Z_TYPE_PP(value) == IS_STRING) { + (Z_TYPE_PP(value) == IS_STRING || Z_TYPE_PP(value) == IS_UNICODE)) { zval **tmp; if ((zend_hash_index_find(Z_ARRVAL_PP(data), 1, (void**)&tmp) == FAILURE || strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_PP(tmp),Z_STRLEN_PP(tmp)) == 0) && (zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == FAILURE || in_domain(phpurl->host,Z_STRVAL_PP(tmp))) && (use_ssl || zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) { - smart_str_appendl(&soap_headers, key.s, strlen(key.s)); + if (key_type == IS_STRING) { + smart_str_appendl(&soap_headers, key.s, key_len-1); + } else { + UErrorCode status = U_ZERO_ERROR; + char *res; + int res_len; + + zend_convert_from_unicode(UG(utf8_conv), &res, &res_len, key.u, key_len-1, &status); + smart_str_appendl(&soap_headers, res, res_len); + efree(res); + } smart_str_appendc(&soap_headers, '='); - smart_str_appendl(&soap_headers, Z_STRVAL_PP(value), Z_STRLEN_PP(value)); + if (Z_TYPE_PP(value) == IS_STRING) { + smart_str_appendl(&soap_headers, Z_STRVAL_PP(value), Z_STRLEN_PP(value)); + } else { + UErrorCode status = U_ZERO_ERROR; + char *res; + int res_len; + + zend_convert_from_unicode(UG(utf8_conv), &res, &res_len, Z_USTRVAL_PP(value), Z_USTRLEN_PP(value), &status); + smart_str_appendl(&soap_headers, res, res_len); + efree(res); + } smart_str_appendc(&soap_headers, ';'); } } @@ -751,6 +772,7 @@ smart_str name = {0}; int cookie_len; zval *zcookie; + zval *zvalue; if (sempos != NULL) { cookie_len = sempos-(eqpos+1); @@ -763,7 +785,12 @@ ALLOC_INIT_ZVAL(zcookie); array_init(zcookie); - add_index_stringl(zcookie, 0, eqpos + 1, cookie_len, 1); + MAKE_STD_ZVAL(zvalue); + ZVAL_STRINGL(zvalue, eqpos + 1, cookie_len, 1); + if (UG(unicode)) { + zval_string_to_unicode_ex(zvalue, UG(utf8_conv) TSRMLS_CC); + } + add_index_zval(zcookie, 0, zvalue); if (sempos != NULL) { char *options = cookie + cookie_len+1; http://cvs.php.net/viewvc.cgi/php-src/ext/soap/php_soap.h?r1=1.46&r2=1.47&diff_format=u Index: php-src/ext/soap/php_soap.h diff -u php-src/ext/soap/php_soap.h:1.46 php-src/ext/soap/php_soap.h:1.47 --- php-src/ext/soap/php_soap.h:1.46 Mon Jul 31 16:02:04 2006 +++ php-src/ext/soap/php_soap.h Tue Aug 1 16:10:25 2006 @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_soap.h,v 1.46 2006/07/31 16:02:04 dmitry Exp $ */ +/* $Id: php_soap.h,v 1.47 2006/08/01 16:10:25 dmitry Exp $ */ #ifndef PHP_SOAP_H #define PHP_SOAP_H @@ -275,5 +275,8 @@ php_error(severity, "SOAP-ERROR: " format, param1, param2, param3) char* soap_unicode_to_string(UChar *ustr, int ustr_len TSRMLS_DC); +void soap_decode_string(zval *ret, char* str TSRMLS_DC); +char* soap_encode_string(zval *data, int* len TSRMLS_DC); +char* soap_encode_string_ex(zend_uchar type, zstr data, int len TSRMLS_DC); #endif http://cvs.php.net/viewvc.cgi/php-src/ext/soap/soap.c?r1=1.199&r2=1.200&diff_format=u Index: php-src/ext/soap/soap.c diff -u php-src/ext/soap/soap.c:1.199 php-src/ext/soap/soap.c:1.200 --- php-src/ext/soap/soap.c:1.199 Mon Jul 31 16:02:04 2006 +++ php-src/ext/soap/soap.c Tue Aug 1 16:10:25 2006 @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: soap.c,v 1.199 2006/07/31 16:02:04 dmitry Exp $ */ +/* $Id: soap.c,v 1.200 2006/08/01 16:10:25 dmitry Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -27,6 +27,7 @@ #include "ext/session/php_session.h" #endif #include "zend_exceptions.h" +#include "ext/libxml/php_libxml.h" typedef struct _soapHeader { sdlFunctionPtr function; @@ -185,6 +186,7 @@ PHP_METHOD(SoapClient, __getTypes); PHP_METHOD(SoapClient, __doRequest); PHP_METHOD(SoapClient, __setCookie); +PHP_METHOD(SoapClient, __getCookies); PHP_METHOD(SoapClient, __setLocation); PHP_METHOD(SoapClient, __setSoapHeaders); @@ -258,6 +260,7 @@ PHP_ME(SoapClient, __getTypes, NULL, 0) PHP_ME(SoapClient, __doRequest, NULL, 0) PHP_ME(SoapClient, __setCookie, NULL, 0) + PHP_ME(SoapClient, __getCookies, NULL, 0) PHP_ME(SoapClient, __setLocation, NULL, 0) PHP_ME(SoapClient, __setSoapHeaders, NULL, 0) {NULL, NULL, NULL} @@ -309,6 +312,105 @@ return tmp; } +void soap_decode_string(zval *ret, char* str TSRMLS_DC) +{ + if (UG(unicode)) { + /* TODO: unicode support */ + ZVAL_STRING(ret, str, 1); + zval_string_to_unicode_ex(ret, UG(utf8_conv) TSRMLS_CC); + } else if (SOAP_GLOBAL(encoding) != NULL) { + xmlBufferPtr in = xmlBufferCreateStatic(str, strlen(str)); + xmlBufferPtr out = xmlBufferCreate(); + int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in); + + if (n >= 0) { + ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1); + } else { + ZVAL_STRING(ret, str, 1); + } + xmlBufferFree(out); + xmlBufferFree(in); + } else { + ZVAL_STRING(ret, str, 1); + } +} + +char* soap_encode_string_ex(zend_uchar type, zstr data, int len TSRMLS_DC) +{ + char *str; + int new_len; + + if (type == IS_UNICODE) { + str = soap_unicode_to_string(data.u, len TSRMLS_CC); + } else { + str = estrndup(data.s, len); + new_len = len; + + if (SOAP_GLOBAL(encoding) != NULL) { + xmlBufferPtr in = xmlBufferCreateStatic(str, new_len); + xmlBufferPtr out = xmlBufferCreate(); + int n = xmlCharEncInFunc(SOAP_GLOBAL(encoding), out, in); + + if (n >= 0) { + efree(str); + str = estrdup((char*)xmlBufferContent(out)); + } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { + soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); + } + xmlBufferFree(out); + xmlBufferFree(in); + } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { + soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); + } + } + return str; +} + +char* soap_encode_string(zval *data, int* len TSRMLS_DC) +{ + char *str; + int new_len; + + if (Z_TYPE_P(data) == IS_UNICODE) { + str = soap_unicode_to_string(Z_USTRVAL_P(data), Z_USTRLEN_P(data) TSRMLS_CC); + new_len = strlen(str); + } else { + if (Z_TYPE_P(data) == IS_STRING) { + str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data)); + new_len = Z_STRLEN_P(data); + } else { + zval tmp = *data; + + zval_copy_ctor(&tmp); + convert_to_string(&tmp); + str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); + new_len = Z_STRLEN(tmp); + zval_dtor(&tmp); + } + + if (SOAP_GLOBAL(encoding) != NULL) { + xmlBufferPtr in = xmlBufferCreateStatic(str, new_len); + xmlBufferPtr out = xmlBufferCreate(); + int n = xmlCharEncInFunc(SOAP_GLOBAL(encoding), out, in); + + if (n >= 0) { + efree(str); + str = estrdup((char*)xmlBufferContent(out)); + new_len = n; + } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { + soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); + } + xmlBufferFree(out); + xmlBufferFree(in); + } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { + soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); + } + } + if (len) { + *len = new_len; + } + return str; +} ZEND_INI_MH(OnUpdateCacheEnabled) { @@ -1465,7 +1567,6 @@ zend_hash_internal_pointer_reset_ex(ft, &pos); while (zend_hash_get_current_data_ex(ft, (void **)&f, &pos) != FAILURE) { if ((service->type != SOAP_CLASS) || (f->common.fn_flags & ZEND_ACC_PUBLIC)) { - /* FIXME: Unicode support??? */ add_next_index_text(return_value, f->common.function_name, 1); } zend_hash_move_forward_ex(ft, &pos); @@ -1583,17 +1684,18 @@ HashTable *function_table; soapHeader *soap_headers = NULL; sdlFunctionPtr function; - char *arg = NULL; + zstr arg = NULL_ZSTR; int arg_len; xmlCharEncodingHandlerPtr old_encoding; HashTable *old_class_map; int old_features; + zend_uchar arg_type; SOAP_SERVER_BEGIN_CODE(); service = (soap_server_object*)zend_object_store_get_object(this_ptr TSRMLS_CC); SOAP_GLOBAL(soap_version) = service->version; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &arg, &arg_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|t", &arg, &arg_len, &arg_type) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters"); } INIT_ZVAL(retval); @@ -1709,8 +1811,14 @@ soap_server_fault("Server", "Bad Request. Can't find HTTP_RAW_POST_DATA", NULL, NULL, NULL TSRMLS_CC); return; } + } else if (arg_type == IS_UNICODE) { + /* TODO: remove unicode->string conversion */ + char *str_req = soap_unicode_to_string(arg.u, arg_len TSRMLS_CC); + + doc_request = soap_xmlParseMemory(str_req, strlen(str_req)); + efree(str_req); } else { - doc_request = soap_xmlParseMemory(arg,arg_len); + doc_request = soap_xmlParseMemory(arg.s, arg_len); } if (doc_request == NULL) { @@ -2593,22 +2701,29 @@ ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1,0); INIT_ZVAL(param0); params[0] = &param0; - ZVAL_STRINGL(params[0], buf, buf_size, 0); + ZVAL_STRINGL(params[0], buf, buf_size, 1); + if (UG(unicode)) { + zval_string_to_unicode_ex(params[0], UG(utf8_conv) TSRMLS_CC); + } INIT_ZVAL(param1); params[1] = &param1; if (location == NULL) { ZVAL_NULL(params[1]); } else { - /* TODO: Unicode support */ - ZVAL_STRING(params[1], location, 0); + ZVAL_STRING(params[1], location, 1); + if (UG(unicode)) { + zval_string_to_unicode_ex(params[1], UG(utf8_conv) TSRMLS_CC); + } } INIT_ZVAL(param2); params[2] = &param2; if (action == NULL) { ZVAL_NULL(params[2]); } else { - /* TODO: Unicode support */ - ZVAL_STRING(params[2], action, 0); + ZVAL_STRING(params[2], action, 1); + if (UG(unicode)) { + zval_string_to_unicode_ex(params[2], UG(utf8_conv) TSRMLS_CC); + } } INIT_ZVAL(param3); params[3] = &param3; @@ -2628,7 +2743,7 @@ ret = FALSE; } else { if (Z_TYPE_P(response) == IS_UNICODE) { - zval_unicode_to_string_ex(response, ZEND_U_CONVERTER(UG(runtime_encoding_conv)) TSRMLS_CC); + zval_unicode_to_string_ex(response, UG(utf8_conv) TSRMLS_CC); } if (client->trace) { if (client->last_response) { @@ -2638,6 +2753,9 @@ } } xmlFree(buf); + zval_dtor(params[0]); + zval_dtor(params[1]); + zval_dtor(params[2]); if (ret && client->fault) { return FALSE; } @@ -2950,14 +3068,12 @@ if (output_headers) { array_init(output_headers); } - if (function_type == IS_UNICODE) { - function.s = soap_unicode_to_string(function.u, function_len TSRMLS_CC); - function_len = strlen(function.s); - } + + function.s = soap_encode_string_ex(function_type, function, function_len TSRMLS_CC); + function_len = strlen(function.s); do_soap_call(this_ptr, function.s, function_len, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers TSRMLS_CC); - if (function_type == IS_UNICODE) { - efree(function.s); - } + efree(function.s); + if (arg_count > 0) { efree(real_args); } @@ -3100,31 +3216,52 @@ SoapClient::__doRequest() */ PHP_METHOD(SoapClient, __doRequest) { - char *buf, *location, *action; + zstr buf, location, action; int buf_size, location_size, action_size; + zend_uchar buf_type, location_type, action_type; long version; long one_way = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssl|l", - &buf, &buf_size, - &location, &location_size, - &action, &action_size, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "tttl|l", + &buf, &buf_size, &buf_type, + &location, &location_size, &location_type, + &action, &action_size, &action_type, &version, &one_way) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters"); } + if (buf_type == IS_UNICODE) { + buf.s = soap_unicode_to_string(buf.u, buf_size TSRMLS_CC); + buf_size = strlen(buf.s); + } + if (location_type == IS_UNICODE) { + location.s = soap_unicode_to_string(location.u, location_size TSRMLS_CC); + } + if (action_type == IS_UNICODE) { + action.s = soap_unicode_to_string(action.u, action_size TSRMLS_CC); + } if (SOAP_GLOBAL(features) & SOAP_WAIT_ONE_WAY_CALLS) { one_way = 0; } if (one_way) { - if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version, NULL, NULL TSRMLS_CC)) { - RETURN_EMPTY_STRING(); + if (make_http_soap_request(this_ptr, buf.s, buf_size, location.s, action.s, version, NULL, NULL TSRMLS_CC)) { + RETVAL_EMPTY_STRING(); } - } else if (make_http_soap_request(this_ptr, buf, buf_size, location, action, version, + } else if (make_http_soap_request(this_ptr, buf.s, buf_size, location.s, action.s, version, &Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC)) { return_value->type = IS_STRING; - return; + if (UG(unicode)) { + zval_string_to_unicode_ex(return_value, UG(utf8_conv) TSRMLS_CC); + } + } + if (buf_type == IS_UNICODE) { + efree(buf.s); + } + if (location_type == IS_UNICODE) { + efree(location.s); + } + if (action_type == IS_UNICODE) { + efree(action.s); } - RETURN_NULL(); } /* }}} */ @@ -3134,21 +3271,22 @@ If value is not specified cookie is removed. */ PHP_METHOD(SoapClient, __setCookie) { - char *name; - char *val = NULL; + zstr name; + zstr val = NULL_ZSTR; int name_len, val_len; + zend_uchar name_type, val_type; soap_client_object *client; client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", - &name, &name_len, &val, &val_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t|t", + &name, &name_len, &name_type, &val, &val_len, &val_type) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters"); RETURN_NULL(); } - if (val == NULL) { + if (val.v == NULL) { if (client->cookies) { - zend_hash_del(Z_ARRVAL_P(client->cookies), name, name_len+1); + zend_u_hash_del(Z_ARRVAL_P(client->cookies), name_type, name, name_len+1); } } else { zval *zcookie; @@ -3160,8 +3298,30 @@ ALLOC_INIT_ZVAL(zcookie); array_init(zcookie); - add_index_stringl(zcookie, 0, val, val_len, 1); - add_assoc_zval_ex(client->cookies, name, name_len+1, zcookie); + if (val_type == IS_STRING) { + add_index_stringl(zcookie, 0, val.s, val_len, 1); + } else { + add_index_unicodel(zcookie, 0, val.u, val_len, 1); + } + add_u_assoc_zval_ex(client->cookies, name_type, name, name_len+1, zcookie); + } +} +/* }}} */ + +/* {{{ proto array SoapClient::__getCookies() + Returns array of cookies. */ +PHP_METHOD(SoapClient, __getCookies) +{ + soap_client_object *client; + + client = (soap_client_object*)zend_object_store_get_object(this_ptr TSRMLS_CC); + + if (!client->cookies) { + array_init(return_value); + } else { + *return_value = *client->cookies; + zval_copy_ctor(return_value); + INIT_PZVAL(return_value); } } /* }}} */ @@ -3760,10 +3920,8 @@ ulong param_index = i; param_name_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(ret), &param_name, &param_name_len, &param_index, 0, &pos); - if (param_name_type == IS_UNICODE) { - param_name.s = soap_unicode_to_string(param_name.u, param_name_len TSRMLS_CC); - param_name_len = strlen(param_name.s); - } + param_name.s = soap_encode_string_ex(param_name_type, param_name, param_name_len TSRMLS_CC); + param_name_len = strlen(param_name.s); parameter = get_param(function, param_name.s, param_index, TRUE); if (style == SOAP_RPC) { param = serialize_parameter(parameter, *data, i, param_name.s, use, method TSRMLS_CC); @@ -3777,9 +3935,7 @@ } } } - if (param_name_type == IS_UNICODE) { - efree(param_name.v); - } + efree(param_name.s); zend_hash_move_forward_ex(Z_ARRVAL_P(ret), &pos); i++; @@ -3847,12 +4003,8 @@ smart_str key = {0}; if (zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&tmp) == SUCCESS) { - if (Z_TYPE_PP(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); - smart_str_appendc(&key, ':'); - hdr_ns = Z_STRVAL_PP(tmp); - } else if (Z_TYPE_PP(tmp) == IS_UNICODE) { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC); + if (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE) { + char *str = soap_encode_string(*tmp, NULL TSRMLS_CC); smart_str_appends(&key, str); smart_str_appendc(&key, ':'); @@ -3861,11 +4013,8 @@ } } if (zend_hash_find(ht, "name", sizeof("name"), (void**)&tmp) == SUCCESS) { - if (Z_TYPE_PP(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); - hdr_name = Z_STRVAL_PP(tmp); - } else if (Z_TYPE_PP(tmp) == IS_UNICODE) { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC); + if (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE) { + char *str = soap_encode_string(*tmp, NULL TSRMLS_CC); smart_str_appends(&key, str); hdr_name = str; @@ -4086,12 +4235,8 @@ smart_str key = {0}; if (zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&tmp) == SUCCESS) { - if (Z_TYPE_PP(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); - smart_str_appendc(&key, ':'); - hdr_ns = Z_STRVAL_PP(tmp); - } else if (Z_TYPE_PP(tmp) == IS_UNICODE) { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC); + if (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE) { + char *str = soap_encode_string(*tmp, NULL TSRMLS_CC); smart_str_appends(&key, str); smart_str_appendc(&key, ':'); @@ -4100,11 +4245,8 @@ } } if (zend_hash_find(ht, "name", sizeof("name"), (void**)&tmp) == SUCCESS) { - if (Z_TYPE_PP(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); - hdr_name = Z_STRVAL_PP(tmp); - } else if (Z_TYPE_PP(tmp) == IS_UNICODE) { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_USTRLEN_PP(tmp) TSRMLS_CC); + if (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE) { + char *str = soap_encode_string(*tmp, NULL TSRMLS_CC); smart_str_appends(&key, str); hdr_name = str; @@ -4316,24 +4458,16 @@ smart_str key = {0}; sdlSoapBindingFunctionHeaderPtr *hdr; - if (Z_TYPE_PP(ns) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_PP(ns), Z_STRLEN_PP(ns)); - } else { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(ns), Z_USTRLEN_PP(ns) TSRMLS_CC); + ns_str = soap_encode_string(*ns, NULL TSRMLS_CC); + smart_str_appends(&key, ns_str); - smart_str_appends(&key, str); - ns_str = str; - } smart_str_appendc(&key, ':'); - if (Z_TYPE_PP(name) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); - } else { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(name), Z_USTRLEN_PP(name) TSRMLS_CC); - smart_str_appends(&key, str); - name_str = str; - } + name_str = soap_encode_string(*name, NULL TSRMLS_CC); + + smart_str_appends(&key, name_str); smart_str_0(&key); + if (zend_hash_find(hdrs, key.c, key.len+1,(void**)&hdr) == SUCCESS) { hdr_use = (*hdr)->use; enc = (*hdr)->encode; @@ -4343,12 +4477,8 @@ } smart_str_free(&key); } else { - if (Z_TYPE_PP(ns) == IS_UNICODE) { - ns_str = soap_unicode_to_string(Z_USTRVAL_PP(ns), Z_USTRLEN_PP(ns) TSRMLS_CC); - } - if (Z_TYPE_PP(name) == IS_UNICODE) { - name_str = soap_unicode_to_string(Z_USTRVAL_PP(name), Z_USTRLEN_PP(name) TSRMLS_CC); - } + ns_str = soap_encode_string(*ns, NULL TSRMLS_CC); + name_str = soap_encode_string(*name, NULL TSRMLS_CC); } if (zend_hash_find(ht, "data", sizeof("data"), (void**)&tmp) == SUCCESS) { @@ -4378,14 +4508,8 @@ } } if (zend_hash_find(ht, "actor", sizeof("actor"), (void**)&tmp) == SUCCESS) { - if (Z_TYPE_PP(tmp) == IS_STRING) { - if (version == SOAP_1_1) { - xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(Z_STRVAL_PP(tmp))); - } else { - xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(Z_STRVAL_PP(tmp))); - } - } else if (Z_TYPE_PP(tmp) == IS_UNICODE) { - char *str = soap_unicode_to_string(Z_USTRVAL_PP(tmp), Z_STRLEN_PP(tmp) TSRMLS_CC); + if (Z_TYPE_PP(tmp) == IS_STRING || Z_TYPE_PP(tmp) == IS_UNICODE) { + char *str = soap_encode_string(*tmp, NULL TSRMLS_CC); if (version == SOAP_1_1) { xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(str)); @@ -4447,12 +4571,8 @@ (Z_TYPE_PP(param_name) == IS_STRING || Z_TYPE_PP(param_name) == IS_UNICODE) && zend_hash_find(Z_OBJPROP_P(param_val), "param_data", sizeof("param_data"), (void **)&param_data) == SUCCESS) { param_val = *param_data; - if (Z_TYPE_PP(param_name) == IS_STRING) { - name = Z_STRVAL_PP(param_name); - } else { - name = soap_unicode_to_string(Z_USTRVAL_PP(param_name), Z_USTRLEN_PP(param_name) TSRMLS_CC); - free_name = 1; - } + name = soap_encode_string(*param_name, NULL TSRMLS_CC); + free_name = 1; } } http://cvs.php.net/viewvc.cgi/php-src/ext/soap/tests/bugs/bug32941.phpt?r1=1.2&r2=1.3&diff_format=u Index: php-src/ext/soap/tests/bugs/bug32941.phpt diff -u php-src/ext/soap/tests/bugs/bug32941.phpt:1.2 php-src/ext/soap/tests/bugs/bug32941.phpt:1.3 --- php-src/ext/soap/tests/bugs/bug32941.phpt:1.2 Wed Jun 1 14:43:13 2005 +++ php-src/ext/soap/tests/bugs/bug32941.phpt Tue Aug 1 16:10:25 2006 @@ -35,7 +35,50 @@ $ahoj = $client->echoString('exception'); $client = new TestSoapClient(dirname(__FILE__).'/bug32941.wsdl', array("trace" => 1, 'exceptions' => 0)); $ahoj = $client->echoString('exception'); +var_dump($ahoj->detail); echo "ok\n"; ?> --EXPECT-- +object(stdClass)#1 (2) { + ["service.EchoServiceException"]=> + object(SoapVar)#8 (4) { + ["enc_type"]=> + int(0) + ["enc_value"]=> + object(stdClass)#7 (2) { + ["intParameter"]=> + int(105) + ["parameter"]=> + string(12) "string param" + } + ["enc_stype"]=> + string(20) "EchoServiceException" + ["enc_ns"]=> + string(23) "urn:service.EchoService" + } + ["hostname"]=> + string(9) "steckovic" +} +ok +--UEXPECT-- +object(stdClass)#1 (2) { + [u"service.EchoServiceException"]=> + object(SoapVar)#8 (4) { + [u"enc_type"]=> + int(0) + [u"enc_value"]=> + object(stdClass)#7 (2) { + [u"intParameter"]=> + int(105) + [u"parameter"]=> + unicode(12) "string param" + } + [u"enc_stype"]=> + unicode(20) "EchoServiceException" + [u"enc_ns"]=> + unicode(23) "urn:service.EchoService" + } + [u"hostname"]=> + unicode(9) "steckovic" +} ok http://cvs.php.net/viewvc.cgi/php-src/ext/soap/tests/cookie.phpt?view=markup&rev=1.1 Index: php-src/ext/soap/tests/cookie.phpt +++ php-src/ext/soap/tests/cookie.phpt --TEST-- SOAP: SoapClient::__setCookie() and SoapClient::__getCookies() --SKIPIF-- <?php require_once('skipif.inc'); ?> --FILE-- <?php function dump_cookies($client) { $c = $client->__getCookies(); $client->test(); if (preg_match('/^Cookie:[^\n\r]*/mi', $client->__getLastRequestHeaders(), $r)) { echo $r[0]."\n"; } else { echo "Cookie:\n"; } foreach ($c as $key => $val) { if (isset($val[0])) { echo " ".gettype($key)."(\"".$key."\") => ".gettype($val[0])."(\"".$val[0]."\")\n"; } } } ini_set('default_socket_timeout', 0.1); $server = stream_socket_server('tcp://127.0.0.1:31337'); $client = new SoapClient(NULL, array("location"=>"http://127.0.0.1:31337","uri"=>"test://", "exceptions"=>0,"trace"=>1, "connection_timeout"=>1)); dump_cookies($client); $client->__setCookie("var1","val1"); dump_cookies($client); $client->__setCookie("var2","val2"); dump_cookies($client); $client->__setCookie("var1"); $client->__setCookie("var2","val3"); dump_cookies($client); $client->__setCookie("var2"); dump_cookies($client); ?> --EXPECT-- Cookie: Cookie: var1=val1; string("var1") => string("val1") Cookie: var1=val1;var2=val2; string("var1") => string("val1") string("var2") => string("val2") Cookie: var2=val3; string("var2") => string("val3") Cookie: --UEXPECT-- Cookie: Cookie: var1=val1; unicode("var1") => unicode("val1") Cookie: var1=val1;var2=val2; unicode("var1") => unicode("val1") unicode("var2") => unicode("val2") Cookie: var2=val3; unicode("var2") => unicode("val3") Cookie:
« previous php.cvs (#39703) next »