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:
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¶ms, &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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user