@@ -1274,12 +1274,11 @@ PHP_METHOD(SoapServer, handle)
1274
1274
sdlPtr old_sdl = NULL ;
1275
1275
soapServicePtr service ;
1276
1276
xmlDocPtr doc_request = NULL , doc_return = NULL ;
1277
- zval function_name , * params , * soap_obj , retval ;
1277
+ zval function_name , * params , retval ;
1278
1278
char cont_len [30 ];
1279
1279
uint32_t num_params = 0 ;
1280
- int size , i , call_status = 0 ;
1280
+ int size , i ;
1281
1281
xmlChar * buf ;
1282
- HashTable * function_table ;
1283
1282
soapHeader * soap_headers = NULL ;
1284
1283
sdlFunctionPtr function ;
1285
1284
char * arg = NULL ;
@@ -1454,10 +1453,15 @@ PHP_METHOD(SoapServer, handle)
1454
1453
1455
1454
service -> soap_headers_ptr = & soap_headers ;
1456
1455
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 ;
1458
1460
if (service -> type == SOAP_OBJECT ) {
1459
1461
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 ;
1461
1465
} else if (service -> type == SOAP_CLASS ) {
1462
1466
/* If persistent then set soap_obj from the previous created session (if available) */
1463
1467
#ifdef SOAP_HAS_SESSION_SUPPORT
@@ -1515,7 +1519,9 @@ PHP_METHOD(SoapServer, handle)
1515
1519
soap_obj = & tmp_soap ;
1516
1520
}
1517
1521
}
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 ;
1519
1525
} else {
1520
1526
if (service -> soap_functions .functions_all ) {
1521
1527
function_table = EG (function_table );
@@ -1540,44 +1546,52 @@ PHP_METHOD(SoapServer, handle)
1540
1546
}
1541
1547
}
1542
1548
#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 ;
1550
1554
}
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 );
1561
1557
goto fail ;
1562
1558
}
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 ;
1565
1575
}
1566
1576
}
1567
1577
}
1568
1578
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 ;
1578
1594
}
1579
- } else {
1580
- php_error (E_ERROR , "Function '%s' doesn't exist" , Z_STRVAL (function_name ));
1581
1595
}
1582
1596
1583
1597
if (EG (exception )) {
@@ -1593,32 +1607,27 @@ PHP_METHOD(SoapServer, handle)
1593
1607
goto fail ;
1594
1608
}
1595
1609
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 ;
1605
1611
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
+ }
1615
1618
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 ;
1619
1622
} 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 );
1622
1631
}
1623
1632
1624
1633
if (EG (exception )) {
0 commit comments