@@ -1274,12 +1274,11 @@ PHP_METHOD(SoapServer, handle)
12741274 sdlPtr old_sdl = NULL ;
12751275 soapServicePtr service ;
12761276 xmlDocPtr doc_request = NULL , doc_return = NULL ;
1277- zval function_name , * params , * soap_obj , retval ;
1277+ zval function_name , * params , retval ;
12781278 char cont_len [30 ];
12791279 uint32_t num_params = 0 ;
1280- int size , i , call_status = 0 ;
1280+ int size , i ;
12811281 xmlChar * buf ;
1282- HashTable * function_table ;
12831282 soapHeader * soap_headers = NULL ;
12841283 sdlFunctionPtr function ;
12851284 char * arg = NULL ;
@@ -1454,10 +1453,15 @@ PHP_METHOD(SoapServer, handle)
14541453
14551454 service -> soap_headers_ptr = & soap_headers ;
14561455
1457- soap_obj = NULL ;
1456+ zval * soap_obj = NULL ;
1457+ zend_object * soap_zobj = NULL ;
1458+ zend_class_entry * soap_obj_ce = NULL ;
1459+ HashTable * function_table ;
14581460 if (service -> type == SOAP_OBJECT ) {
14591461 soap_obj = & service -> soap_object ;
1460- function_table = & ((Z_OBJCE_P (soap_obj ))-> function_table );
1462+ soap_zobj = Z_OBJ_P (soap_obj );
1463+ soap_obj_ce = Z_OBJCE_P (soap_obj );
1464+ function_table = & soap_obj_ce -> function_table ;
14611465 } else if (service -> type == SOAP_CLASS ) {
14621466 /* If persistent then set soap_obj from the previous created session (if available) */
14631467#ifdef SOAP_HAS_SESSION_SUPPORT
@@ -1515,7 +1519,9 @@ PHP_METHOD(SoapServer, handle)
15151519 soap_obj = & tmp_soap ;
15161520 }
15171521 }
1518- function_table = & ((Z_OBJCE_P (soap_obj ))-> function_table );
1522+ soap_zobj = Z_OBJ_P (soap_obj );
1523+ soap_obj_ce = Z_OBJCE_P (soap_obj );
1524+ function_table = & soap_obj_ce -> function_table ;
15191525 } else {
15201526 if (service -> soap_functions .functions_all ) {
15211527 function_table = EG (function_table );
@@ -1540,44 +1546,52 @@ PHP_METHOD(SoapServer, handle)
15401546 }
15411547 }
15421548#endif
1543- if (zend_hash_find_ptr_lc (function_table , Z_STR (h -> function_name )) != NULL ||
1544- ((service -> type == SOAP_CLASS || service -> type == SOAP_OBJECT ) &&
1545- zend_hash_str_exists (function_table , ZEND_CALL_FUNC_NAME , sizeof (ZEND_CALL_FUNC_NAME )- 1 ))) {
1546- call_status = call_user_function (NULL , soap_obj , & h -> function_name , & h -> retval , h -> num_params , h -> parameters );
1547- if (call_status != SUCCESS ) {
1548- php_error_docref (NULL , E_WARNING , "Function '%s' call failed" , Z_STRVAL (h -> function_name ));
1549- return ;
1549+ zend_function * header_fn = zend_hash_find_ptr_lc (function_table , Z_STR (h -> function_name ));
1550+ if (UNEXPECTED (header_fn == NULL )) {
1551+ if (soap_obj_ce && soap_obj_ce -> __call ) {
1552+ header_fn = zend_get_call_trampoline_func (soap_obj_ce , Z_STR (function_name ), false);
1553+ goto soap_header_func_call ;
15501554 }
1551- if (Z_TYPE (h -> retval ) == IS_OBJECT &&
1552- instanceof_function (Z_OBJCE (h -> retval ), soap_fault_class_entry )) {
1553- php_output_discard ();
1554- soap_server_fault_ex (function , & h -> retval , h );
1555- if (service -> type == SOAP_CLASS && soap_obj ) {zval_ptr_dtor (soap_obj );}
1556- goto fail ;
1557- } else if (EG (exception )) {
1558- php_output_discard ();
1559- _soap_server_exception (service , function , ZEND_THIS );
1560- if (service -> type == SOAP_CLASS && soap_obj ) {zval_ptr_dtor (soap_obj );}
1555+ if (h -> mustUnderstand ) {
1556+ soap_server_fault_en ("MustUnderstand" ,"Header not understood" , NULL , NULL , NULL );
15611557 goto fail ;
15621558 }
1563- } else if (h -> mustUnderstand ) {
1564- soap_server_fault_en ("MustUnderstand" ,"Header not understood" , NULL , NULL , NULL );
1559+ continue ;
1560+ }
1561+
1562+ soap_header_func_call :
1563+ zend_call_known_function (header_fn , soap_zobj , soap_obj_ce , & h -> retval , h -> num_params , h -> parameters , NULL );
1564+ if (Z_TYPE (h -> retval ) == IS_OBJECT &&
1565+ instanceof_function (Z_OBJCE (h -> retval ), soap_fault_class_entry )) {
1566+ php_output_discard ();
1567+ soap_server_fault_ex (function , & h -> retval , h );
1568+ if (service -> type == SOAP_CLASS && soap_obj ) {zval_ptr_dtor (soap_obj );}
1569+ goto fail ;
1570+ } else if (EG (exception )) {
1571+ php_output_discard ();
1572+ _soap_server_exception (service , function , ZEND_THIS );
1573+ if (service -> type == SOAP_CLASS && soap_obj ) {zval_ptr_dtor (soap_obj );}
1574+ goto fail ;
15651575 }
15661576 }
15671577 }
15681578
1569- if (zend_hash_find_ptr_lc (function_table , Z_STR (function_name )) != NULL ||
1570- ((service -> type == SOAP_CLASS || service -> type == SOAP_OBJECT ) &&
1571- zend_hash_str_exists (function_table , ZEND_CALL_FUNC_NAME , sizeof (ZEND_CALL_FUNC_NAME )- 1 ))) {
1572- call_status = call_user_function (NULL , soap_obj , & function_name , & retval , num_params , params );
1573- if (service -> type == SOAP_CLASS ) {
1574- if (service -> soap_class .persistence != SOAP_PERSISTENCE_SESSION ) {
1575- zval_ptr_dtor (soap_obj );
1576- soap_obj = NULL ;
1577- }
1579+ zend_function * fn = zend_hash_find_ptr_lc (function_table , Z_STR (function_name ));
1580+ if (UNEXPECTED (fn == NULL )) {
1581+ if (soap_obj_ce && soap_obj_ce -> __call ) {
1582+ fn = zend_get_call_trampoline_func (soap_obj_ce , Z_STR (function_name ), false);
1583+ } else {
1584+ php_error (E_ERROR , "Function '%s' doesn't exist" , Z_STRVAL (function_name ));
1585+ goto fail ;
1586+ }
1587+ }
1588+ zend_call_known_function (fn , soap_zobj , soap_obj_ce , & retval , num_params , params , NULL );
1589+
1590+ if (service -> type == SOAP_CLASS ) {
1591+ if (service -> soap_class .persistence != SOAP_PERSISTENCE_SESSION ) {
1592+ zval_ptr_dtor (soap_obj );
1593+ soap_obj = NULL ;
15781594 }
1579- } else {
1580- php_error (E_ERROR , "Function '%s' doesn't exist" , Z_STRVAL (function_name ));
15811595 }
15821596
15831597 if (EG (exception )) {
@@ -1593,32 +1607,27 @@ PHP_METHOD(SoapServer, handle)
15931607 goto fail ;
15941608 }
15951609
1596- if (call_status == SUCCESS ) {
1597- char * response_name ;
1598-
1599- if (Z_TYPE (retval ) == IS_OBJECT &&
1600- instanceof_function (Z_OBJCE (retval ), soap_fault_class_entry )) {
1601- php_output_discard ();
1602- soap_server_fault_ex (function , & retval , NULL );
1603- goto fail ;
1604- }
1610+ char * response_name ;
16051611
1606- bool has_response_name = function && function -> responseName ;
1607- if (has_response_name ) {
1608- response_name = function -> responseName ;
1609- } else {
1610- response_name = emalloc (Z_STRLEN (function_name ) + sizeof ("Response" ));
1611- memcpy (response_name ,Z_STRVAL (function_name ),Z_STRLEN (function_name ));
1612- memcpy (response_name + Z_STRLEN (function_name ),"Response" ,sizeof ("Response" ));
1613- }
1614- doc_return = serialize_response_call (function , response_name , service -> uri , & retval , soap_headers , soap_version );
1612+ if (Z_TYPE (retval ) == IS_OBJECT &&
1613+ instanceof_function (Z_OBJCE (retval ), soap_fault_class_entry )) {
1614+ php_output_discard ();
1615+ soap_server_fault_ex (function , & retval , NULL );
1616+ goto fail ;
1617+ }
16151618
1616- if (! has_response_name ) {
1617- efree ( response_name );
1618- }
1619+ bool has_response_name = function && function -> responseName ;
1620+ if ( has_response_name ) {
1621+ response_name = function -> responseName ;
16191622 } else {
1620- php_error_docref (NULL , E_WARNING , "Function '%s' call failed" , Z_STRVAL (function_name ));
1621- return ;
1623+ response_name = emalloc (Z_STRLEN (function_name ) + sizeof ("Response" ));
1624+ memcpy (response_name ,Z_STRVAL (function_name ),Z_STRLEN (function_name ));
1625+ memcpy (response_name + Z_STRLEN (function_name ),"Response" ,sizeof ("Response" ));
1626+ }
1627+ doc_return = serialize_response_call (function , response_name , service -> uri , & retval , soap_headers , soap_version );
1628+
1629+ if (!has_response_name ) {
1630+ efree (response_name );
16221631 }
16231632
16241633 if (EG (exception )) {
0 commit comments