mirror of
https://github.com/php/php-src.git
synced 2025-01-18 09:43:36 +08:00
Bug #36226 Inconsistent handling when passing potential arrays
This commit is contained in:
parent
6a176fa7b3
commit
7dc9be77fc
2
NEWS
2
NEWS
@ -22,6 +22,8 @@ PHP NEWS
|
||||
- Fixed bug #36242 (Possible memory corruption in stream_select()). (Tony)
|
||||
- Fixed bug #36235 (ocicolumnname returns false before a succesfull fetch).
|
||||
(Tony)
|
||||
- Fixed bug #36226 (Inconsistent handling when passing potential arrays).
|
||||
(Dmitry)
|
||||
- Fixed bug #36224 (date(DATE_ATOM) gives wrong results). (Derick, Hannes
|
||||
Magnusson)
|
||||
- Fixed bug #36222 (errorInfo in PDOException is always NULL). (Ilia)
|
||||
|
@ -1157,6 +1157,14 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr
|
||||
add_next_index_zval(array, val);
|
||||
} while ((node = get_node(node->next, model->u.element->name)) != NULL);
|
||||
val = array;
|
||||
} else if ((SOAP_GLOBAL(features) & SOAP_SINGLE_ELEMENT_ARRAYS) &&
|
||||
(model->max_occurs == -1 || model->max_occurs > 1)) {
|
||||
zval *array;
|
||||
|
||||
MAKE_STD_ZVAL(array);
|
||||
array_init(array);
|
||||
add_next_index_zval(array, val);
|
||||
val = array;
|
||||
}
|
||||
set_zval_property(ret, model->u.element->name, val TSRMLS_CC);
|
||||
}
|
||||
|
@ -119,6 +119,7 @@ struct _soapService {
|
||||
char *uri;
|
||||
xmlCharEncodingHandlerPtr encoding;
|
||||
HashTable *class_map;
|
||||
int features;
|
||||
};
|
||||
|
||||
#define SOAP_CLASS 1
|
||||
@ -151,6 +152,8 @@ struct _soapService {
|
||||
#define SOAP_AUTHENTICATION_BASIC 0
|
||||
#define SOAP_AUTHENTICATION_DIGEST 1
|
||||
|
||||
#define SOAP_SINGLE_ELEMENT_ARRAYS (1<<0)
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(soap)
|
||||
HashTable defEncNs; /* mapping of default namespaces to prefixes */
|
||||
HashTable defEnc;
|
||||
@ -167,6 +170,7 @@ ZEND_BEGIN_MODULE_GLOBALS(soap)
|
||||
long cache_ttl;
|
||||
xmlCharEncodingHandlerPtr encoding;
|
||||
HashTable *class_map;
|
||||
int features;
|
||||
ZEND_END_MODULE_GLOBALS(soap)
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
|
@ -479,6 +479,7 @@ PHP_RINIT_FUNCTION(soap)
|
||||
SOAP_GLOBAL(soap_version) = SOAP_1_1;
|
||||
SOAP_GLOBAL(encoding) = NULL;
|
||||
SOAP_GLOBAL(class_map) = NULL;
|
||||
SOAP_GLOBAL(features) = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -633,6 +634,8 @@ PHP_MINIT_FUNCTION(soap)
|
||||
REGISTER_STRING_CONSTANT("XSD_NAMESPACE", XSD_NAMESPACE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("XSD_1999_NAMESPACE", XSD_1999_NAMESPACE, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("SOAP_SINGLE_ELEMENT_ARRAYS", SOAP_SINGLE_ELEMENT_ARRAYS, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
old_error_handler = zend_error_cb;
|
||||
zend_error_cb = soap_error_handler;
|
||||
|
||||
@ -957,6 +960,11 @@ PHP_METHOD(SoapServer, SoapServer)
|
||||
zend_hash_copy(service->class_map, (*tmp)->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &ztmp, sizeof(zval *));
|
||||
}
|
||||
|
||||
if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS &&
|
||||
Z_TYPE_PP(tmp) == IS_LONG) {
|
||||
service->features = Z_LVAL_PP(tmp);
|
||||
}
|
||||
|
||||
} else if (wsdl == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments. 'uri' option is required in nonWSDL mode.");
|
||||
}
|
||||
@ -1358,6 +1366,7 @@ PHP_METHOD(SoapServer, handle)
|
||||
int arg_len;
|
||||
xmlCharEncodingHandlerPtr old_encoding;
|
||||
HashTable *old_class_map;
|
||||
int old_features;
|
||||
|
||||
SOAP_SERVER_BEGIN_CODE();
|
||||
|
||||
@ -1503,6 +1512,8 @@ PHP_METHOD(SoapServer, handle)
|
||||
SOAP_GLOBAL(encoding) = service->encoding;
|
||||
old_class_map = SOAP_GLOBAL(class_map);
|
||||
SOAP_GLOBAL(class_map) = service->class_map;
|
||||
old_features = SOAP_GLOBAL(features);
|
||||
SOAP_GLOBAL(features) = service->features;
|
||||
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);
|
||||
@ -1773,6 +1784,7 @@ fail:
|
||||
SOAP_GLOBAL(encoding) = old_encoding;
|
||||
SOAP_GLOBAL(sdl) = old_sdl;
|
||||
SOAP_GLOBAL(class_map) = old_class_map;
|
||||
SOAP_GLOBAL(features) = old_features;
|
||||
|
||||
/* Free soap headers */
|
||||
zval_dtor(&retval);
|
||||
@ -2189,6 +2201,11 @@ PHP_METHOD(SoapClient, SoapClient)
|
||||
add_property_zval(this_ptr, "_classmap", class_map);
|
||||
}
|
||||
|
||||
if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS &&
|
||||
Z_TYPE_PP(tmp) == IS_ARRAY) {
|
||||
add_property_long(this_ptr, "_features", Z_LVAL_PP(tmp));
|
||||
}
|
||||
|
||||
if (zend_hash_find(ht, "connection_timeout", sizeof("connection_timeout"), (void**)&tmp) == SUCCESS &&
|
||||
Z_TYPE_PP(tmp) == IS_LONG && Z_LVAL_PP(tmp) > 0) {
|
||||
add_property_long(this_ptr, "_connection_timeout", Z_LVAL_PP(tmp));
|
||||
@ -2313,6 +2330,7 @@ static void do_soap_call(zval* this_ptr,
|
||||
zval response;
|
||||
xmlCharEncodingHandlerPtr old_encoding;
|
||||
HashTable *old_class_map;
|
||||
int old_features;
|
||||
|
||||
SOAP_CLIENT_BEGIN_CODE();
|
||||
|
||||
@ -2358,6 +2376,13 @@ static void do_soap_call(zval* this_ptr,
|
||||
} else {
|
||||
SOAP_GLOBAL(class_map) = NULL;
|
||||
}
|
||||
old_features = SOAP_GLOBAL(features);
|
||||
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_features", sizeof("_features"), (void **) &tmp) == SUCCESS &&
|
||||
Z_TYPE_PP(tmp) == IS_LONG) {
|
||||
SOAP_GLOBAL(features) = Z_LVAL_PP(tmp);
|
||||
} else {
|
||||
SOAP_GLOBAL(features) = 0;
|
||||
}
|
||||
|
||||
if (sdl != NULL) {
|
||||
fn = get_function(sdl, function);
|
||||
@ -2458,10 +2483,11 @@ static void do_soap_call(zval* this_ptr,
|
||||
zend_throw_exception_object(exception TSRMLS_CC);
|
||||
}
|
||||
#endif
|
||||
if (SOAP_GLOBAL(encoding) != NULL) {
|
||||
if (SOAP_GLOBAL(encoding) != NULL) {
|
||||
xmlCharEncCloseFunc(SOAP_GLOBAL(encoding));
|
||||
}
|
||||
SOAP_GLOBAL(class_map) = old_class_map;
|
||||
}
|
||||
SOAP_GLOBAL(features) = old_features;
|
||||
SOAP_GLOBAL(class_map) = old_class_map;
|
||||
SOAP_GLOBAL(encoding) = old_encoding;
|
||||
SOAP_GLOBAL(sdl) = old_sdl;
|
||||
SOAP_CLIENT_END_CODE();
|
||||
|
139
ext/soap/tests/bugs/bug36226.phpt
Executable file
139
ext/soap/tests/bugs/bug36226.phpt
Executable file
@ -0,0 +1,139 @@
|
||||
--TEST--
|
||||
Bug #36226 SOAP Inconsistent handling when passing potential arrays.
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--INI--
|
||||
soap.wsdl_cache_enabled=0
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("soap.wsdl_cache_enabled",0);
|
||||
$timestamp = "2005-11-08T11:22:07+03:00";
|
||||
$wsdl = dirname(__FILE__)."/bug35142.wsdl";
|
||||
|
||||
function PostEvents($x) {
|
||||
var_dump($x);
|
||||
exit();
|
||||
return $x;
|
||||
}
|
||||
|
||||
class TestSoapClient extends SoapClient {
|
||||
|
||||
function __construct($wsdl, $options) {
|
||||
parent::__construct($wsdl, $options);
|
||||
$this->server = new SoapServer($wsdl, $options);
|
||||
$this->server->addFunction('PostEvents');
|
||||
}
|
||||
|
||||
function __doRequest($request, $location, $action, $version) {
|
||||
echo "$request\n";
|
||||
$this->server->handle($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$soapClient = new TestSoapClient($wsdl,
|
||||
array('trace' => 1, 'exceptions' => 0,
|
||||
'classmap' => array('logOnEvent' => 'LogOnEvent',
|
||||
'logOffEvent' => 'LogOffEvent',
|
||||
'events' => 'IVREvents'),
|
||||
'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
|
||||
|
||||
$logOnEvent = new LogOnEvent(34567, $timestamp);
|
||||
$logOffEvents[] = new LogOffEvent(34567, $timestamp, "Smoked");
|
||||
$logOffEvents[] = new LogOffEvent(34568, $timestamp, "SmokeFree");
|
||||
$ivrEvents = new IVREvents("1.0", 101, 12345, 'IVR', $logOnEvent, $logOffEvents);
|
||||
|
||||
$result = $soapClient->PostEvents($ivrEvents);
|
||||
|
||||
class LogOffEvent {
|
||||
public $audienceMemberId;
|
||||
public $timestamp;
|
||||
public $smokeStatus;
|
||||
public $callInititator;
|
||||
|
||||
function __construct($audienceMemberId, $timestamp, $smokeStatus) {
|
||||
$this->audienceMemberId = $audienceMemberId;
|
||||
$this->timestamp = $timestamp;
|
||||
$this->smokeStatus = $smokeStatus;
|
||||
$this->callInitiator = "IVR";
|
||||
}
|
||||
}
|
||||
|
||||
class LogOnEvent {
|
||||
public $audienceMemberId;
|
||||
public $timestamp;
|
||||
|
||||
function __construct($audienceMemberId, $timestamp) {
|
||||
$this->audienceMemberId = $audienceMemberId;
|
||||
$this->timestamp = $timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
class IVREvents {
|
||||
public $version;
|
||||
public $activityId;
|
||||
public $messageId;
|
||||
public $source;
|
||||
public $logOnEvent;
|
||||
public $logOffEvent;
|
||||
|
||||
function __construct($version, $activityId, $messageId, $source, $logOnEvent=NULL, $logOffEvent=NULL) {
|
||||
$this->version = $version;
|
||||
$this->activityId = $activityId;
|
||||
$this->messageId = $messageId;
|
||||
$this->source = $source;
|
||||
$this->logOnEvent = $logOnEvent;
|
||||
$this->logOffEvent = $logOffEvent;
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testurl/Message"><SOAP-ENV:Body><ns1:ivrEvents version="1.0" activityId="101" messageId="12345" source="IVR"><ns1:logOffEvent audienceMemberId="34567" timestamp="2005-11-08T11:22:07+03:00" smokeStatus="Smoked" callInitiator="IVR"/><ns1:logOffEvent audienceMemberId="34568" timestamp="2005-11-08T11:22:07+03:00" smokeStatus="SmokeFree" callInitiator="IVR"/><ns1:logOnEvent audienceMemberId="34567" timestamp="2005-11-08T11:22:07+03:00"/></ns1:ivrEvents></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
|
||||
object(IVREvents)#%d (6) {
|
||||
["version"]=>
|
||||
string(3) "1.0"
|
||||
["activityId"]=>
|
||||
int(101)
|
||||
["messageId"]=>
|
||||
int(12345)
|
||||
["logOffEvent"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(LogOffEvent)#%d (4) {
|
||||
["audienceMemberId"]=>
|
||||
int(34567)
|
||||
["timestamp"]=>
|
||||
string(25) "2005-11-08T11:22:07+03:00"
|
||||
["smokeStatus"]=>
|
||||
string(6) "Smoked"
|
||||
["callInitiator"]=>
|
||||
string(3) "IVR"
|
||||
}
|
||||
[1]=>
|
||||
object(LogOffEvent)#%d (4) {
|
||||
["audienceMemberId"]=>
|
||||
int(34568)
|
||||
["timestamp"]=>
|
||||
string(25) "2005-11-08T11:22:07+03:00"
|
||||
["smokeStatus"]=>
|
||||
string(9) "SmokeFree"
|
||||
["callInitiator"]=>
|
||||
string(3) "IVR"
|
||||
}
|
||||
}
|
||||
["logOnEvent"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(LogOnEvent)#10 (2) {
|
||||
["audienceMemberId"]=>
|
||||
int(34567)
|
||||
["timestamp"]=>
|
||||
string(25) "2005-11-08T11:22:07+03:00"
|
||||
}
|
||||
}
|
||||
["source"]=>
|
||||
string(3) "IVR"
|
||||
}
|
Loading…
Reference in New Issue
Block a user