1
0
mirror of https://github.com/php/php-src.git synced 2026-04-29 19:23:22 +02:00

Fixed bug #28969 (Wrong data encoding of special characters)

This commit is contained in:
Dmitry Stogov
2004-08-10 16:30:31 +00:00
parent 02893ad216
commit bd96cca64f
5 changed files with 141 additions and 5 deletions
+1
View File
@@ -44,6 +44,7 @@ PHP NEWS
- Fixed bug #29109 (SoapFault exception: [WSDL] Out of memory). (Dmitry)
- Fixed bug #29061 (soap extension segfaults). (Dmitry)
- Fixed bug #28985 (__getTypes() returning nothing on complex WSDL). (Dmitry)
- Fixed bug #28969 (Wrong data encoding of special characters). (Dmitry)
- Fixed bug #28895 (ReflectionClass::isAbstract always returns false). (Marcus)
- Fixed bug #28829 (Thread-unsafety in bcmath elementary values). (Sara)
- Fixed bug #28464 (catch() does not catch exceptions by interfaces). (Marcus)
+91 -4
View File
@@ -31,6 +31,7 @@ static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data);
static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data);
static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data);
static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data);
static zval *to_zval_stringb(encodeTypePtr type, xmlNodePtr data);
static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data);
static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data);
@@ -145,8 +146,8 @@ encode defaultEncoding[] = {
{{XSD_GMONTH, XSD_GMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonth},
{{XSD_DURATION, XSD_DURATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_duration},
{{XSD_HEXBINARY, XSD_HEXBINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_stringl},
{{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_stringl},
{{XSD_HEXBINARY, XSD_HEXBINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringb, to_xml_stringl},
{{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringb, to_xml_stringl},
{{XSD_LONG, XSD_LONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
{{XSD_INT, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
@@ -460,7 +461,23 @@ static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data)
FIND_XML_NULL(data, ret);
if (data && data->children) {
if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
ZVAL_STRING(ret, data->children->content, 1);
TSRMLS_FETCH();
if (SOAP_GLOBAL(encoding) != NULL) {
xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, strlen(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, data->children->content, 1);
}
xmlBufferFree(out);
xmlBufferFree(in);
} else {
ZVAL_STRING(ret, data->children->content, 1);
}
} else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
ZVAL_STRING(ret, data->children->content, 1);
} else {
@@ -479,8 +496,24 @@ static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data)
FIND_XML_NULL(data, ret);
if (data && data->children) {
if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
TSRMLS_FETCH();
whiteSpace_replace(data->children->content);
ZVAL_STRING(ret, data->children->content, 1);
if (SOAP_GLOBAL(encoding) != NULL) {
xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, strlen(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, data->children->content, 1);
}
xmlBufferFree(out);
xmlBufferFree(in);
} else {
ZVAL_STRING(ret, data->children->content, 1);
}
} else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
ZVAL_STRING(ret, data->children->content, 1);
} else {
@@ -493,6 +526,42 @@ static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data)
}
static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data)
{
zval *ret;
MAKE_STD_ZVAL(ret);
FIND_XML_NULL(data, ret);
if (data && data->children) {
if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
TSRMLS_FETCH();
whiteSpace_collapse(data->children->content);
if (SOAP_GLOBAL(encoding) != NULL) {
xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, strlen(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, data->children->content, 1);
}
xmlBufferFree(out);
xmlBufferFree(in);
} else {
ZVAL_STRING(ret, data->children->content, 1);
}
} else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
ZVAL_STRING(ret, data->children->content, 1);
} else {
soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
}
} else {
ZVAL_EMPTY_STRING(ret);
}
return ret;
}
static zval *to_zval_stringb(encodeTypePtr type, xmlNodePtr data)
{
zval *ret;
MAKE_STD_ZVAL(ret);
@@ -534,6 +603,24 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
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(xmlBufferContent(out));
new_len = n;
} else if (!xmlCheckUTF8(str)) {
soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str);
}
xmlBufferFree(out);
xmlBufferFree(in);
} else if (!xmlCheckUTF8(str)) {
soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str);
}
xmlNodeSetContentLen(ret, str, new_len);
efree(str);
+2
View File
@@ -115,6 +115,7 @@ struct _soapService {
int type;
char *actor;
char *uri;
xmlCharEncodingHandlerPtr encoding;
};
#define SOAP_CLASS 1
@@ -158,6 +159,7 @@ ZEND_BEGIN_MODULE_GLOBALS(soap)
zend_bool cache_enabled;
char* cache_dir;
long cache_ttl;
xmlCharEncodingHandlerPtr encoding;
ZEND_END_MODULE_GLOBALS(soap)
#ifdef PHP_WIN32
+46
View File
@@ -423,6 +423,7 @@ PHP_RINIT_FUNCTION(soap)
SOAP_GLOBAL(error_object) = NULL;
SOAP_GLOBAL(sdl) = NULL;
SOAP_GLOBAL(soap_version) = SOAP_1_1;
SOAP_GLOBAL(encoding) = NULL;
return SUCCESS;
}
@@ -835,6 +836,19 @@ PHP_METHOD(SoapServer, SoapServer)
Z_TYPE_PP(tmp) == IS_STRING) {
service->actor = estrndup(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
}
if (zend_hash_find(ht, "encoding", sizeof("encoding"), (void**)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
xmlCharEncodingHandlerPtr encoding;
encoding = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
if (encoding == NULL) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments. Invalid 'encoding' option - '%s'.", Z_STRVAL_PP(tmp));
} else {
service->encoding = encoding;
}
}
} else if (wsdl == NULL) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments. 'uri' option is required in nonWSDL mode.");
}
@@ -1233,6 +1247,7 @@ PHP_METHOD(SoapServer, handle)
sdlFunctionPtr function;
char *arg = NULL;
int arg_len;
xmlCharEncodingHandlerPtr old_encoding;
SOAP_SERVER_BEGIN_CODE();
@@ -1374,6 +1389,8 @@ PHP_METHOD(SoapServer, handle)
old_sdl = SOAP_GLOBAL(sdl);
SOAP_GLOBAL(sdl) = service->sdl;
old_encoding = SOAP_GLOBAL(encoding);
SOAP_GLOBAL(encoding) = service->encoding;
old_soap_version = SOAP_GLOBAL(soap_version);
function = deserialize_function_call(service->sdl, doc_request, service->actor, &function_name, &num_params, &params, &soap_version, &soap_headers TSRMLS_CC);
xmlFreeDoc(doc_request);
@@ -1636,6 +1653,7 @@ PHP_METHOD(SoapServer, handle)
fail:
SOAP_GLOBAL(soap_version) = old_soap_version;
SOAP_GLOBAL(encoding) = old_encoding;
SOAP_GLOBAL(sdl) = old_sdl;
/* Free soap headers */
@@ -1936,6 +1954,18 @@ PHP_METHOD(SoapClient, SoapClient)
zend_hash_exists(EG(function_table), "gzencode", sizeof("gzencode"))) {
add_property_long(this_ptr, "compression", Z_LVAL_PP(tmp));
}
if (zend_hash_find(ht, "encoding", sizeof("encoding"), (void**)&tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
xmlCharEncodingHandlerPtr encoding;
encoding = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
if (encoding == NULL) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid 'encoding' option - '%s'.", Z_STRVAL_PP(tmp));
} else {
xmlCharEncCloseFunc(encoding);
add_property_stringl(this_ptr, "_encoding", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
}
}
} else if (wsdl == NULL) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' and 'uri' options are requred in nonWSDL mode.");
return;
@@ -2046,6 +2076,7 @@ static void do_soap_call(zval* this_ptr,
int ret = FALSE;
int soap_version;
zval response;
xmlCharEncodingHandlerPtr old_encoding;
SOAP_CLIENT_BEGIN_CODE();
@@ -2070,6 +2101,14 @@ static void do_soap_call(zval* this_ptr,
SOAP_GLOBAL(soap_version) = soap_version;
old_sdl = SOAP_GLOBAL(sdl);
SOAP_GLOBAL(sdl) = sdl;
old_encoding = SOAP_GLOBAL(encoding);
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_encoding", sizeof("_encoding"), (void **) &tmp) == SUCCESS &&
Z_TYPE_PP(tmp) == IS_STRING) {
SOAP_GLOBAL(encoding) = xmlFindCharEncodingHandler(Z_STRVAL_PP(tmp));
} else {
SOAP_GLOBAL(encoding) = NULL;
}
if (sdl != NULL) {
fn = get_function(sdl, function);
if (fn != NULL) {
@@ -2166,6 +2205,10 @@ static void do_soap_call(zval* this_ptr,
zend_throw_exception_object(exception TSRMLS_CC);
}
#endif
if (SOAP_GLOBAL(encoding) != NULL) {
xmlCharEncCloseFunc(SOAP_GLOBAL(encoding));
}
SOAP_GLOBAL(encoding) = old_encoding;
SOAP_GLOBAL(sdl) = old_sdl;
SOAP_CLIENT_END_CODE();
}
@@ -3910,5 +3953,8 @@ static void delete_service(void *data)
if (service->sdl) {
delete_sdl(service->sdl);
}
if (service->encoding) {
xmlCharEncCloseFunc(service->encoding);
}
efree(service);
}
+1 -1
View File
@@ -5,7 +5,7 @@ SOAP Server 21: SoapServer::setClass and __call()
--FILE--
<?php
class Foo {
function __call($name) {
function __call($name, $args) {
if ($name == "test") {
return "Hello World";
} else {