mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
Fix bug #70388 - SOAP serialize_function_call() type confusion
This commit is contained in:
parent
f9c2bf73ad
commit
e201f01ac1
@ -989,7 +989,7 @@ static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC)
|
||||
HashTable *ht2;
|
||||
HashPosition pos1, pos2;
|
||||
HashTable *typemap = NULL;
|
||||
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(ht, &pos1);
|
||||
while (zend_hash_get_current_data_ex(ht, (void**)&tmp, &pos1) == SUCCESS) {
|
||||
char *type_name = NULL;
|
||||
@ -1033,7 +1033,7 @@ static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC)
|
||||
}
|
||||
}
|
||||
zend_hash_move_forward_ex(ht2, &pos2);
|
||||
}
|
||||
}
|
||||
|
||||
if (type_name) {
|
||||
smart_str nscat = {0};
|
||||
@ -1063,7 +1063,7 @@ static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC)
|
||||
new_enc->to_xml = enc->to_xml;
|
||||
new_enc->to_zval = enc->to_zval;
|
||||
new_enc->details.map = emalloc(sizeof(soapMapping));
|
||||
memset(new_enc->details.map, 0, sizeof(soapMapping));
|
||||
memset(new_enc->details.map, 0, sizeof(soapMapping));
|
||||
if (to_xml) {
|
||||
zval_add_ref(&to_xml);
|
||||
new_enc->details.map->to_xml = to_xml;
|
||||
@ -1120,7 +1120,7 @@ PHP_METHOD(SoapServer, SoapServer)
|
||||
if (Z_TYPE_P(wsdl) != IS_STRING && Z_TYPE_P(wsdl) != IS_NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters");
|
||||
}
|
||||
|
||||
|
||||
service = emalloc(sizeof(soapService));
|
||||
memset(service, 0, sizeof(soapService));
|
||||
service->send_errors = 1;
|
||||
@ -1155,7 +1155,7 @@ PHP_METHOD(SoapServer, SoapServer)
|
||||
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));
|
||||
@ -1215,7 +1215,7 @@ PHP_METHOD(SoapServer, SoapServer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (typemap_ht) {
|
||||
service->typemap = soap_create_typemap(service->sdl, typemap_ht TSRMLS_CC);
|
||||
}
|
||||
@ -1345,7 +1345,7 @@ PHP_METHOD(SoapServer, getFunctions)
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FETCH_THIS_SERVICE(service);
|
||||
|
||||
array_init(return_value);
|
||||
@ -1505,7 +1505,7 @@ PHP_METHOD(SoapServer, handle)
|
||||
|
||||
FETCH_THIS_SERVICE(service);
|
||||
SOAP_GLOBAL(soap_version) = service->version;
|
||||
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &arg, &arg_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
@ -1930,7 +1930,7 @@ PHP_METHOD(SoapServer, handle)
|
||||
|
||||
if (size == 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Dump memory failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (soap_version == SOAP_1_2) {
|
||||
sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
|
||||
@ -2147,10 +2147,10 @@ static void soap_error_handler(int error_num, const char *error_filename, const
|
||||
use_exceptions = 1;
|
||||
}
|
||||
|
||||
if ((error_num == E_USER_ERROR ||
|
||||
error_num == E_COMPILE_ERROR ||
|
||||
if ((error_num == E_USER_ERROR ||
|
||||
error_num == E_COMPILE_ERROR ||
|
||||
error_num == E_CORE_ERROR ||
|
||||
error_num == E_ERROR ||
|
||||
error_num == E_ERROR ||
|
||||
error_num == E_PARSE) &&
|
||||
use_exceptions) {
|
||||
zval *fault, *exception;
|
||||
@ -2219,10 +2219,10 @@ static void soap_error_handler(int error_num, const char *error_filename, const
|
||||
va_list argcopy;
|
||||
#endif
|
||||
|
||||
if (error_num == E_USER_ERROR ||
|
||||
error_num == E_COMPILE_ERROR ||
|
||||
if (error_num == E_USER_ERROR ||
|
||||
error_num == E_COMPILE_ERROR ||
|
||||
error_num == E_CORE_ERROR ||
|
||||
error_num == E_ERROR ||
|
||||
error_num == E_ERROR ||
|
||||
error_num == E_PARSE) {
|
||||
|
||||
char* code = SOAP_GLOBAL(error_code);
|
||||
@ -2452,13 +2452,13 @@ PHP_METHOD(SoapClient, SoapClient)
|
||||
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);
|
||||
add_property_stringl(this_ptr, "_encoding", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
|
||||
}
|
||||
}
|
||||
if (zend_hash_find(ht, "classmap", sizeof("classmap"), (void**)&tmp) == SUCCESS &&
|
||||
@ -2493,7 +2493,7 @@ PHP_METHOD(SoapClient, SoapClient)
|
||||
if (context) {
|
||||
add_property_resource(this_ptr, "_stream_context", context->rsrc_id);
|
||||
}
|
||||
|
||||
|
||||
if (zend_hash_find(ht, "cache_wsdl", sizeof("cache_wsdl"), (void**)&tmp) == SUCCESS &&
|
||||
Z_TYPE_PP(tmp) == IS_LONG) {
|
||||
cache_wsdl = Z_LVAL_PP(tmp);
|
||||
@ -2503,7 +2503,7 @@ PHP_METHOD(SoapClient, SoapClient)
|
||||
Z_TYPE_PP(tmp) == IS_STRING) {
|
||||
add_property_stringl(this_ptr, "_user_agent", Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
|
||||
}
|
||||
|
||||
|
||||
if (zend_hash_find(ht, "keep_alive", sizeof("keep_alive"), (void**)&tmp) == SUCCESS &&
|
||||
(Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) && Z_LVAL_PP(tmp) == 0) {
|
||||
add_property_long(this_ptr, "_keep_alive", 0);
|
||||
@ -2606,7 +2606,7 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
|
||||
xmlFree(buf);
|
||||
if (ret && zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2903,8 +2903,10 @@ PHP_METHOD(SoapClient, __call)
|
||||
}
|
||||
zend_hash_internal_pointer_reset(default_headers);
|
||||
while (zend_hash_get_current_data(default_headers, (void**)&tmp) == SUCCESS) {
|
||||
Z_ADDREF_PP(tmp);
|
||||
zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL);
|
||||
if(Z_TYPE_PP(tmp) == IS_OBJECT) {
|
||||
Z_ADDREF_PP(tmp);
|
||||
zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
zend_hash_move_forward(default_headers);
|
||||
}
|
||||
} else {
|
||||
@ -2912,7 +2914,7 @@ PHP_METHOD(SoapClient, __call)
|
||||
free_soap_headers = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
|
||||
|
||||
if (arg_count > 0) {
|
||||
@ -2978,7 +2980,7 @@ PHP_METHOD(SoapClient, __getTypes)
|
||||
HashPosition pos;
|
||||
|
||||
FETCH_THIS_SDL(sdl);
|
||||
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
@ -3007,7 +3009,7 @@ PHP_METHOD(SoapClient, __getTypes)
|
||||
PHP_METHOD(SoapClient, __getLastRequest)
|
||||
{
|
||||
zval **tmp;
|
||||
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
@ -3030,7 +3032,7 @@ PHP_METHOD(SoapClient, __getLastResponse)
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response"), (void **)&tmp) == SUCCESS &&
|
||||
Z_TYPE_PP(tmp) == IS_STRING) {
|
||||
RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
|
||||
@ -3045,11 +3047,11 @@ PHP_METHOD(SoapClient, __getLastResponse)
|
||||
PHP_METHOD(SoapClient, __getLastRequestHeaders)
|
||||
{
|
||||
zval **tmp;
|
||||
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__last_request_headers", sizeof("__last_request_headers"), (void **)&tmp) == SUCCESS &&
|
||||
Z_TYPE_PP(tmp) == IS_STRING) {
|
||||
RETURN_STRINGL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), 1);
|
||||
@ -3064,7 +3066,7 @@ PHP_METHOD(SoapClient, __getLastRequestHeaders)
|
||||
PHP_METHOD(SoapClient, __getLastResponseHeaders)
|
||||
{
|
||||
zval **tmp;
|
||||
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
@ -3209,10 +3211,10 @@ PHP_METHOD(SoapClient, __setSoapHeaders)
|
||||
|
||||
|
||||
/* {{{ proto string SoapClient::__setLocation([string new_location])
|
||||
Sets the location option (the endpoint URL that will be touched by the
|
||||
Sets the location option (the endpoint URL that will be touched by the
|
||||
following SOAP requests).
|
||||
If new_location is not specified or null then SoapClient will use endpoint
|
||||
from WSDL file.
|
||||
from WSDL file.
|
||||
The function returns old value of location options. */
|
||||
PHP_METHOD(SoapClient, __setLocation)
|
||||
{
|
||||
@ -3261,10 +3263,10 @@ static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, cha
|
||||
if (Z_TYPE_P(obj) != IS_OBJECT) {
|
||||
object_init_ex(obj, soap_fault_class_entry);
|
||||
}
|
||||
|
||||
|
||||
add_property_string(obj, "faultstring", fault_string ? fault_string : "", 1);
|
||||
zend_update_property_string(zend_exception_get_default(TSRMLS_C), obj, "message", sizeof("message")-1, (fault_string ? fault_string : "") TSRMLS_CC);
|
||||
|
||||
|
||||
if (fault_code != NULL) {
|
||||
int soap_version = SOAP_GLOBAL(soap_version);
|
||||
|
||||
@ -3689,7 +3691,7 @@ ignore_header:
|
||||
func = func->children;
|
||||
}
|
||||
deserialize_parameters(func, function, num_params, parameters TSRMLS_CC);
|
||||
|
||||
|
||||
encode_finish();
|
||||
|
||||
return function;
|
||||
@ -3971,8 +3973,8 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
|
||||
}
|
||||
|
||||
if (fault_ns == NULL &&
|
||||
fault &&
|
||||
fault->details &&
|
||||
fault &&
|
||||
fault->details &&
|
||||
zend_hash_num_elements(fault->details) == 1) {
|
||||
sdlParamPtr sparam;
|
||||
|
||||
@ -3996,7 +3998,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
|
||||
xmlChar *code = xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0);
|
||||
xmlNodeSetContent(node, code);
|
||||
xmlFree(code);
|
||||
} else {
|
||||
} else {
|
||||
xmlNodeSetContentLen(node, BAD_CAST(str), (int)new_len);
|
||||
}
|
||||
efree(str);
|
||||
@ -4022,7 +4024,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
|
||||
xmlChar *code = xmlBuildQName(BAD_CAST(str), nsptr->prefix, NULL, 0);
|
||||
xmlNodeSetContent(node, code);
|
||||
xmlFree(code);
|
||||
} else {
|
||||
} else {
|
||||
xmlNodeSetContentLen(node, BAD_CAST(str), (int)new_len);
|
||||
}
|
||||
efree(str);
|
||||
@ -4194,7 +4196,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
|
||||
|
||||
encode_finish();
|
||||
|
||||
if (function && function->responseName == NULL &&
|
||||
if (function && function->responseName == NULL &&
|
||||
body->children == NULL && head == NULL) {
|
||||
xmlFreeDoc(doc);
|
||||
return NULL;
|
||||
@ -4328,11 +4330,18 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
|
||||
if (head) {
|
||||
zval** header;
|
||||
|
||||
zend_hash_internal_pointer_reset(soap_headers);
|
||||
while (zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS) {
|
||||
HashTable *ht = Z_OBJPROP_PP(header);
|
||||
for(zend_hash_internal_pointer_reset(soap_headers);
|
||||
zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS;
|
||||
zend_hash_move_forward(soap_headers)
|
||||
) {
|
||||
HashTable *ht;
|
||||
zval **name, **ns, **tmp;
|
||||
|
||||
if (Z_TYPE_PP(header) != IS_OBJECT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ht = Z_OBJPROP_PP(header);
|
||||
if (zend_hash_find(ht, "name", sizeof("name"), (void**)&name) == SUCCESS &&
|
||||
Z_TYPE_PP(name) == IS_STRING &&
|
||||
zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&ns) == SUCCESS &&
|
||||
@ -4371,7 +4380,6 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
|
||||
xmlSetNs(h, nsptr);
|
||||
set_soap_header_attributes(h, ht, version);
|
||||
}
|
||||
zend_hash_move_forward(soap_headers);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4482,7 +4490,7 @@ static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int inde
|
||||
return *tmp;
|
||||
} else {
|
||||
HashPosition pos;
|
||||
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
||||
while (zend_hash_get_current_data_ex(ht, (void **)&tmp, &pos) != FAILURE) {
|
||||
if ((*tmp)->paramName && strcmp(param_name, (*tmp)->paramName) == 0) {
|
||||
|
17
ext/soap/tests/bug70388.phpt
Normal file
17
ext/soap/tests/bug70388.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #70388 (SOAP serialize_function_call() type confusion / RCE)
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$dummy = unserialize('O:10:"SoapClient":3:{s:3:"uri";s:1:"X";s:8:"location";s:22:"http://localhost/a.xml";s:17:"__default_headers";a:1:{i:1;s:1337:"'.str_repeat("X", 1337).'";}}');
|
||||
try {
|
||||
var_dump($dummy->notexisting());
|
||||
} catch(Exception $e) {
|
||||
var_dump($e->getMessage());
|
||||
var_dump(get_class($e));
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(%d) "%s"
|
||||
string(9) "SoapFault"
|
Loading…
Reference in New Issue
Block a user