@@ -1383,12 +1383,11 @@ PHP_METHOD(SoapServer, handle)
13831383 sdlPtr old_sdl = NULL ;
13841384 soapServicePtr service ;
13851385 xmlDocPtr doc_request = NULL , doc_return = NULL ;
1386- zval function_name , * params , * soap_obj , retval ;
1386+ zval function_name , * params , retval ;
13871387 char cont_len [30 ];
13881388 uint32_t num_params = 0 ;
1389- int size , i , call_status = 0 ;
1389+ int size , i ;
13901390 xmlChar * buf ;
1391- HashTable * function_table ;
13921391 soapHeader * soap_headers = NULL ;
13931392 sdlFunctionPtr function ;
13941393 char * arg = NULL ;
@@ -1563,10 +1562,10 @@ PHP_METHOD(SoapServer, handle)
15631562
15641563 service -> soap_headers_ptr = & soap_headers ;
15651564
1566- soap_obj = NULL ;
1565+ zval * soap_obj = NULL ;
1566+ HashTable * function_table = NULL ;
15671567 if (service -> type == SOAP_OBJECT ) {
15681568 soap_obj = & service -> soap_object ;
1569- function_table = & ((Z_OBJCE_P (soap_obj ))-> function_table );
15701569 } else if (service -> type == SOAP_CLASS ) {
15711570 /* If persistent then set soap_obj from the previous created session (if available) */
15721571#ifdef SOAP_HAS_SESSION_SUPPORT
@@ -1590,7 +1589,7 @@ PHP_METHOD(SoapServer, handle)
15901589 }
15911590#endif
15921591
1593- /* If new session or something weird happned */
1592+ /* If new session or something weird happened */
15941593 if (soap_obj == NULL ) {
15951594 if (UNEXPECTED (object_init_ex (& tmp_soap , service -> soap_class .ce ) != SUCCESS )) {
15961595 php_output_discard ();
@@ -1628,7 +1627,6 @@ PHP_METHOD(SoapServer, handle)
16281627 soap_obj = & tmp_soap ;
16291628 }
16301629 }
1631- function_table = & ((Z_OBJCE_P (soap_obj ))-> function_table );
16321630 } else {
16331631 if (service -> soap_functions .functions_all ) {
16341632 function_table = EG (function_table );
@@ -1653,41 +1651,69 @@ PHP_METHOD(SoapServer, handle)
16531651 }
16541652 }
16551653#endif
1656- if (zend_hash_find_ptr_lc (function_table , Z_STR (h -> function_name )) != NULL ||
1657- ((service -> type == SOAP_CLASS || service -> type == SOAP_OBJECT ) &&
1658- zend_hash_str_exists (function_table , ZEND_CALL_FUNC_NAME , sizeof (ZEND_CALL_FUNC_NAME )- 1 ))) {
1659- call_status = call_user_function (NULL , soap_obj , & h -> function_name , & h -> retval , h -> num_params , h -> parameters );
1660- if (call_status != SUCCESS ) {
1661- php_error_docref (NULL , E_WARNING , "Function '%s' call failed" , Z_STRVAL (h -> function_name ));
1662- return ;
1654+ if (soap_obj ) {
1655+ /* This is because the object might define a __call() magic method */
1656+ zend_result method_call_result = zend_call_method_if_exists (Z_OBJ_P (soap_obj ), Z_STR (h -> function_name ), & h -> retval , h -> num_params , h -> parameters );
1657+ if (UNEXPECTED (method_call_result == FAILURE )) {
1658+ if (h -> mustUnderstand ) {
1659+ soap_server_fault_en ("MustUnderstand" ,"Header not understood" );
1660+ goto fail ;
1661+ }
1662+ ZVAL_NULL (& h -> retval );
1663+ continue ;
16631664 }
1664- if (Z_TYPE (h -> retval ) == IS_OBJECT &&
1665- instanceof_function (Z_OBJCE (h -> retval ), soap_fault_class_entry )) {
1666- php_output_discard ();
1667- soap_server_fault_ex (function , & h -> retval , h );
1668- soap_free_server_object (service , soap_obj );
1669- goto fail ;
1670- } else if (EG (exception )) {
1671- php_output_discard ();
1672- _soap_server_exception (service , function , ZEND_THIS );
1673- soap_free_server_object (service , soap_obj );
1674- goto fail ;
1665+ } else {
1666+ zend_function * header_fn = zend_hash_find_ptr_lc (function_table , Z_STR (h -> function_name ));
1667+ if (UNEXPECTED (header_fn == NULL )) {
1668+ if (h -> mustUnderstand ) {
1669+ soap_server_fault_en ("MustUnderstand" ,"Header not understood" );
1670+ goto fail ;
1671+ }
1672+ ZVAL_NULL (& h -> retval );
1673+ continue ;
16751674 }
1676- } else if (h -> mustUnderstand ) {
1677- soap_server_fault_en ("MustUnderstand" ,"Header not understood" );
1675+ zend_call_known_function (header_fn , NULL , NULL , & h -> retval , h -> num_params , h -> parameters , NULL );
1676+ }
1677+
1678+ if (Z_TYPE (h -> retval ) == IS_OBJECT &&
1679+ instanceof_function (Z_OBJCE (h -> retval ), soap_fault_class_entry )) {
1680+ php_output_discard ();
1681+ soap_server_fault_ex (function , & h -> retval , h );
1682+ soap_free_server_object (service , soap_obj );
1683+ goto fail ;
1684+ } else if (EG (exception )) {
1685+ php_output_discard ();
1686+ _soap_server_exception (service , function , ZEND_THIS );
1687+ soap_free_server_object (service , soap_obj );
1688+ goto fail ;
16781689 }
16791690 }
16801691 }
16811692
1682- if (zend_hash_find_ptr_lc (function_table , Z_STR (function_name )) != NULL ||
1683- ((service -> type == SOAP_CLASS || service -> type == SOAP_OBJECT ) &&
1684- zend_hash_str_exists (function_table , ZEND_CALL_FUNC_NAME , sizeof (ZEND_CALL_FUNC_NAME )- 1 ))) {
1685- call_status = call_user_function (NULL , soap_obj , & function_name , & retval , num_params , params );
1686- soap_free_server_object (service , soap_obj );
1693+ if (soap_obj ) {
1694+ /* This is because the object might define a __call() magic method */
1695+ zend_result method_call_result = zend_call_method_if_exists (Z_OBJ_P (soap_obj ), Z_STR (function_name ), & retval , num_params , params );
1696+ if (UNEXPECTED (method_call_result == FAILURE )) {
1697+ zend_throw_error (NULL , "Call to undefined method %s::%s()" , ZSTR_VAL (Z_OBJCE_P (soap_obj )-> name ), Z_STRVAL (function_name ));
1698+ php_output_discard ();
1699+ _soap_server_exception (service , function , ZEND_THIS );
1700+ soap_free_server_object (service , soap_obj );
1701+ goto fail ;
1702+ }
16871703 } else {
1688- php_error (E_ERROR , "Function '%s' doesn't exist" , Z_STRVAL (function_name ));
1704+ zend_function * fn = zend_hash_find_ptr_lc (function_table , Z_STR (function_name ));
1705+ if (UNEXPECTED (fn == NULL )) {
1706+ zend_throw_error (NULL , "Call to undefined function %s()" , Z_STRVAL (function_name ));
1707+ php_output_discard ();
1708+ _soap_server_exception (service , function , ZEND_THIS );
1709+ soap_free_server_object (service , soap_obj );
1710+ goto fail ;
1711+ }
1712+ zend_call_known_function (fn , NULL , NULL , & retval , num_params , params , NULL );
16891713 }
16901714
1715+ soap_free_server_object (service , soap_obj );
1716+
16911717 if (EG (exception )) {
16921718 if (!zend_is_unwind_exit (EG (exception ))) {
16931719 php_output_discard ();
@@ -1697,32 +1723,27 @@ PHP_METHOD(SoapServer, handle)
16971723 goto fail ;
16981724 }
16991725
1700- if (call_status == SUCCESS ) {
1701- char * response_name ;
1726+ char * response_name ;
17021727
1703- if (Z_TYPE (retval ) == IS_OBJECT &&
1704- instanceof_function (Z_OBJCE (retval ), soap_fault_class_entry )) {
1705- php_output_discard ();
1706- soap_server_fault_ex (function , & retval , NULL );
1707- goto fail ;
1708- }
1709-
1710- bool has_response_name = function && function -> responseName ;
1711- if (has_response_name ) {
1712- response_name = function -> responseName ;
1713- } else {
1714- response_name = emalloc (Z_STRLEN (function_name ) + sizeof ("Response" ));
1715- memcpy (response_name ,Z_STRVAL (function_name ),Z_STRLEN (function_name ));
1716- memcpy (response_name + Z_STRLEN (function_name ),"Response" ,sizeof ("Response" ));
1717- }
1718- doc_return = serialize_response_call (function , response_name , service -> uri , & retval , soap_headers , soap_version );
1728+ if (Z_TYPE (retval ) == IS_OBJECT &&
1729+ instanceof_function (Z_OBJCE (retval ), soap_fault_class_entry )) {
1730+ php_output_discard ();
1731+ soap_server_fault_ex (function , & retval , NULL );
1732+ goto fail ;
1733+ }
17191734
1720- if (! has_response_name ) {
1721- efree ( response_name );
1722- }
1735+ bool has_response_name = function && function -> responseName ;
1736+ if ( has_response_name ) {
1737+ response_name = function -> responseName ;
17231738 } else {
1724- php_error_docref (NULL , E_WARNING , "Function '%s' call failed" , Z_STRVAL (function_name ));
1725- return ;
1739+ response_name = emalloc (Z_STRLEN (function_name ) + sizeof ("Response" ));
1740+ memcpy (response_name ,Z_STRVAL (function_name ),Z_STRLEN (function_name ));
1741+ memcpy (response_name + Z_STRLEN (function_name ),"Response" ,sizeof ("Response" ));
1742+ }
1743+ doc_return = serialize_response_call (function , response_name , service -> uri , & retval , soap_headers , soap_version );
1744+
1745+ if (!has_response_name ) {
1746+ efree (response_name );
17261747 }
17271748
17281749 if (EG (exception )) {
0 commit comments