PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/soap - soap.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 2010 2394 84.0 %
Date: 2016-08-24 Functions: 67 71 94.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2016 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Brad Lafountain <rodif_bl@yahoo.com>                        |
      16             :   |          Shane Caraveo <shane@caraveo.com>                           |
      17             :   |          Dmitry Stogov <dmitry@zend.com>                             |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : /* $Id$ */
      21             : 
      22             : #ifdef HAVE_CONFIG_H
      23             : #include "config.h"
      24             : #endif
      25             : #include "php_soap.h"
      26             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
      27             : #include "ext/session/php_session.h"
      28             : #endif
      29             : #include "zend_exceptions.h"
      30             : 
      31             : 
      32             : static int le_sdl = 0;
      33             : int le_url = 0;
      34             : static int le_service = 0;
      35             : static int le_typemap = 0;
      36             : 
      37             : typedef struct _soapHeader {
      38             :         sdlFunctionPtr                    function;
      39             :         zval                              function_name;
      40             :         int                               mustUnderstand;
      41             :         int                               num_params;
      42             :         zval                             *parameters;
      43             :         zval                              retval;
      44             :         sdlSoapBindingFunctionHeaderPtr   hdr;
      45             :         struct _soapHeader               *next;
      46             : } soapHeader;
      47             : 
      48             : /* Local functions */
      49             : static void function_to_string(sdlFunctionPtr function, smart_str *buf);
      50             : static void type_to_string(sdlTypePtr type, smart_str *buf, int level);
      51             : 
      52             : static void clear_soap_fault(zval *obj);
      53             : static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, char *name);
      54             : static void add_soap_fault_ex(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail);
      55             : static void soap_server_fault(char* code, char* string, char *actor, zval* details, char *name);
      56             : static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader* hdr);
      57             : 
      58             : static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int);
      59             : static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name);
      60             : static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr node);
      61             : 
      62             : static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters, int *version, soapHeader **headers);
      63             : static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function_name,char *uri,zval *ret, soapHeader *headers, int version);
      64             : static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval *arguments, int arg_count, int version, HashTable *soap_headers);
      65             : static xmlNodePtr serialize_parameter(sdlParamPtr param,zval *param_val,int index,char *name, int style, xmlNodePtr parent);
      66             : static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, int style, xmlNodePtr parent);
      67             : 
      68             : static void delete_service(void *service);
      69             : static void delete_url(void *handle);
      70             : static void delete_hashtable(void *hashtable);
      71             : 
      72             : static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args);
      73             : 
      74             : #define SOAP_SERVER_BEGIN_CODE() \
      75             :         zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
      76             :         char* _old_error_code = SOAP_GLOBAL(error_code);\
      77             :         zend_object* _old_error_object = Z_OBJ(SOAP_GLOBAL(error_object));\
      78             :         int _old_soap_version = SOAP_GLOBAL(soap_version);\
      79             :         SOAP_GLOBAL(use_soap_error_handler) = 1;\
      80             :         SOAP_GLOBAL(error_code) = "Server";\
      81             :         Z_OBJ(SOAP_GLOBAL(error_object)) = Z_OBJ(EX(This));
      82             : 
      83             : #define SOAP_SERVER_END_CODE() \
      84             :         SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
      85             :         SOAP_GLOBAL(error_code) = _old_error_code;\
      86             :         Z_OBJ(SOAP_GLOBAL(error_object)) = _old_error_object;\
      87             :         SOAP_GLOBAL(soap_version) = _old_soap_version;
      88             : 
      89             : #define SOAP_CLIENT_BEGIN_CODE() \
      90             :         zend_bool _old_handler = SOAP_GLOBAL(use_soap_error_handler);\
      91             :         char* _old_error_code = SOAP_GLOBAL(error_code);\
      92             :         zend_object* _old_error_object = Z_OBJ(SOAP_GLOBAL(error_object));\
      93             :         int _old_soap_version = SOAP_GLOBAL(soap_version);\
      94             :         zend_bool _old_in_compilation = CG(in_compilation); \
      95             :         zend_execute_data *_old_current_execute_data = EG(current_execute_data); \
      96             :         zval *_old_stack_top = EG(vm_stack_top); \
      97             :         int _bailout = 0;\
      98             :         SOAP_GLOBAL(use_soap_error_handler) = 1;\
      99             :         SOAP_GLOBAL(error_code) = "Client";\
     100             :         Z_OBJ(SOAP_GLOBAL(error_object)) = Z_OBJ(EX(This));\
     101             :         zend_try {
     102             : 
     103             : #define SOAP_CLIENT_END_CODE() \
     104             :         } zend_catch {\
     105             :                 CG(in_compilation) = _old_in_compilation; \
     106             :                 EG(current_execute_data) = _old_current_execute_data; \
     107             :                 if (EG(exception) == NULL || \
     108             :                     !instanceof_function(EG(exception)->ce, soap_fault_class_entry)) {\
     109             :                         _bailout = 1;\
     110             :                 }\
     111             :                 if (_old_stack_top != EG(vm_stack_top)) { \
     112             :                         while (EG(vm_stack)->prev != NULL && \
     113             :                                ((char*)_old_stack_top < (char*)EG(vm_stack) || \
     114             :                                 (char*) _old_stack_top > (char*)EG(vm_stack)->end)) { \
     115             :                                 zend_vm_stack tmp = EG(vm_stack)->prev; \
     116             :                                 efree(EG(vm_stack)); \
     117             :                                 EG(vm_stack) = tmp; \
     118             :                                 EG(vm_stack_end) = tmp->end; \
     119             :                         } \
     120             :                         EG(vm_stack)->top = _old_stack_top; \
     121             :                 } \
     122             :         } zend_end_try();\
     123             :         SOAP_GLOBAL(use_soap_error_handler) = _old_handler;\
     124             :         SOAP_GLOBAL(error_code) = _old_error_code;\
     125             :         Z_OBJ(SOAP_GLOBAL(error_object)) = _old_error_object;\
     126             :         SOAP_GLOBAL(soap_version) = _old_soap_version;\
     127             :         if (_bailout) {\
     128             :                 zend_bailout();\
     129             :         }
     130             : 
     131             : #define FETCH_THIS_SDL(ss) \
     132             :         { \
     133             :                 zval *__tmp; \
     134             :                 if(FIND_SDL_PROPERTY(getThis(), __tmp) != NULL) { \
     135             :                         FETCH_SDL_RES(ss,__tmp); \
     136             :                 } else { \
     137             :                         ss = NULL; \
     138             :                 } \
     139             :         }
     140             : 
     141             : #define FIND_SDL_PROPERTY(ss,tmp) (tmp = zend_hash_str_find(Z_OBJPROP_P(ss), "sdl", sizeof("sdl")-1))
     142             : #define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource_ex(tmp, "sdl", le_sdl)
     143             : 
     144             : #define FIND_TYPEMAP_PROPERTY(ss,tmp) (tmp = zend_hash_str_find(Z_OBJPROP_P(ss), "typemap", sizeof("typemap")-1))
     145             : #define FETCH_TYPEMAP_RES(ss,tmp) ss = (HashTable*) zend_fetch_resource_ex(tmp, "typemap", le_typemap)
     146             : 
     147             : #define FETCH_THIS_SERVICE(ss) \
     148             :         { \
     149             :                 zval *tmp; \
     150             :                 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()),"service", sizeof("service")-1)) != NULL) { \
     151             :                         ss = (soapServicePtr)zend_fetch_resource_ex(tmp, "service", le_service); \
     152             :                 } else { \
     153             :                         php_error_docref(NULL, E_WARNING, "Can not fetch service object"); \
     154             :                         SOAP_SERVER_END_CODE(); \
     155             :                         return; \
     156             :                 } \
     157             :         }
     158             : 
     159             : static zend_class_entry* soap_class_entry;
     160             : static zend_class_entry* soap_server_class_entry;
     161             : static zend_class_entry* soap_fault_class_entry;
     162             : static zend_class_entry* soap_header_class_entry;
     163             : static zend_class_entry* soap_param_class_entry;
     164             : zend_class_entry* soap_var_class_entry;
     165             : 
     166             : ZEND_DECLARE_MODULE_GLOBALS(soap)
     167             : 
     168             : static void (*old_error_handler)(int, const char *, const uint, const char*, va_list);
     169             : 
     170             : #ifdef va_copy
     171             : #define call_old_error_handler(error_num, error_filename, error_lineno, format, args) \
     172             : { \
     173             :         va_list copy; \
     174             :         va_copy(copy, args); \
     175             :         old_error_handler(error_num, error_filename, error_lineno, format, copy); \
     176             :         va_end(copy); \
     177             : }
     178             : #else
     179             : #define call_old_error_handler(error_num, error_filename, error_lineno, format, args) \
     180             : { \
     181             :         old_error_handler(error_num, error_filename, error_lineno, format, args); \
     182             : }
     183             : #endif
     184             : 
     185             : #define PHP_SOAP_SERVER_CLASSNAME "SoapServer"
     186             : #define PHP_SOAP_CLIENT_CLASSNAME "SoapClient"
     187             : #define PHP_SOAP_VAR_CLASSNAME    "SoapVar"
     188             : #define PHP_SOAP_FAULT_CLASSNAME  "SoapFault"
     189             : #define PHP_SOAP_PARAM_CLASSNAME  "SoapParam"
     190             : #define PHP_SOAP_HEADER_CLASSNAME "SoapHeader"
     191             : 
     192             : PHP_RINIT_FUNCTION(soap);
     193             : PHP_MINIT_FUNCTION(soap);
     194             : PHP_MSHUTDOWN_FUNCTION(soap);
     195             : PHP_MINFO_FUNCTION(soap);
     196             : 
     197             : /*
     198             :   Registry Functions
     199             :   TODO: this!
     200             : */
     201             : PHP_FUNCTION(soap_encode_to_xml);
     202             : PHP_FUNCTION(soap_encode_to_zval);
     203             : PHP_FUNCTION(use_soap_error_handler);
     204             : PHP_FUNCTION(is_soap_fault);
     205             : 
     206             : 
     207             : /* Server Functions */
     208             : PHP_METHOD(SoapServer, SoapServer);
     209             : PHP_METHOD(SoapServer, setClass);
     210             : PHP_METHOD(SoapServer, setObject);
     211             : PHP_METHOD(SoapServer, addFunction);
     212             : PHP_METHOD(SoapServer, getFunctions);
     213             : PHP_METHOD(SoapServer, handle);
     214             : PHP_METHOD(SoapServer, setPersistence);
     215             : PHP_METHOD(SoapServer, fault);
     216             : PHP_METHOD(SoapServer, addSoapHeader);
     217             : 
     218             : /* Client Functions */
     219             : PHP_METHOD(SoapClient, SoapClient);
     220             : PHP_METHOD(SoapClient, __call);
     221             : PHP_METHOD(SoapClient, __getLastRequest);
     222             : PHP_METHOD(SoapClient, __getLastResponse);
     223             : PHP_METHOD(SoapClient, __getLastRequestHeaders);
     224             : PHP_METHOD(SoapClient, __getLastResponseHeaders);
     225             : PHP_METHOD(SoapClient, __getFunctions);
     226             : PHP_METHOD(SoapClient, __getTypes);
     227             : PHP_METHOD(SoapClient, __doRequest);
     228             : PHP_METHOD(SoapClient, __setCookie);
     229             : PHP_METHOD(SoapClient, __getCookies);
     230             : PHP_METHOD(SoapClient, __setLocation);
     231             : PHP_METHOD(SoapClient, __setSoapHeaders);
     232             : 
     233             : /* SoapVar Functions */
     234             : PHP_METHOD(SoapVar, SoapVar);
     235             : 
     236             : /* SoapFault Functions */
     237             : PHP_METHOD(SoapFault, SoapFault);
     238             : PHP_METHOD(SoapFault, __toString);
     239             : 
     240             : /* SoapParam Functions */
     241             : PHP_METHOD(SoapParam, SoapParam);
     242             : 
     243             : /* SoapHeader Functions */
     244             : PHP_METHOD(SoapHeader, SoapHeader);
     245             : 
     246             : #define SOAP_CTOR(class_name, func_name, arginfo, flags) PHP_ME(class_name, func_name, arginfo, flags)
     247             : 
     248             : /* {{{ arginfo */
     249             : ZEND_BEGIN_ARG_INFO(arginfo_soap__void, 0)
     250             : ZEND_END_ARG_INFO()
     251             : 
     252             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapparam_soapparam, 0, 0, 2)
     253             :         ZEND_ARG_INFO(0, data)
     254             :         ZEND_ARG_INFO(0, name)
     255             : ZEND_END_ARG_INFO()
     256             : 
     257             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapheader_soapheader, 0, 0, 2)
     258             :         ZEND_ARG_INFO(0, namespace)
     259             :         ZEND_ARG_INFO(0, name)
     260             :         ZEND_ARG_INFO(0, data)
     261             :         ZEND_ARG_INFO(0, mustunderstand)
     262             :         ZEND_ARG_INFO(0, actor)
     263             : ZEND_END_ARG_INFO()
     264             : 
     265             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapfault_soapfault, 0, 0, 2)
     266             :         ZEND_ARG_INFO(0, faultcode)
     267             :         ZEND_ARG_INFO(0, faultstring)
     268             :         ZEND_ARG_INFO(0, faultactor)
     269             :         ZEND_ARG_INFO(0, detail)
     270             :         ZEND_ARG_INFO(0, faultname)
     271             :         ZEND_ARG_INFO(0, headerfault)
     272             : ZEND_END_ARG_INFO()
     273             : 
     274             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapvar_soapvar, 0, 0, 2)
     275             :         ZEND_ARG_INFO(0, data)
     276             :         ZEND_ARG_INFO(0, encoding)
     277             :         ZEND_ARG_INFO(0, type_name)
     278             :         ZEND_ARG_INFO(0, type_namespace)
     279             :         ZEND_ARG_INFO(0, node_name)
     280             :         ZEND_ARG_INFO(0, node_namespace)
     281             : ZEND_END_ARG_INFO()
     282             : 
     283             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_fault, 0, 0, 2)
     284             :         ZEND_ARG_INFO(0, code)
     285             :         ZEND_ARG_INFO(0, string)
     286             :         ZEND_ARG_INFO(0, actor)
     287             :         ZEND_ARG_INFO(0, details)
     288             :         ZEND_ARG_INFO(0, name)
     289             : ZEND_END_ARG_INFO()
     290             : 
     291             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_addsoapheader, 0, 0, 1)
     292             :         ZEND_ARG_INFO(0, object)
     293             : ZEND_END_ARG_INFO()
     294             : 
     295             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_soapserver, 0, 0, 1)
     296             :         ZEND_ARG_INFO(0, wsdl)
     297             :         ZEND_ARG_INFO(0, options)
     298             : ZEND_END_ARG_INFO()
     299             : 
     300             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setpersistence, 0, 0, 1)
     301             :         ZEND_ARG_INFO(0, mode)
     302             : ZEND_END_ARG_INFO()
     303             : 
     304             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setclass, 0, 0, 1)
     305             :         ZEND_ARG_INFO(0, class_name)
     306             :         ZEND_ARG_INFO(0, args)
     307             : ZEND_END_ARG_INFO()
     308             : 
     309             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_setobject, 0, 0, 1)
     310             :         ZEND_ARG_INFO(0, object)
     311             : ZEND_END_ARG_INFO()
     312             : 
     313             : ZEND_BEGIN_ARG_INFO(arginfo_soapserver_getfunctions, 0)
     314             : ZEND_END_ARG_INFO()
     315             : 
     316             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_addfunction, 0, 0, 1)
     317             :         ZEND_ARG_INFO(0, functions)
     318             : ZEND_END_ARG_INFO()
     319             : 
     320             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapserver_handle, 0, 0, 0)
     321             :         ZEND_ARG_INFO(0, soap_request)
     322             : ZEND_END_ARG_INFO()
     323             : 
     324             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient_soapclient, 0, 0, 1)
     325             :         ZEND_ARG_INFO(0, wsdl)
     326             :         ZEND_ARG_INFO(0, options)
     327             : ZEND_END_ARG_INFO()
     328             : 
     329             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___call, 0, 0, 2)
     330             :         ZEND_ARG_INFO(0, function_name)
     331             :         ZEND_ARG_INFO(0, arguments)
     332             : ZEND_END_ARG_INFO()
     333             : 
     334             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___soapcall, 0, 0, 2)
     335             :         ZEND_ARG_INFO(0, function_name)
     336             :         ZEND_ARG_INFO(0, arguments)
     337             :         ZEND_ARG_INFO(0, options)
     338             :         ZEND_ARG_INFO(0, input_headers)
     339             :         ZEND_ARG_INFO(1, output_headers)
     340             : ZEND_END_ARG_INFO()
     341             : 
     342             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getfunctions, 0)
     343             : ZEND_END_ARG_INFO()
     344             : 
     345             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___gettypes, 0)
     346             : ZEND_END_ARG_INFO()
     347             : 
     348             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastrequest, 0)
     349             : ZEND_END_ARG_INFO()
     350             : 
     351             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastresponse, 0)
     352             : ZEND_END_ARG_INFO()
     353             : 
     354             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastrequestheaders, 0)
     355             : ZEND_END_ARG_INFO()
     356             : 
     357             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getlastresponseheaders, 0)
     358             : ZEND_END_ARG_INFO()
     359             : 
     360             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___dorequest, 0, 0, 4)
     361             :         ZEND_ARG_INFO(0, request)
     362             :         ZEND_ARG_INFO(0, location)
     363             :         ZEND_ARG_INFO(0, action)
     364             :         ZEND_ARG_INFO(0, version)
     365             :         ZEND_ARG_INFO(0, one_way)
     366             : ZEND_END_ARG_INFO()
     367             : 
     368             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setcookie, 0, 0, 1)
     369             :         ZEND_ARG_INFO(0, name)
     370             :         ZEND_ARG_INFO(0, value)
     371             : ZEND_END_ARG_INFO()
     372             : 
     373             : ZEND_BEGIN_ARG_INFO(arginfo_soapclient___getcookies, 0)
     374             : ZEND_END_ARG_INFO()
     375             : 
     376             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setsoapheaders, 0, 0, 1)
     377             :         ZEND_ARG_INFO(0, soapheaders)
     378             : ZEND_END_ARG_INFO()
     379             : 
     380             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soapclient___setlocation, 0, 0, 0)
     381             :         ZEND_ARG_INFO(0, new_location)
     382             : ZEND_END_ARG_INFO()
     383             : 
     384             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soap_use_soap_error_handler, 0, 0, 0)
     385             :         ZEND_ARG_INFO(0, handler)
     386             : ZEND_END_ARG_INFO()
     387             : 
     388             : ZEND_BEGIN_ARG_INFO_EX(arginfo_soap_is_soap_fault, 0, 0, 1)
     389             :         ZEND_ARG_INFO(0, object)
     390             : ZEND_END_ARG_INFO()
     391             : /* }}} */
     392             : 
     393             : static const zend_function_entry soap_functions[] = {
     394             :         PHP_FE(use_soap_error_handler,  arginfo_soap_use_soap_error_handler)
     395             :         PHP_FE(is_soap_fault,                   arginfo_soap_is_soap_fault)
     396             :         PHP_FE_END
     397             : };
     398             : 
     399             : static const zend_function_entry soap_fault_functions[] = {
     400             :         SOAP_CTOR(SoapFault, SoapFault, arginfo_soapfault_soapfault, 0)
     401             :         PHP_ME(SoapFault, __toString, arginfo_soap__void, 0)
     402             :         PHP_FE_END
     403             : };
     404             : 
     405             : static const zend_function_entry soap_server_functions[] = {
     406             :         SOAP_CTOR(SoapServer, SoapServer,       arginfo_soapserver_soapserver, 0)
     407             :         PHP_ME(SoapServer, setPersistence,      arginfo_soapserver_setpersistence, 0)
     408             :         PHP_ME(SoapServer, setClass,            arginfo_soapserver_setclass, 0)
     409             :         PHP_ME(SoapServer, setObject,           arginfo_soapserver_setobject, 0)
     410             :         PHP_ME(SoapServer, addFunction,         arginfo_soapserver_addfunction, 0)
     411             :         PHP_ME(SoapServer, getFunctions,        arginfo_soapserver_getfunctions, 0)
     412             :         PHP_ME(SoapServer, handle,                      arginfo_soapserver_handle, 0)
     413             :         PHP_ME(SoapServer, fault,                       arginfo_soapserver_fault, 0)
     414             :         PHP_ME(SoapServer, addSoapHeader,       arginfo_soapserver_addsoapheader, 0)
     415             :         PHP_FE_END
     416             : };
     417             : 
     418             : static const zend_function_entry soap_client_functions[] = {
     419             :         SOAP_CTOR(SoapClient, SoapClient, arginfo_soapclient_soapclient, 0)
     420             :         PHP_ME(SoapClient, __call,                                              arginfo_soapclient___call, 0)
     421             :         ZEND_NAMED_ME(__soapCall, ZEND_MN(SoapClient___call), arginfo_soapclient___soapcall, 0)
     422             :         PHP_ME(SoapClient, __getLastRequest,                    arginfo_soapclient___getlastrequest, 0)
     423             :         PHP_ME(SoapClient, __getLastResponse,                   arginfo_soapclient___getlastresponse, 0)
     424             :         PHP_ME(SoapClient, __getLastRequestHeaders,     arginfo_soapclient___getlastrequestheaders, 0)
     425             :         PHP_ME(SoapClient, __getLastResponseHeaders,    arginfo_soapclient___getlastresponseheaders, 0)
     426             :         PHP_ME(SoapClient, __getFunctions,                              arginfo_soapclient___getfunctions, 0)
     427             :         PHP_ME(SoapClient, __getTypes,                                  arginfo_soapclient___gettypes, 0)
     428             :         PHP_ME(SoapClient, __doRequest,                                 arginfo_soapclient___dorequest, 0)
     429             :         PHP_ME(SoapClient, __setCookie,                                 arginfo_soapclient___setcookie, 0)
     430             :         PHP_ME(SoapClient, __getCookies,                                arginfo_soapclient___getcookies, 0)
     431             :         PHP_ME(SoapClient, __setLocation,                               arginfo_soapclient___setlocation, 0)
     432             :         PHP_ME(SoapClient, __setSoapHeaders,                    arginfo_soapclient___setsoapheaders, 0)
     433             :         PHP_FE_END
     434             : };
     435             : 
     436             : static const zend_function_entry soap_var_functions[] = {
     437             :         SOAP_CTOR(SoapVar, SoapVar, arginfo_soapvar_soapvar, 0)
     438             :         PHP_FE_END
     439             : };
     440             : 
     441             : static const zend_function_entry soap_param_functions[] = {
     442             :         SOAP_CTOR(SoapParam, SoapParam, arginfo_soapparam_soapparam, 0)
     443             :         PHP_FE_END
     444             : };
     445             : 
     446             : static const zend_function_entry soap_header_functions[] = {
     447             :         SOAP_CTOR(SoapHeader, SoapHeader, arginfo_soapheader_soapheader, 0)
     448             :         PHP_FE_END
     449             : };
     450             : 
     451             : zend_module_entry soap_module_entry = {
     452             : #ifdef STANDARD_MODULE_HEADER
     453             :   STANDARD_MODULE_HEADER,
     454             : #endif
     455             :   "soap",
     456             :   soap_functions,
     457             :   PHP_MINIT(soap),
     458             :   PHP_MSHUTDOWN(soap),
     459             :   PHP_RINIT(soap),
     460             :   NULL,
     461             :   PHP_MINFO(soap),
     462             : #ifdef STANDARD_MODULE_HEADER
     463             :   PHP_SOAP_VERSION,
     464             : #endif
     465             :   STANDARD_MODULE_PROPERTIES,
     466             : };
     467             : 
     468             : #ifdef COMPILE_DL_SOAP
     469             : #ifdef ZTS
     470             : ZEND_TSRMLS_CACHE_DEFINE()
     471             : #endif
     472             : ZEND_GET_MODULE(soap)
     473             : #endif
     474             : 
     475       23504 : ZEND_INI_MH(OnUpdateCacheMode)
     476             : {
     477             :         char *p;
     478             : #ifndef ZTS
     479       23504 :         char *base = (char *) mh_arg2;
     480             : #else
     481             :         char *base = (char *) ts_resource(*((int *) mh_arg2));
     482             : #endif
     483             : 
     484       23504 :         p = (char*) (base+(size_t) mh_arg1);
     485             : 
     486       23504 :         *p = (char)atoi(ZSTR_VAL(new_value));
     487             : 
     488       23504 :         return SUCCESS;
     489             : }
     490             : 
     491       23504 : static PHP_INI_MH(OnUpdateCacheDir)
     492             : {
     493             :         /* Only do the open_basedir check at runtime */
     494       23504 :         if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) {
     495             :                 char *p;
     496             : 
     497           0 :                 if (memchr(ZSTR_VAL(new_value), '\0', ZSTR_LEN(new_value)) != NULL) {
     498           0 :                         return FAILURE;
     499             :                 }
     500             : 
     501             :                 /* we do not use zend_memrchr() since path can contain ; itself */
     502           0 :                 if ((p = strchr(ZSTR_VAL(new_value), ';'))) {
     503             :                         char *p2;
     504           0 :                         p++;
     505           0 :                         if ((p2 = strchr(p, ';'))) {
     506           0 :                                 p = p2 + 1;
     507             :                         }
     508             :                 } else {
     509           0 :                         p = ZSTR_VAL(new_value);
     510             :                 }
     511             : 
     512           0 :                 if (PG(open_basedir) && *p && php_check_open_basedir(p)) {
     513           0 :                         return FAILURE;
     514             :                 }
     515             :         }
     516             : 
     517       23504 :         OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
     518       23504 :         return SUCCESS;
     519             : }
     520             : 
     521             : PHP_INI_BEGIN()
     522             : STD_PHP_INI_ENTRY("soap.wsdl_cache_enabled",     "1", PHP_INI_ALL, OnUpdateBool,
     523             :                   cache_enabled, zend_soap_globals, soap_globals)
     524             : STD_PHP_INI_ENTRY("soap.wsdl_cache_dir",         "/tmp", PHP_INI_ALL, OnUpdateCacheDir,
     525             :                   cache_dir, zend_soap_globals, soap_globals)
     526             : STD_PHP_INI_ENTRY("soap.wsdl_cache_ttl",         "86400", PHP_INI_ALL, OnUpdateLong,
     527             :                   cache_ttl, zend_soap_globals, soap_globals)
     528             : STD_PHP_INI_ENTRY("soap.wsdl_cache",             "1", PHP_INI_ALL, OnUpdateCacheMode,
     529             :                   cache_mode, zend_soap_globals, soap_globals)
     530             : STD_PHP_INI_ENTRY("soap.wsdl_cache_limit",       "5", PHP_INI_ALL, OnUpdateLong,
     531             :                   cache_limit, zend_soap_globals, soap_globals)
     532             : PHP_INI_END()
     533             : 
     534             : static HashTable defEnc, defEncIndex, defEncNs;
     535             : 
     536       23504 : static void php_soap_prepare_globals()
     537             : {
     538             :         int i;
     539             :         encodePtr enc;
     540             : 
     541       23504 :         zend_hash_init(&defEnc, 0, NULL, NULL, 1);
     542       23504 :         zend_hash_init(&defEncIndex, 0, NULL, NULL, 1);
     543       23504 :         zend_hash_init(&defEncNs, 0, NULL, NULL, 1);
     544             : 
     545       23504 :         i = 0;
     546             :         do {
     547     1739296 :                 enc = &defaultEncoding[i];
     548             : 
     549             :                 /* If has a ns and a str_type then index it */
     550     1739296 :                 if (defaultEncoding[i].details.type_str) {
     551     1715792 :                         if (defaultEncoding[i].details.ns != NULL) {
     552             :                                 char *ns_type;
     553     1715792 :                                 spprintf(&ns_type, 0, "%s:%s", defaultEncoding[i].details.ns, defaultEncoding[i].details.type_str);
     554     1715792 :                                 zend_hash_str_add_ptr(&defEnc, ns_type, strlen(ns_type), enc);
     555     1715792 :                                 efree(ns_type);
     556             :                         } else {
     557           0 :                                 zend_hash_str_add_ptr(&defEnc, defaultEncoding[i].details.type_str, strlen(defaultEncoding[i].details.type_str), enc);
     558             :                         }
     559             :                 }
     560             :                 /* Index everything by number */
     561     1739296 :                 if (!zend_hash_index_exists(&defEncIndex, defaultEncoding[i].details.type)) {
     562     1433744 :                         zend_hash_index_update_ptr(&defEncIndex, defaultEncoding[i].details.type, enc);
     563             :                 }
     564     1739296 :                 i++;
     565     1739296 :         } while (defaultEncoding[i].details.type != END_KNOWN_TYPES);
     566             : 
     567             :         /* hash by namespace */
     568             :         zend_hash_str_add_ptr(&defEncNs, XSD_1999_NAMESPACE, sizeof(XSD_1999_NAMESPACE)-1, XSD_NS_PREFIX);
     569             :         zend_hash_str_add_ptr(&defEncNs, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1, XSD_NS_PREFIX);
     570             :         zend_hash_str_add_ptr(&defEncNs, XSI_NAMESPACE, sizeof(XSI_NAMESPACE)-1, XSI_NS_PREFIX);
     571             :         zend_hash_str_add_ptr(&defEncNs, XML_NAMESPACE, sizeof(XML_NAMESPACE)-1, XML_NS_PREFIX);
     572             :         zend_hash_str_add_ptr(&defEncNs, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1, SOAP_1_1_ENC_NS_PREFIX);
     573             :         zend_hash_str_add_ptr(&defEncNs, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1, SOAP_1_2_ENC_NS_PREFIX);
     574       23504 : }
     575             : 
     576       23504 : static void php_soap_init_globals(zend_soap_globals *soap_globals)
     577             : {
     578       23504 :         soap_globals->defEnc = defEnc;
     579       23504 :         soap_globals->defEncIndex = defEncIndex;
     580       23504 :         soap_globals->defEncNs = defEncNs;
     581       23504 :         soap_globals->typemap = NULL;
     582       23504 :         soap_globals->use_soap_error_handler = 0;
     583       23504 :         soap_globals->error_code = NULL;
     584       23504 :         ZVAL_OBJ(&soap_globals->error_object, NULL);
     585       23504 :         soap_globals->sdl = NULL;
     586       23504 :         soap_globals->soap_version = SOAP_1_1;
     587       23504 :         soap_globals->mem_cache = NULL;
     588       23504 :         soap_globals->ref_map = NULL;
     589       23504 : }
     590             : 
     591       23544 : PHP_MSHUTDOWN_FUNCTION(soap)
     592             : {
     593       23544 :         zend_error_cb = old_error_handler;
     594       23544 :         zend_hash_destroy(&SOAP_GLOBAL(defEnc));
     595       23544 :         zend_hash_destroy(&SOAP_GLOBAL(defEncIndex));
     596       23544 :         zend_hash_destroy(&SOAP_GLOBAL(defEncNs));
     597       23544 :         if (SOAP_GLOBAL(mem_cache)) {
     598           1 :                 zend_hash_destroy(SOAP_GLOBAL(mem_cache));
     599           1 :                 free(SOAP_GLOBAL(mem_cache));
     600             :         }
     601       23544 :         UNREGISTER_INI_ENTRIES();
     602       23544 :         return SUCCESS;
     603             : }
     604             : 
     605       23458 : PHP_RINIT_FUNCTION(soap)
     606             : {
     607             : #if defined(COMPILE_DL_SOAP) && defined(ZTS)
     608             :         ZEND_TSRMLS_CACHE_UPDATE();
     609             : #endif
     610       23458 :         SOAP_GLOBAL(typemap) = NULL;
     611       23458 :         SOAP_GLOBAL(use_soap_error_handler) = 0;
     612       23458 :         SOAP_GLOBAL(error_code) = NULL;
     613       23458 :         ZVAL_OBJ(&SOAP_GLOBAL(error_object), NULL);
     614       23458 :         SOAP_GLOBAL(sdl) = NULL;
     615       23458 :         SOAP_GLOBAL(soap_version) = SOAP_1_1;
     616       23458 :         SOAP_GLOBAL(encoding) = NULL;
     617       23458 :         SOAP_GLOBAL(class_map) = NULL;
     618       23458 :         SOAP_GLOBAL(features) = 0;
     619       23458 :         SOAP_GLOBAL(ref_map) = NULL;
     620       23458 :         return SUCCESS;
     621             : }
     622             : 
     623         306 : static void delete_sdl_res(zend_resource *res)
     624             : {
     625         306 :         delete_sdl(res->ptr);
     626         306 : }
     627             : 
     628           4 : static void delete_url_res(zend_resource *res)
     629             : {
     630           4 :         delete_url(res->ptr);
     631           4 : }
     632             : 
     633         458 : static void delete_service_res(zend_resource *res)
     634             : {
     635         458 :         delete_service(res->ptr);
     636         458 : }
     637             : 
     638           7 : static void delete_hashtable_res(zend_resource *res)
     639             : {
     640           7 :         delete_hashtable(res->ptr);
     641           7 : }
     642             : 
     643       23504 : PHP_MINIT_FUNCTION(soap)
     644             : {
     645             :         zend_class_entry ce;
     646             : 
     647             : #if defined(COMPILE_DL_SOAP) && defined(ZTS)
     648             :         ZEND_TSRMLS_CACHE_UPDATE();
     649             : #endif
     650             :         /* TODO: add ini entry for always use soap errors */
     651       23504 :         php_soap_prepare_globals();
     652       23504 :         ZEND_INIT_MODULE_GLOBALS(soap, php_soap_init_globals, NULL);
     653       23504 :         REGISTER_INI_ENTRIES();
     654             : 
     655             :         /* Register SoapClient class */
     656             :         /* BIG NOTE : THIS EMITS AN COMPILATION WARNING UNDER ZE2 - handle_function_call deprecated.
     657             :                 soap_call_function_handler should be of type struct _zend_function, not (*handle_function_call).
     658             :         */
     659             :         {
     660             :                 zend_internal_function fe;
     661             : 
     662       23504 :                 fe.type = ZEND_INTERNAL_FUNCTION;
     663       23504 :                 fe.handler = ZEND_MN(SoapClient___call);
     664       23504 :                 fe.function_name = NULL;
     665       23504 :                 fe.scope = NULL;
     666       23504 :                 fe.fn_flags = 0;
     667       23504 :                 fe.prototype = NULL;
     668       23504 :                 fe.num_args = 2;
     669       23504 :                 fe.arg_info = NULL;
     670       23504 :                 zend_set_function_arg_flags((zend_function*)&fe);
     671             : 
     672       23504 :                 INIT_OVERLOADED_CLASS_ENTRY(ce, PHP_SOAP_CLIENT_CLASSNAME, soap_client_functions,
     673             :                         (zend_function *)&fe, NULL, NULL);
     674       23504 :                 soap_class_entry = zend_register_internal_class(&ce);
     675             :         }
     676             :         /* Register SoapVar class */
     677       23504 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_VAR_CLASSNAME, soap_var_functions);
     678       23504 :         soap_var_class_entry = zend_register_internal_class(&ce);
     679             : 
     680             :         /* Register SoapServer class */
     681       23504 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_SERVER_CLASSNAME, soap_server_functions);
     682       23504 :         soap_server_class_entry = zend_register_internal_class(&ce);
     683             : 
     684             :         /* Register SoapFault class */
     685       23504 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_FAULT_CLASSNAME, soap_fault_functions);
     686       23504 :         soap_fault_class_entry = zend_register_internal_class_ex(&ce, zend_ce_exception);
     687             : 
     688             :         /* Register SoapParam class */
     689       23504 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_PARAM_CLASSNAME, soap_param_functions);
     690       23504 :         soap_param_class_entry = zend_register_internal_class(&ce);
     691             : 
     692       23504 :         INIT_CLASS_ENTRY(ce, PHP_SOAP_HEADER_CLASSNAME, soap_header_functions);
     693       23504 :         soap_header_class_entry = zend_register_internal_class(&ce);
     694             : 
     695       23504 :         le_sdl = zend_register_list_destructors_ex(delete_sdl_res, NULL, "SOAP SDL", module_number);
     696       23504 :         le_url = zend_register_list_destructors_ex(delete_url_res, NULL, "SOAP URL", module_number);
     697       23504 :         le_service = zend_register_list_destructors_ex(delete_service_res, NULL, "SOAP service", module_number);
     698       23504 :         le_typemap = zend_register_list_destructors_ex(delete_hashtable_res, NULL, "SOAP table", module_number);
     699             : 
     700       23504 :         REGISTER_LONG_CONSTANT("SOAP_1_1", SOAP_1_1, CONST_CS | CONST_PERSISTENT);
     701       23504 :         REGISTER_LONG_CONSTANT("SOAP_1_2", SOAP_1_2, CONST_CS | CONST_PERSISTENT);
     702             : 
     703       23504 :         REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_SESSION", SOAP_PERSISTENCE_SESSION, CONST_CS | CONST_PERSISTENT);
     704       23504 :         REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_REQUEST", SOAP_PERSISTENCE_REQUEST, CONST_CS | CONST_PERSISTENT);
     705       23504 :         REGISTER_LONG_CONSTANT("SOAP_FUNCTIONS_ALL", SOAP_FUNCTIONS_ALL, CONST_CS | CONST_PERSISTENT);
     706             : 
     707       23504 :         REGISTER_LONG_CONSTANT("SOAP_ENCODED", SOAP_ENCODED, CONST_CS | CONST_PERSISTENT);
     708       23504 :         REGISTER_LONG_CONSTANT("SOAP_LITERAL", SOAP_LITERAL, CONST_CS | CONST_PERSISTENT);
     709             : 
     710       23504 :         REGISTER_LONG_CONSTANT("SOAP_RPC", SOAP_RPC, CONST_CS | CONST_PERSISTENT);
     711       23504 :         REGISTER_LONG_CONSTANT("SOAP_DOCUMENT", SOAP_DOCUMENT, CONST_CS | CONST_PERSISTENT);
     712             : 
     713       23504 :         REGISTER_LONG_CONSTANT("SOAP_ACTOR_NEXT", SOAP_ACTOR_NEXT, CONST_CS | CONST_PERSISTENT);
     714       23504 :         REGISTER_LONG_CONSTANT("SOAP_ACTOR_NONE", SOAP_ACTOR_NONE, CONST_CS | CONST_PERSISTENT);
     715       23504 :         REGISTER_LONG_CONSTANT("SOAP_ACTOR_UNLIMATERECEIVER", SOAP_ACTOR_UNLIMATERECEIVER, CONST_CS | CONST_PERSISTENT);
     716             : 
     717       23504 :         REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_ACCEPT", SOAP_COMPRESSION_ACCEPT, CONST_CS | CONST_PERSISTENT);
     718       23504 :         REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_GZIP", SOAP_COMPRESSION_GZIP, CONST_CS | CONST_PERSISTENT);
     719       23504 :         REGISTER_LONG_CONSTANT("SOAP_COMPRESSION_DEFLATE", SOAP_COMPRESSION_DEFLATE, CONST_CS | CONST_PERSISTENT);
     720             : 
     721       23504 :         REGISTER_LONG_CONSTANT("SOAP_AUTHENTICATION_BASIC", SOAP_AUTHENTICATION_BASIC, CONST_CS | CONST_PERSISTENT);
     722       23504 :         REGISTER_LONG_CONSTANT("SOAP_AUTHENTICATION_DIGEST", SOAP_AUTHENTICATION_DIGEST, CONST_CS | CONST_PERSISTENT);
     723             : 
     724       23504 :         REGISTER_LONG_CONSTANT("UNKNOWN_TYPE", UNKNOWN_TYPE, CONST_CS | CONST_PERSISTENT);
     725             : 
     726       23504 :         REGISTER_LONG_CONSTANT("XSD_STRING", XSD_STRING, CONST_CS | CONST_PERSISTENT);
     727       23504 :         REGISTER_LONG_CONSTANT("XSD_BOOLEAN", XSD_BOOLEAN, CONST_CS | CONST_PERSISTENT);
     728       23504 :         REGISTER_LONG_CONSTANT("XSD_DECIMAL", XSD_DECIMAL, CONST_CS | CONST_PERSISTENT);
     729       23504 :         REGISTER_LONG_CONSTANT("XSD_FLOAT", XSD_FLOAT, CONST_CS | CONST_PERSISTENT);
     730       23504 :         REGISTER_LONG_CONSTANT("XSD_DOUBLE", XSD_DOUBLE, CONST_CS | CONST_PERSISTENT);
     731       23504 :         REGISTER_LONG_CONSTANT("XSD_DURATION", XSD_DURATION, CONST_CS | CONST_PERSISTENT);
     732       23504 :         REGISTER_LONG_CONSTANT("XSD_DATETIME", XSD_DATETIME, CONST_CS | CONST_PERSISTENT);
     733       23504 :         REGISTER_LONG_CONSTANT("XSD_TIME", XSD_TIME, CONST_CS | CONST_PERSISTENT);
     734       23504 :         REGISTER_LONG_CONSTANT("XSD_DATE", XSD_DATE, CONST_CS | CONST_PERSISTENT);
     735       23504 :         REGISTER_LONG_CONSTANT("XSD_GYEARMONTH", XSD_GYEARMONTH, CONST_CS | CONST_PERSISTENT);
     736       23504 :         REGISTER_LONG_CONSTANT("XSD_GYEAR", XSD_GYEAR, CONST_CS | CONST_PERSISTENT);
     737       23504 :         REGISTER_LONG_CONSTANT("XSD_GMONTHDAY", XSD_GMONTHDAY, CONST_CS | CONST_PERSISTENT);
     738       23504 :         REGISTER_LONG_CONSTANT("XSD_GDAY", XSD_GDAY, CONST_CS | CONST_PERSISTENT);
     739       23504 :         REGISTER_LONG_CONSTANT("XSD_GMONTH", XSD_GMONTH, CONST_CS | CONST_PERSISTENT);
     740       23504 :         REGISTER_LONG_CONSTANT("XSD_HEXBINARY", XSD_HEXBINARY, CONST_CS | CONST_PERSISTENT);
     741       23504 :         REGISTER_LONG_CONSTANT("XSD_BASE64BINARY", XSD_BASE64BINARY, CONST_CS | CONST_PERSISTENT);
     742       23504 :         REGISTER_LONG_CONSTANT("XSD_ANYURI", XSD_ANYURI, CONST_CS | CONST_PERSISTENT);
     743       23504 :         REGISTER_LONG_CONSTANT("XSD_QNAME", XSD_QNAME, CONST_CS | CONST_PERSISTENT);
     744       23504 :         REGISTER_LONG_CONSTANT("XSD_NOTATION", XSD_NOTATION, CONST_CS | CONST_PERSISTENT);
     745       23504 :         REGISTER_LONG_CONSTANT("XSD_NORMALIZEDSTRING", XSD_NORMALIZEDSTRING, CONST_CS | CONST_PERSISTENT);
     746       23504 :         REGISTER_LONG_CONSTANT("XSD_TOKEN", XSD_TOKEN, CONST_CS | CONST_PERSISTENT);
     747       23504 :         REGISTER_LONG_CONSTANT("XSD_LANGUAGE", XSD_LANGUAGE, CONST_CS | CONST_PERSISTENT);
     748       23504 :         REGISTER_LONG_CONSTANT("XSD_NMTOKEN", XSD_NMTOKEN, CONST_CS | CONST_PERSISTENT);
     749       23504 :         REGISTER_LONG_CONSTANT("XSD_NAME", XSD_NAME, CONST_CS | CONST_PERSISTENT);
     750       23504 :         REGISTER_LONG_CONSTANT("XSD_NCNAME", XSD_NCNAME, CONST_CS | CONST_PERSISTENT);
     751       23504 :         REGISTER_LONG_CONSTANT("XSD_ID", XSD_ID, CONST_CS | CONST_PERSISTENT);
     752       23504 :         REGISTER_LONG_CONSTANT("XSD_IDREF", XSD_IDREF, CONST_CS | CONST_PERSISTENT);
     753       23504 :         REGISTER_LONG_CONSTANT("XSD_IDREFS", XSD_IDREFS, CONST_CS | CONST_PERSISTENT);
     754       23504 :         REGISTER_LONG_CONSTANT("XSD_ENTITY", XSD_ENTITY, CONST_CS | CONST_PERSISTENT);
     755       23504 :         REGISTER_LONG_CONSTANT("XSD_ENTITIES", XSD_ENTITIES, CONST_CS | CONST_PERSISTENT);
     756       23504 :         REGISTER_LONG_CONSTANT("XSD_INTEGER", XSD_INTEGER, CONST_CS | CONST_PERSISTENT);
     757       23504 :         REGISTER_LONG_CONSTANT("XSD_NONPOSITIVEINTEGER", XSD_NONPOSITIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     758       23504 :         REGISTER_LONG_CONSTANT("XSD_NEGATIVEINTEGER", XSD_NEGATIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     759       23504 :         REGISTER_LONG_CONSTANT("XSD_LONG", XSD_LONG, CONST_CS | CONST_PERSISTENT);
     760       23504 :         REGISTER_LONG_CONSTANT("XSD_INT", XSD_INT, CONST_CS | CONST_PERSISTENT);
     761       23504 :         REGISTER_LONG_CONSTANT("XSD_SHORT", XSD_SHORT, CONST_CS | CONST_PERSISTENT);
     762       23504 :         REGISTER_LONG_CONSTANT("XSD_BYTE", XSD_BYTE, CONST_CS | CONST_PERSISTENT);
     763       23504 :         REGISTER_LONG_CONSTANT("XSD_NONNEGATIVEINTEGER", XSD_NONNEGATIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     764       23504 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDLONG", XSD_UNSIGNEDLONG, CONST_CS | CONST_PERSISTENT);
     765       23504 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDINT", XSD_UNSIGNEDINT, CONST_CS | CONST_PERSISTENT);
     766       23504 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDSHORT", XSD_UNSIGNEDSHORT, CONST_CS | CONST_PERSISTENT);
     767       23504 :         REGISTER_LONG_CONSTANT("XSD_UNSIGNEDBYTE", XSD_UNSIGNEDBYTE, CONST_CS | CONST_PERSISTENT);
     768       23504 :         REGISTER_LONG_CONSTANT("XSD_POSITIVEINTEGER", XSD_POSITIVEINTEGER, CONST_CS | CONST_PERSISTENT);
     769       23504 :         REGISTER_LONG_CONSTANT("XSD_NMTOKENS", XSD_NMTOKENS, CONST_CS | CONST_PERSISTENT);
     770       23504 :         REGISTER_LONG_CONSTANT("XSD_ANYTYPE", XSD_ANYTYPE, CONST_CS | CONST_PERSISTENT);
     771       23504 :         REGISTER_LONG_CONSTANT("XSD_ANYXML", XSD_ANYXML, CONST_CS | CONST_PERSISTENT);
     772             : 
     773       23504 :         REGISTER_LONG_CONSTANT("APACHE_MAP", APACHE_MAP, CONST_CS | CONST_PERSISTENT);
     774             : 
     775       23504 :         REGISTER_LONG_CONSTANT("SOAP_ENC_OBJECT", SOAP_ENC_OBJECT, CONST_CS | CONST_PERSISTENT);
     776       23504 :         REGISTER_LONG_CONSTANT("SOAP_ENC_ARRAY", SOAP_ENC_ARRAY, CONST_CS | CONST_PERSISTENT);
     777             : 
     778       23504 :         REGISTER_LONG_CONSTANT("XSD_1999_TIMEINSTANT", XSD_1999_TIMEINSTANT, CONST_CS | CONST_PERSISTENT);
     779             : 
     780       23504 :         REGISTER_STRING_CONSTANT("XSD_NAMESPACE", XSD_NAMESPACE, CONST_CS | CONST_PERSISTENT);
     781       23504 :         REGISTER_STRING_CONSTANT("XSD_1999_NAMESPACE", XSD_1999_NAMESPACE,  CONST_CS | CONST_PERSISTENT);
     782             : 
     783       23504 :         REGISTER_LONG_CONSTANT("SOAP_SINGLE_ELEMENT_ARRAYS", SOAP_SINGLE_ELEMENT_ARRAYS, CONST_CS | CONST_PERSISTENT);
     784       23504 :         REGISTER_LONG_CONSTANT("SOAP_WAIT_ONE_WAY_CALLS", SOAP_WAIT_ONE_WAY_CALLS, CONST_CS | CONST_PERSISTENT);
     785       23504 :         REGISTER_LONG_CONSTANT("SOAP_USE_XSI_ARRAY_TYPE", SOAP_USE_XSI_ARRAY_TYPE, CONST_CS | CONST_PERSISTENT);
     786             : 
     787       23504 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_NONE",   WSDL_CACHE_NONE,   CONST_CS | CONST_PERSISTENT);
     788       23504 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_DISK",   WSDL_CACHE_DISK,   CONST_CS | CONST_PERSISTENT);
     789       23504 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_MEMORY", WSDL_CACHE_MEMORY, CONST_CS | CONST_PERSISTENT);
     790       23504 :         REGISTER_LONG_CONSTANT("WSDL_CACHE_BOTH",   WSDL_CACHE_BOTH,   CONST_CS | CONST_PERSISTENT);
     791             : 
     792             :         /* New SOAP SSL Method Constants */
     793       23504 :         REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_TLS",    SOAP_SSL_METHOD_TLS,    CONST_CS | CONST_PERSISTENT);
     794       23504 :         REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv2",  SOAP_SSL_METHOD_SSLv2,  CONST_CS | CONST_PERSISTENT);
     795       23504 :         REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv3",  SOAP_SSL_METHOD_SSLv3,  CONST_CS | CONST_PERSISTENT);
     796       23504 :         REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv23", SOAP_SSL_METHOD_SSLv23, CONST_CS | CONST_PERSISTENT);
     797             : 
     798       23504 :         old_error_handler = zend_error_cb;
     799       23504 :         zend_error_cb = soap_error_handler;
     800             : 
     801       23504 :         return SUCCESS;
     802             : }
     803             : 
     804         150 : PHP_MINFO_FUNCTION(soap)
     805             : {
     806         150 :         php_info_print_table_start();
     807         150 :         php_info_print_table_row(2, "Soap Client", "enabled");
     808         150 :         php_info_print_table_row(2, "Soap Server", "enabled");
     809         150 :         php_info_print_table_end();
     810         150 :         DISPLAY_INI_ENTRIES();
     811         150 : }
     812             : 
     813             : 
     814             : /* {{{ proto object SoapParam::SoapParam ( mixed data, string name)
     815             :    SoapParam constructor */
     816          30 : PHP_METHOD(SoapParam, SoapParam)
     817             : {
     818             :         zval *data;
     819             :         char *name;
     820             :         size_t name_length;
     821             :         zval *this_ptr;
     822             : 
     823          30 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs", &data, &name, &name_length) == FAILURE) {
     824           0 :                 return;
     825             :         }
     826          30 :         if (name_length == 0) {
     827           0 :                 php_error_docref(NULL, E_WARNING, "Invalid parameter name");
     828           0 :                 return;
     829             :         }
     830             : 
     831          60 :         this_ptr = getThis();
     832          30 :         add_property_stringl(this_ptr, "param_name", name, name_length);
     833          30 :         add_property_zval(this_ptr, "param_data", data);
     834             : }
     835             : /* }}} */
     836             : 
     837             : 
     838             : /* {{{ proto object SoapHeader::SoapHeader ( string namespace, string name [, mixed data [, bool mustUnderstand [, mixed actor]]])
     839             :    SoapHeader constructor */
     840          31 : PHP_METHOD(SoapHeader, SoapHeader)
     841             : {
     842          31 :         zval *data = NULL, *actor = NULL;
     843             :         char *name, *ns;
     844             :         size_t name_len, ns_len;
     845          31 :         zend_bool must_understand = 0;
     846             :         zval *this_ptr;
     847             : 
     848          31 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|zbz", &ns, &ns_len, &name, &name_len, &data, &must_understand, &actor) == FAILURE) {
     849           0 :                 return;
     850             :         }
     851          31 :         if (ns_len == 0) {
     852           1 :                 php_error_docref(NULL, E_WARNING, "Invalid namespace");
     853           1 :                 return;
     854             :         }
     855          30 :         if (name_len == 0) {
     856           0 :                 php_error_docref(NULL, E_WARNING, "Invalid header name");
     857           0 :                 return;
     858             :         }
     859             : 
     860          60 :         this_ptr = getThis();
     861          30 :         add_property_stringl(this_ptr, "namespace", ns, ns_len);
     862          30 :         add_property_stringl(this_ptr, "name", name, name_len);
     863          30 :         if (data) {
     864          26 :                 add_property_zval(this_ptr, "data", data);
     865             :         }
     866          30 :         add_property_bool(this_ptr, "mustUnderstand", must_understand);
     867          30 :         if (actor == NULL) {
     868           8 :         } else if (Z_TYPE_P(actor) == IS_LONG &&
     869           2 :           (Z_LVAL_P(actor) == SOAP_ACTOR_NEXT ||
     870           0 :            Z_LVAL_P(actor) == SOAP_ACTOR_NONE ||
     871           0 :            Z_LVAL_P(actor) == SOAP_ACTOR_UNLIMATERECEIVER)) {
     872           2 :                 add_property_long(this_ptr, "actor", Z_LVAL_P(actor));
     873           0 :         } else if (Z_TYPE_P(actor) == IS_STRING && Z_STRLEN_P(actor) > 0) {
     874           0 :                 add_property_stringl(this_ptr, "actor", Z_STRVAL_P(actor), Z_STRLEN_P(actor));
     875             :         } else {
     876           0 :                 php_error_docref(NULL, E_WARNING, "Invalid actor");
     877             :         }
     878             : }
     879             : 
     880             : /* {{{ proto object SoapFault::SoapFault ( string faultcode, string faultstring [, string faultactor [, mixed detail [, string faultname [, mixed headerfault]]]])
     881             :    SoapFault constructor */
     882          68 : PHP_METHOD(SoapFault, SoapFault)
     883             : {
     884          68 :         char *fault_string = NULL, *fault_code = NULL, *fault_actor = NULL, *name = NULL, *fault_code_ns = NULL;
     885          68 :         size_t fault_string_len, fault_actor_len = 0, name_len = 0, fault_code_len = 0;
     886          68 :         zval *code = NULL, *details = NULL, *headerfault = NULL, *this_ptr;
     887             : 
     888          68 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs|s!z!s!z",
     889             :                 &code,
     890             :                 &fault_string, &fault_string_len,
     891             :                 &fault_actor, &fault_actor_len,
     892             :                 &details, &name, &name_len, &headerfault) == FAILURE) {
     893           0 :                 return;
     894             :         }
     895             : 
     896         136 :         if (Z_TYPE_P(code) == IS_NULL) {
     897         136 :         } else if (Z_TYPE_P(code) == IS_STRING) {
     898          68 :                 fault_code = Z_STRVAL_P(code);
     899          68 :                 fault_code_len = Z_STRLEN_P(code);
     900           0 :         } else if (Z_TYPE_P(code) == IS_ARRAY && zend_hash_num_elements(Z_ARRVAL_P(code)) == 2) {
     901             :                 zval *t_ns, *t_code;
     902             : 
     903           0 :                 zend_hash_internal_pointer_reset(Z_ARRVAL_P(code));
     904           0 :                 t_ns = zend_hash_get_current_data(Z_ARRVAL_P(code));
     905           0 :                 zend_hash_move_forward(Z_ARRVAL_P(code));
     906           0 :                 t_code = zend_hash_get_current_data(Z_ARRVAL_P(code));
     907           0 :                 if (Z_TYPE_P(t_ns) == IS_STRING && Z_TYPE_P(t_code) == IS_STRING) {
     908           0 :                   fault_code_ns = Z_STRVAL_P(t_ns);
     909           0 :                   fault_code = Z_STRVAL_P(t_code);
     910           0 :                   fault_code_len = Z_STRLEN_P(t_code);
     911             :                 } else {
     912           0 :                         php_error_docref(NULL, E_WARNING, "Invalid fault code");
     913           0 :                         return;
     914             :                 }
     915             :         } else  {
     916           0 :                 php_error_docref(NULL, E_WARNING, "Invalid fault code");
     917           0 :                 return;
     918             :         }
     919          68 :         if (fault_code != NULL && fault_code_len == 0) {
     920           0 :                 php_error_docref(NULL, E_WARNING, "Invalid fault code");
     921           0 :                 return;
     922             :         }
     923          68 :         if (name != NULL && name_len == 0) {
     924           0 :                 name = NULL;
     925             :         }
     926             : 
     927         136 :         this_ptr = getThis();
     928          68 :         set_soap_fault(this_ptr, fault_code_ns, fault_code, fault_string, fault_actor, details, name);
     929          68 :         if (headerfault != NULL) {
     930           2 :                 add_property_zval(this_ptr, "headerfault", headerfault);
     931             :         }
     932             : }
     933             : /* }}} */
     934             : 
     935             : 
     936             : /* {{{ proto object SoapFault::SoapFault ( string faultcode, string faultstring [, string faultactor [, mixed detail [, string faultname [, mixed headerfault]]]])
     937             :    SoapFault constructor */
     938           1 : PHP_METHOD(SoapFault, __toString)
     939             : {
     940             :         zval *faultcode, *faultstring, *file, *line, trace, rv1, rv2, rv3, rv4;
     941             :         zend_string *str;
     942             :         zend_fcall_info fci;
     943             :         zval *this_ptr;
     944             : 
     945           1 :         if (zend_parse_parameters_none() == FAILURE) {
     946           0 :                 return;
     947             :         }
     948             : 
     949           2 :         this_ptr = getThis();
     950           1 :         faultcode   = zend_read_property(soap_fault_class_entry, this_ptr, "faultcode", sizeof("faultcode")-1, 1, &rv1);
     951           1 :         faultstring = zend_read_property(soap_fault_class_entry, this_ptr, "faultstring", sizeof("faultstring")-1, 1, &rv2);
     952           1 :         file = zend_read_property(soap_fault_class_entry, this_ptr, "file", sizeof("file")-1, 1, &rv3);
     953           1 :         line = zend_read_property(soap_fault_class_entry, this_ptr, "line", sizeof("line")-1, 1, &rv4);
     954             : 
     955           1 :         fci.size = sizeof(fci);
     956           2 :         ZVAL_STRINGL(&fci.function_name, "gettraceasstring", sizeof("gettraceasstring")-1);
     957           1 :         fci.object = Z_OBJ(EX(This));
     958           1 :         fci.retval = &trace;
     959           1 :         fci.param_count = 0;
     960           1 :         fci.params = NULL;
     961           1 :         fci.no_separation = 1;
     962             : 
     963           1 :         zend_call_function(&fci, NULL);
     964             : 
     965           1 :         zval_ptr_dtor(&fci.function_name);
     966             : 
     967           1 :         convert_to_string(faultcode);
     968           1 :         convert_to_string(faultstring);
     969           1 :         convert_to_string(file);
     970           1 :         convert_to_long(line);
     971           1 :         convert_to_string(&trace);
     972             : 
     973           5 :         str = strpprintf(0, "SoapFault exception: [%s] %s in %s:" ZEND_LONG_FMT "\nStack trace:\n%s",
     974           3 :                        Z_STRVAL_P(faultcode), Z_STRVAL_P(faultstring), Z_STRVAL_P(file), Z_LVAL_P(line),
     975           2 :                        Z_STRLEN(trace) ? Z_STRVAL(trace) : "#0 {main}\n");
     976             : 
     977           1 :         zval_ptr_dtor(&trace);
     978             : 
     979           1 :         RETVAL_STR(str);
     980             : }
     981             : /* }}} */
     982             : 
     983             : /* {{{ proto object SoapVar::SoapVar ( mixed data, int encoding [, string type_name [, string type_namespace [, string node_name [, string node_namespace]]]])
     984             :    SoapVar constructor */
     985         107 : PHP_METHOD(SoapVar, SoapVar)
     986             : {
     987             :         zval *data, *type, *this_ptr;
     988         107 :         char *stype = NULL, *ns = NULL, *name = NULL, *namens = NULL;
     989         107 :         size_t stype_len = 0, ns_len = 0, name_len = 0, namens_len = 0;
     990             : 
     991         107 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z!z|ssss", &data, &type, &stype, &stype_len, &ns, &ns_len, &name, &name_len, &namens, &namens_len) == FAILURE) {
     992           0 :                 return;
     993             :         }
     994             : 
     995         214 :         this_ptr = getThis();
     996         214 :         if (Z_TYPE_P(type) == IS_NULL) {
     997           2 :                 add_property_long(this_ptr, "enc_type", UNKNOWN_TYPE);
     998             :         } else {
     999         105 :                 if (zend_hash_index_exists(&SOAP_GLOBAL(defEncIndex), Z_LVAL_P(type))) {
    1000         105 :                         add_property_long(this_ptr, "enc_type", Z_LVAL_P(type));
    1001             :                 } else {
    1002           0 :                         php_error_docref(NULL, E_WARNING, "Invalid type ID");
    1003           0 :                         return;
    1004             :                 }
    1005             :         }
    1006             : 
    1007         107 :         if (data) {
    1008         105 :                 add_property_zval(this_ptr, "enc_value", data);
    1009             :         }
    1010             : 
    1011         107 :         if (stype && stype_len > 0) {
    1012          21 :                 add_property_stringl(this_ptr, "enc_stype", stype, stype_len);
    1013             :         }
    1014         107 :         if (ns && ns_len > 0) {
    1015          21 :                 add_property_stringl(this_ptr, "enc_ns", ns, ns_len);
    1016             :         }
    1017         107 :         if (name && name_len > 0) {
    1018          26 :                 add_property_stringl(this_ptr, "enc_name", name, name_len);
    1019             :         }
    1020         107 :         if (namens && namens_len > 0) {
    1021           4 :                 add_property_stringl(this_ptr, "enc_namens", namens, namens_len);
    1022             :         }
    1023             : }
    1024             : /* }}} */
    1025             : 
    1026          15 : static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht)
    1027             : {
    1028             :         zval *tmp;
    1029             :         HashTable *ht2;
    1030          15 :         HashTable *typemap = NULL;
    1031             : 
    1032          45 :         ZEND_HASH_FOREACH_VAL(ht, tmp) {
    1033          15 :                 char *type_name = NULL;
    1034          15 :                 char *type_ns = NULL;
    1035          15 :                 zval *to_xml = NULL;
    1036          15 :                 zval *to_zval = NULL;
    1037             :                 encodePtr enc, new_enc;
    1038             :                 zend_string *name;
    1039             : 
    1040          15 :                 if (Z_TYPE_P(tmp) != IS_ARRAY) {
    1041           0 :                         php_error_docref(NULL, E_WARNING, "Wrong 'typemap' option");
    1042           0 :                         return NULL;
    1043             :                 }
    1044          15 :                 ht2 = Z_ARRVAL_P(tmp);
    1045             : 
    1046         101 :                 ZEND_HASH_FOREACH_STR_KEY_VAL(ht2, name, tmp) {
    1047          43 :                         if (name) {
    1048          73 :                                 if (ZSTR_LEN(name) == sizeof("type_name")-1 &&
    1049          15 :                                     strncmp(ZSTR_VAL(name), "type_name", sizeof("type_name")-1) == 0) {
    1050          15 :                                         if (Z_TYPE_P(tmp) == IS_STRING) {
    1051          15 :                                                 type_name = Z_STRVAL_P(tmp);
    1052             :                                         } else if (Z_TYPE_P(tmp) != IS_NULL) {
    1053             :                                         }
    1054          58 :                                 } else if (ZSTR_LEN(name) == sizeof("type_ns")-1 &&
    1055          15 :                                     strncmp(ZSTR_VAL(name), "type_ns", sizeof("type_ns")-1) == 0) {
    1056          15 :                                         if (Z_TYPE_P(tmp) == IS_STRING) {
    1057          15 :                                                 type_ns = Z_STRVAL_P(tmp);
    1058             :                                         } else if (Z_TYPE_P(tmp) != IS_NULL) {
    1059             :                                         }
    1060          27 :                                 } else if (ZSTR_LEN(name) == sizeof("to_xml")-1 &&
    1061           7 :                                     strncmp(ZSTR_VAL(name), "to_xml", sizeof("to_xml")-1) == 0) {
    1062           7 :                                         to_xml = tmp;
    1063          12 :                                 } else if (ZSTR_LEN(name) == sizeof("from_xml")-1 &&
    1064           6 :                                     strncmp(ZSTR_VAL(name), "from_xml", sizeof("from_xml")-1) == 0) {
    1065           6 :                                         to_zval = tmp;
    1066             :                                 }
    1067             :                         }
    1068             :                 } ZEND_HASH_FOREACH_END();
    1069             : 
    1070          15 :                 if (type_name) {
    1071          15 :                         smart_str nscat = {0};
    1072             : 
    1073          15 :                         if (type_ns) {
    1074          15 :                                 enc = get_encoder(sdl, type_ns, type_name);
    1075             :                         } else {
    1076           0 :                                 enc = get_encoder_ex(sdl, type_name, strlen(type_name));
    1077             :                         }
    1078             : 
    1079          15 :                         new_enc = emalloc(sizeof(encode));
    1080          15 :                         memset(new_enc, 0, sizeof(encode));
    1081             : 
    1082          15 :                         if (enc) {
    1083           9 :                                 new_enc->details.type = enc->details.type;
    1084           9 :                                 new_enc->details.ns = estrdup(enc->details.ns);
    1085           9 :                                 new_enc->details.type_str = estrdup(enc->details.type_str);
    1086           9 :                                 new_enc->details.sdl_type = enc->details.sdl_type;
    1087             :                         } else {
    1088           6 :                                 enc = get_conversion(UNKNOWN_TYPE);
    1089           6 :                                 new_enc->details.type = enc->details.type;
    1090           6 :                                 if (type_ns) {
    1091           6 :                                         new_enc->details.ns = estrdup(type_ns);
    1092             :                                 }
    1093           6 :                                 new_enc->details.type_str = estrdup(type_name);
    1094             :                         }
    1095          15 :                         new_enc->to_xml = enc->to_xml;
    1096          15 :                         new_enc->to_zval = enc->to_zval;
    1097          15 :                         new_enc->details.map = emalloc(sizeof(soapMapping));
    1098          15 :                         memset(new_enc->details.map, 0, sizeof(soapMapping));
    1099          15 :                         if (to_xml) {
    1100           7 :                                 ZVAL_COPY(&new_enc->details.map->to_xml, to_xml);
    1101           7 :                                 new_enc->to_xml = to_xml_user;
    1102           8 :                         } else if (enc->details.map && Z_TYPE(enc->details.map->to_xml) != IS_UNDEF) {
    1103           0 :                                 ZVAL_COPY(&new_enc->details.map->to_xml, &enc->details.map->to_xml);
    1104             :                         }
    1105          15 :                         if (to_zval) {
    1106           6 :                                 ZVAL_COPY(&new_enc->details.map->to_zval, to_zval);
    1107           6 :                                 new_enc->to_zval = to_zval_user;
    1108           9 :                         } else if (enc->details.map && Z_TYPE(enc->details.map->to_zval) != IS_UNDEF) {
    1109           0 :                                 ZVAL_COPY(&new_enc->details.map->to_zval, &enc->details.map->to_zval);
    1110             :                         }
    1111          15 :                         if (!typemap) {
    1112          15 :                                 typemap = emalloc(sizeof(HashTable));
    1113          15 :                                 zend_hash_init(typemap, 0, NULL, delete_encoder, 0);
    1114             :                         }
    1115             : 
    1116          15 :                         if (type_ns) {
    1117          15 :                                 smart_str_appends(&nscat, type_ns);
    1118             :                                 smart_str_appendc(&nscat, ':');
    1119             :                         }
    1120          15 :                         smart_str_appends(&nscat, type_name);
    1121             :                         smart_str_0(&nscat);
    1122          15 :                         zend_hash_update_ptr(typemap, nscat.s, new_enc);
    1123             :                         smart_str_free(&nscat);
    1124             :                 }
    1125             :         } ZEND_HASH_FOREACH_END();
    1126          15 :         return typemap;
    1127             : }
    1128             : 
    1129             : 
    1130             : /* {{{ proto object SoapServer::SoapServer ( mixed wsdl [, array options])
    1131             :    SoapServer constructor */
    1132         458 : PHP_METHOD(SoapServer, SoapServer)
    1133             : {
    1134             :         soapServicePtr service;
    1135         458 :         zval *wsdl = NULL, *options = NULL;
    1136             :         zend_resource *res;
    1137         458 :         int version = SOAP_1_1;
    1138             :         zend_long cache_wsdl;
    1139         458 :         HashTable *typemap_ht = NULL;
    1140             : 
    1141         458 :         SOAP_SERVER_BEGIN_CODE();
    1142             : 
    1143         458 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z|a", &wsdl, &options) == FAILURE) {
    1144           0 :                 php_error_docref(NULL, E_ERROR, "Invalid parameters");
    1145             :         }
    1146             : 
    1147         964 :         if (Z_TYPE_P(wsdl) != IS_STRING && Z_TYPE_P(wsdl) != IS_NULL) {
    1148           0 :                 php_error_docref(NULL, E_ERROR, "Invalid parameters");
    1149             :         }
    1150             : 
    1151         458 :         service = emalloc(sizeof(soapService));
    1152         458 :         memset(service, 0, sizeof(soapService));
    1153         458 :         service->send_errors = 1;
    1154             : 
    1155         458 :         cache_wsdl = SOAP_GLOBAL(cache_enabled) ? SOAP_GLOBAL(cache_mode) : 0;
    1156             : 
    1157         458 :         if (options != NULL) {
    1158         235 :                 HashTable *ht = Z_ARRVAL_P(options);
    1159             :                 zval *tmp;
    1160             : 
    1161         235 :                 if ((tmp = zend_hash_str_find(ht, "soap_version", sizeof("soap_version")-1)) != NULL) {
    1162         300 :                         if (Z_TYPE_P(tmp) == IS_LONG &&
    1163         150 :                             (Z_LVAL_P(tmp) == SOAP_1_1 || Z_LVAL_P(tmp) == SOAP_1_2)) {
    1164          75 :                                 version = Z_LVAL_P(tmp);
    1165             :                         } else {
    1166           0 :                                 php_error_docref(NULL, E_ERROR, "'soap_version' option must be SOAP_1_1 or SOAP_1_2");
    1167             :                         }
    1168             :                 }
    1169             : 
    1170         331 :                 if ((tmp = zend_hash_str_find(ht, "uri", sizeof("uri")-1)) != NULL &&
    1171             :                     Z_TYPE_P(tmp) == IS_STRING) {
    1172          48 :                         service->uri = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
    1173         374 :                 } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    1174           0 :                         php_error_docref(NULL, E_ERROR, "'uri' option is required in nonWSDL mode");
    1175             :                 }
    1176             : 
    1177         316 :                 if ((tmp = zend_hash_str_find(ht, "actor", sizeof("actor")-1)) != NULL &&
    1178             :                     Z_TYPE_P(tmp) == IS_STRING) {
    1179          81 :                         service->actor = estrndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
    1180             :                 }
    1181             : 
    1182         239 :                 if ((tmp = zend_hash_str_find(ht, "encoding", sizeof("encoding")-1)) != NULL &&
    1183             :                     Z_TYPE_P(tmp) == IS_STRING) {
    1184             :                         xmlCharEncodingHandlerPtr encoding;
    1185             : 
    1186           4 :                         encoding = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp));
    1187           4 :                         if (encoding == NULL) {
    1188           0 :                                 php_error_docref(NULL, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_P(tmp));
    1189             :                         } else {
    1190           4 :                           service->encoding = encoding;
    1191             :                         }
    1192             :                 }
    1193             : 
    1194         246 :                 if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL &&
    1195             :                         Z_TYPE_P(tmp) == IS_ARRAY) {
    1196          11 :                         service->class_map = zend_array_dup(Z_ARRVAL_P(tmp));
    1197             :                 }
    1198             : 
    1199         251 :                 if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL &&
    1200             :                         Z_TYPE_P(tmp) == IS_ARRAY &&
    1201           8 :                         zend_hash_num_elements(Z_ARRVAL_P(tmp)) > 0) {
    1202           8 :                         typemap_ht = Z_ARRVAL_P(tmp);
    1203             :                 }
    1204             : 
    1205         323 :                 if ((tmp = zend_hash_str_find(ht, "features", sizeof("features")-1)) != NULL &&
    1206             :                         Z_TYPE_P(tmp) == IS_LONG) {
    1207          88 :                         service->features = Z_LVAL_P(tmp);
    1208             :                 }
    1209             : 
    1210         236 :                 if ((tmp = zend_hash_str_find(ht, "cache_wsdl", sizeof("cache_wsdl")-1)) != NULL &&
    1211             :                     Z_TYPE_P(tmp) == IS_LONG) {
    1212           1 :                         cache_wsdl = Z_LVAL_P(tmp);
    1213             :                 }
    1214             : 
    1215         235 :                 if ((tmp = zend_hash_str_find(ht, "send_errors", sizeof("send_errors")-1)) != NULL) {
    1216           1 :                         if (Z_TYPE_P(tmp) == IS_FALSE) {
    1217           0 :                                 service->send_errors = 0;
    1218           1 :                         } else if (Z_TYPE_P(tmp) == IS_TRUE) {
    1219           0 :                                 service->send_errors = 1;
    1220           1 :                         } else if (Z_TYPE_P(tmp) == IS_LONG) {
    1221           1 :                                 service->send_errors = Z_LVAL_P(tmp);
    1222             :                         }
    1223             :                 }
    1224             : 
    1225         446 :         } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    1226           0 :                 php_error_docref(NULL, E_ERROR, "'uri' option is required in nonWSDL mode");
    1227             :         }
    1228             : 
    1229         458 :         service->version = version;
    1230         458 :         service->type = SOAP_FUNCTIONS;
    1231         458 :         service->soap_functions.functions_all = FALSE;
    1232         458 :         service->soap_functions.ft = emalloc(sizeof(HashTable));
    1233         458 :         zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0);
    1234             : 
    1235         916 :         if (Z_TYPE_P(wsdl) != IS_NULL) {
    1236         820 :                 service->sdl = get_sdl(getThis(), Z_STRVAL_P(wsdl), cache_wsdl);
    1237         410 :                 if (service->uri == NULL) {
    1238         410 :                         if (service->sdl->target_ns) {
    1239         410 :                                 service->uri = estrdup(service->sdl->target_ns);
    1240             :                         } else {
    1241             :                                 /*FIXME*/
    1242           0 :                                 service->uri = estrdup("http://unknown-uri/");
    1243             :                         }
    1244             :                 }
    1245             :         }
    1246             : 
    1247         458 :         if (typemap_ht) {
    1248           8 :                 service->typemap = soap_create_typemap(service->sdl, typemap_ht);
    1249             :         }
    1250             : 
    1251         458 :         res = zend_register_resource(service, le_service);
    1252         916 :         add_property_resource(getThis(), "service", res);
    1253             : 
    1254         458 :         SOAP_SERVER_END_CODE();
    1255         458 : }
    1256             : /* }}} */
    1257             : 
    1258             : 
    1259             : /* {{{ proto object SoapServer::setPersistence ( int mode )
    1260             :    Sets persistence mode of SoapServer */
    1261           2 : PHP_METHOD(SoapServer, setPersistence)
    1262             : {
    1263             :         soapServicePtr service;
    1264             :         zend_long value;
    1265             : 
    1266           2 :         SOAP_SERVER_BEGIN_CODE();
    1267             : 
    1268           6 :         FETCH_THIS_SERVICE(service);
    1269             : 
    1270           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &value) != FAILURE) {
    1271           2 :                 if (service->type == SOAP_CLASS) {
    1272           5 :                         if (value == SOAP_PERSISTENCE_SESSION ||
    1273           1 :                                 value == SOAP_PERSISTENCE_REQUEST) {
    1274           2 :                                 service->soap_class.persistence = value;
    1275             :                         } else {
    1276           0 :                                 php_error_docref(NULL, E_WARNING, "Tried to set persistence with bogus value (" ZEND_LONG_FMT ")", value);
    1277           0 :                                 return;
    1278             :                         }
    1279             :                 } else {
    1280           0 :                         php_error_docref(NULL, E_WARNING, "Tried to set persistence when you are using you SOAP SERVER in function mode, no persistence needed");
    1281           0 :                         return;
    1282             :                 }
    1283             :         }
    1284             : 
    1285           2 :         SOAP_SERVER_END_CODE();
    1286             : }
    1287             : /* }}} */
    1288             : 
    1289             : 
    1290             : /* {{{ proto void SoapServer::setClass(string class_name [, mixed args])
    1291             :    Sets class which will handle SOAP requests */
    1292         310 : PHP_METHOD(SoapServer, setClass)
    1293             : {
    1294             :         soapServicePtr service;
    1295             :         zend_string *classname;
    1296             :         zend_class_entry *ce;
    1297         310 :         int num_args = 0;
    1298         310 :         zval *argv = NULL;
    1299             : 
    1300         310 :         SOAP_SERVER_BEGIN_CODE();
    1301             : 
    1302         930 :         FETCH_THIS_SERVICE(service);
    1303             : 
    1304         310 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S*", &classname, &argv, &num_args) == FAILURE) {
    1305           0 :                 return;
    1306             :         }
    1307             : 
    1308         310 :         ce = zend_lookup_class(classname);
    1309             : 
    1310         310 :         if (ce) {
    1311         310 :                 service->type = SOAP_CLASS;
    1312         310 :                 service->soap_class.ce = ce;
    1313             : 
    1314         310 :                 service->soap_class.persistence = SOAP_PERSISTENCE_REQUEST;
    1315         310 :                 service->soap_class.argc = num_args;
    1316         310 :                 if (service->soap_class.argc > 0) {
    1317             :                         int i;
    1318           1 :                         service->soap_class.argv = safe_emalloc(sizeof(zval), service->soap_class.argc, 0);
    1319           2 :                         for (i = 0;i < service->soap_class.argc;i++) {
    1320           1 :                                 ZVAL_COPY(&service->soap_class.argv[i], &argv[i]);
    1321             :                         }
    1322             :                 }
    1323             :         } else {
    1324           0 :                 php_error_docref(NULL, E_WARNING, "Tried to set a non existent class (%s)", ZSTR_VAL(classname));
    1325           0 :                 return;
    1326             :         }
    1327             : 
    1328         310 :         SOAP_SERVER_END_CODE();
    1329             : }
    1330             : /* }}} */
    1331             : 
    1332             : 
    1333             : /* {{{ proto void SoapServer::setObject(object obj)
    1334             :    Sets object which will handle SOAP requests */
    1335           4 : PHP_METHOD(SoapServer, setObject)
    1336             : {
    1337             :         soapServicePtr service;
    1338             :         zval *obj;
    1339             : 
    1340           4 :         SOAP_SERVER_BEGIN_CODE();
    1341             : 
    1342          12 :         FETCH_THIS_SERVICE(service);
    1343             : 
    1344           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &obj) == FAILURE) {
    1345           0 :                 return;
    1346             :         }
    1347             : 
    1348           4 :         service->type = SOAP_OBJECT;
    1349             : 
    1350           4 :         ZVAL_COPY(&service->soap_object, obj);
    1351             : 
    1352           4 :         SOAP_SERVER_END_CODE();
    1353             : }
    1354             : /* }}} */
    1355             : 
    1356             : 
    1357             : /* {{{ proto array SoapServer::getFunctions(void)
    1358             :    Returns list of defined functions */
    1359           4 : PHP_METHOD(SoapServer, getFunctions)
    1360             : {
    1361             :         soapServicePtr  service;
    1362           4 :         HashTable      *ft = NULL;
    1363             : 
    1364           4 :         SOAP_SERVER_BEGIN_CODE();
    1365             : 
    1366           4 :         if (zend_parse_parameters_none() == FAILURE) {
    1367           0 :                 return;
    1368             :         }
    1369             : 
    1370          12 :         FETCH_THIS_SERVICE(service);
    1371             : 
    1372           4 :         array_init(return_value);
    1373           4 :         if (service->type == SOAP_OBJECT) {
    1374           1 :                 ft = &(Z_OBJCE(service->soap_object)->function_table);
    1375           3 :         } else if (service->type == SOAP_CLASS) {
    1376           2 :                 ft = &service->soap_class.ce->function_table;
    1377           1 :         } else if (service->soap_functions.functions_all == TRUE) {
    1378           0 :                 ft = EG(function_table);
    1379           1 :         } else if (service->soap_functions.ft != NULL) {
    1380             :                 zval *name;
    1381             : 
    1382           5 :                 ZEND_HASH_FOREACH_VAL(service->soap_functions.ft, name) {
    1383           4 :                         add_next_index_str(return_value, zend_string_copy(Z_STR_P(name)));
    1384             :                 } ZEND_HASH_FOREACH_END();
    1385             :         }
    1386           4 :         if (ft != NULL) {
    1387             :                 zend_function *f;
    1388             : 
    1389          15 :                 ZEND_HASH_FOREACH_PTR(ft, f) {
    1390           6 :                         if ((service->type != SOAP_OBJECT && service->type != SOAP_CLASS) || (f->common.fn_flags & ZEND_ACC_PUBLIC)) {
    1391          10 :                                 add_next_index_str(return_value, zend_string_copy(f->common.function_name));
    1392             :                         }
    1393             :                 } ZEND_HASH_FOREACH_END();
    1394             :         }
    1395             : 
    1396           4 :         SOAP_SERVER_END_CODE();
    1397             : }
    1398             : /* }}} */
    1399             : 
    1400             : 
    1401             : /* {{{ proto void SoapServer::addFunction(mixed functions)
    1402             :    Adds one or several functions those will handle SOAP requests */
    1403         143 : PHP_METHOD(SoapServer, addFunction)
    1404             : {
    1405             :         soapServicePtr service;
    1406             :         zval *function_name, function_copy;
    1407             : 
    1408         143 :         SOAP_SERVER_BEGIN_CODE();
    1409             : 
    1410         429 :         FETCH_THIS_SERVICE(service);
    1411             : 
    1412         143 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &function_name) == FAILURE) {
    1413           0 :                 return;
    1414             :         }
    1415             : 
    1416             :         /* TODO: could use zend_is_callable here */
    1417             : 
    1418         286 :         if (Z_TYPE_P(function_name) == IS_ARRAY) {
    1419           3 :                 if (service->type == SOAP_FUNCTIONS) {
    1420             :                         zval *tmp_function;
    1421             : 
    1422           3 :                         if (service->soap_functions.ft == NULL) {
    1423           0 :                                 service->soap_functions.functions_all = FALSE;
    1424           0 :                                 service->soap_functions.ft = emalloc(sizeof(HashTable));
    1425           0 :                                 zend_hash_init(service->soap_functions.ft, zend_hash_num_elements(Z_ARRVAL_P(function_name)), NULL, ZVAL_PTR_DTOR, 0);
    1426             :                         }
    1427             : 
    1428          15 :                         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(function_name), tmp_function) {
    1429             :                                 zend_string *key;
    1430             :                                 zend_function *f;
    1431             : 
    1432           6 :                                 if (Z_TYPE_P(tmp_function) != IS_STRING) {
    1433           0 :                                         php_error_docref(NULL, E_WARNING, "Tried to add a function that isn't a string");
    1434           0 :                                         return;
    1435             :                                 }
    1436             : 
    1437          12 :                                 key = zend_string_alloc(Z_STRLEN_P(tmp_function), 0);
    1438           6 :                                 zend_str_tolower_copy(ZSTR_VAL(key), Z_STRVAL_P(tmp_function), Z_STRLEN_P(tmp_function));
    1439             : 
    1440          12 :                                 if ((f = zend_hash_find_ptr(EG(function_table), key)) == NULL) {
    1441           0 :                                         php_error_docref(NULL, E_WARNING, "Tried to add a non existent function '%s'", Z_STRVAL_P(tmp_function));
    1442           0 :                                         return;
    1443             :                                 }
    1444             : 
    1445           6 :                                 ZVAL_STR_COPY(&function_copy, f->common.function_name);
    1446           6 :                                 zend_hash_update(service->soap_functions.ft, key, &function_copy);
    1447             : 
    1448             :                                 zend_string_release(key);
    1449             :                         } ZEND_HASH_FOREACH_END();
    1450             :                 }
    1451         280 :         } else if (Z_TYPE_P(function_name) == IS_STRING) {
    1452             :                 zend_string *key;
    1453             :                 zend_function *f;
    1454             : 
    1455         278 :                 key = zend_string_alloc(Z_STRLEN_P(function_name), 0);
    1456         139 :                 zend_str_tolower_copy(ZSTR_VAL(key), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name));
    1457             : 
    1458         278 :                 if ((f = zend_hash_find_ptr(EG(function_table), key)) == NULL) {
    1459           0 :                         php_error_docref(NULL, E_WARNING, "Tried to add a non existent function '%s'", Z_STRVAL_P(function_name));
    1460           0 :                         return;
    1461             :                 }
    1462         139 :                 if (service->soap_functions.ft == NULL) {
    1463           0 :                         service->soap_functions.functions_all = FALSE;
    1464           0 :                         service->soap_functions.ft = emalloc(sizeof(HashTable));
    1465           0 :                         zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0);
    1466             :                 }
    1467             : 
    1468         139 :                 ZVAL_STR_COPY(&function_copy, f->common.function_name);
    1469         139 :                 zend_hash_update(service->soap_functions.ft, key, &function_copy);
    1470             :                 zend_string_release(key);
    1471           2 :         } else if (Z_TYPE_P(function_name) == IS_LONG) {
    1472           1 :                 if (Z_LVAL_P(function_name) == SOAP_FUNCTIONS_ALL) {
    1473           1 :                         if (service->soap_functions.ft != NULL) {
    1474           1 :                                 zend_hash_destroy(service->soap_functions.ft);
    1475           1 :                                 efree(service->soap_functions.ft);
    1476           1 :                                 service->soap_functions.ft = NULL;
    1477             :                         }
    1478           1 :                         service->soap_functions.functions_all = TRUE;
    1479             :                 } else {
    1480           0 :                         php_error_docref(NULL, E_WARNING, "Invalid value passed");
    1481           0 :                         return;
    1482             :                 }
    1483             :         }
    1484             : 
    1485         143 :         SOAP_SERVER_END_CODE();
    1486             : }
    1487             : /* }}} */
    1488             : 
    1489           8 : static void _soap_server_exception(soapServicePtr service, sdlFunctionPtr function, zval *this_ptr) /* {{{ */
    1490             : {
    1491             :         zval exception_object;
    1492             : 
    1493           8 :         ZVAL_OBJ(&exception_object, EG(exception));
    1494           8 :         if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry)) {
    1495           5 :                 soap_server_fault_ex(function, &exception_object, NULL);
    1496           3 :         } else if (instanceof_function(Z_OBJCE(exception_object), zend_ce_error)) {
    1497           2 :                 if (service->send_errors) {
    1498             :                         zval rv;
    1499           2 :                         zend_string *msg = zval_get_string(zend_read_property(zend_ce_error, &exception_object, "message", sizeof("message")-1, 0, &rv));
    1500           1 :                         add_soap_fault_ex(&exception_object, this_ptr, "Server", ZSTR_VAL(msg), NULL, NULL);
    1501             :                         zend_string_release(msg);
    1502             :                 } else {
    1503           1 :                         add_soap_fault_ex(&exception_object, this_ptr, "Server", "Internal Error", NULL, NULL);
    1504             :                 }
    1505           2 :                 soap_server_fault_ex(function, &exception_object, NULL);
    1506             :         }
    1507           8 : }
    1508             : /* }}} */
    1509             : 
    1510             : /* {{{ proto void SoapServer::handle ( [string soap_request])
    1511             :    Handles a SOAP request */
    1512         478 : PHP_METHOD(SoapServer, handle)
    1513             : {
    1514             :         int soap_version, old_soap_version;
    1515         478 :         sdlPtr old_sdl = NULL;
    1516             :         soapServicePtr service;
    1517         478 :         xmlDocPtr doc_request=NULL, doc_return;
    1518             :         zval function_name, *params, *soap_obj, retval;
    1519             :         char *fn_name, cont_len[30];
    1520         478 :         int num_params = 0, size, i, call_status = 0;
    1521             :         xmlChar *buf;
    1522             :         HashTable *function_table;
    1523         478 :         soapHeader *soap_headers = NULL;
    1524             :         sdlFunctionPtr function;
    1525         478 :         char *arg = NULL;
    1526         478 :         size_t arg_len = 0;
    1527             :         xmlCharEncodingHandlerPtr old_encoding;
    1528             :         HashTable *old_class_map, *old_typemap;
    1529             :         int old_features;
    1530             : 
    1531         478 :         SOAP_SERVER_BEGIN_CODE();
    1532             : 
    1533        1434 :         FETCH_THIS_SERVICE(service);
    1534         478 :         SOAP_GLOBAL(soap_version) = service->version;
    1535             : 
    1536         478 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s", &arg, &arg_len) == FAILURE) {
    1537           0 :                 return;
    1538             :         }
    1539             : 
    1540         478 :         if (ZEND_NUM_ARGS() > 0 && ZEND_SIZE_T_INT_OVFL(arg_len)) {
    1541           0 :                 soap_server_fault("Server", "Input string is too long", NULL, NULL, NULL);
    1542           0 :                 return;
    1543             :         }
    1544             : 
    1545         487 :         if (SG(request_info).request_method &&
    1546           5 :             strcmp(SG(request_info).request_method, "GET") == 0 &&
    1547           2 :             SG(request_info).query_string &&
    1548           2 :             stricmp(SG(request_info).query_string, "wsdl") == 0) {
    1549             : 
    1550           2 :                 if (service->sdl) {
    1551             : /*
    1552             :                         char *hdr = emalloc(sizeof("Location: ")+strlen(service->sdl->source));
    1553             :                         strcpy(hdr,"Location: ");
    1554             :                         strcat(hdr,service->sdl->source);
    1555             :                         sapi_add_header(hdr, sizeof("Location: ")+strlen(service->sdl->source)-1, 1);
    1556             :                         efree(hdr);
    1557             : */
    1558             :                         zval readfile, readfile_ret, param;
    1559             : 
    1560           1 :                         sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
    1561           2 :                         ZVAL_STRING(&param, service->sdl->source);
    1562           2 :                         ZVAL_STRING(&readfile, "readfile");
    1563           1 :                         if (call_user_function(EG(function_table), NULL, &readfile, &readfile_ret, 1, &param ) == FAILURE) {
    1564           0 :                                 soap_server_fault("Server", "Couldn't find WSDL", NULL, NULL, NULL);
    1565             :                         }
    1566             : 
    1567           1 :                         zval_ptr_dtor(&param);
    1568             :                         zval_dtor(&readfile);
    1569             :                         zval_dtor(&readfile_ret);
    1570             : 
    1571           1 :                         SOAP_SERVER_END_CODE();
    1572           1 :                         return;
    1573             :                 } else {
    1574           1 :                         soap_server_fault("Server", "WSDL generation is not supported yet", NULL, NULL, NULL);
    1575             : /*
    1576             :                         sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8"), 1);
    1577             :                         PUTS("<?xml version=\"1.0\" ?>\n<definitions\n");
    1578             :                         PUTS("    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n");
    1579             :                         PUTS("    targetNamespace=\"");
    1580             :                         PUTS(service->uri);
    1581             :                         PUTS("\">\n");
    1582             :                         PUTS("</definitions>");
    1583             : */
    1584           0 :                         SOAP_SERVER_END_CODE();
    1585           0 :                         return;
    1586             :                 }
    1587             :         }
    1588             : 
    1589         476 :         ZVAL_NULL(&retval);
    1590             : 
    1591         476 :         if (php_output_start_default() != SUCCESS) {
    1592           0 :                 php_error_docref(NULL, E_ERROR,"ob_start failed");
    1593             :         }
    1594             : 
    1595         476 :         if (ZEND_NUM_ARGS() == 0) {
    1596           6 :                 if (SG(request_info).request_body && 0 == php_stream_rewind(SG(request_info).request_body)) {
    1597             :                         zval *server_vars, *encoding;
    1598           3 :                         php_stream_filter *zf = NULL;
    1599           3 :                         zend_string *server = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
    1600             : 
    1601           3 :                         zend_is_auto_global(server);
    1602          11 :                         if ((server_vars = zend_hash_find(&EG(symbol_table), server)) != NULL &&
    1603             :                             Z_TYPE_P(server_vars) == IS_ARRAY &&
    1604           3 :                             (encoding = zend_hash_str_find(Z_ARRVAL_P(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING")-1)) != NULL &&
    1605             :                             Z_TYPE_P(encoding) == IS_STRING) {
    1606             : 
    1607           8 :                                 if (strcmp(Z_STRVAL_P(encoding),"gzip") == 0
    1608           3 :                                 ||  strcmp(Z_STRVAL_P(encoding),"x-gzip") == 0
    1609           2 :                                 ||  strcmp(Z_STRVAL_P(encoding),"deflate") == 0
    1610             :                                 ) {
    1611             :                                         zval filter_params;
    1612             : 
    1613           2 :                                         array_init_size(&filter_params, 1);
    1614           2 :                                         add_assoc_long_ex(&filter_params, "window", sizeof("window")-1, 0x2f); /* ANY WBITS */
    1615             : 
    1616           2 :                                         zf = php_stream_filter_create("zlib.inflate", &filter_params, 0);
    1617             :                                         zval_dtor(&filter_params);
    1618             : 
    1619           2 :                                         if (zf) {
    1620           2 :                                                 php_stream_filter_append(&SG(request_info).request_body->readfilters, zf);
    1621             :                                         } else {
    1622           0 :                                                 php_error_docref(NULL, E_WARNING,"Can't uncompress compressed request");
    1623             :                                                 zend_string_release(server);
    1624           0 :                                                 return;
    1625             :                                         }
    1626             :                                 } else {
    1627           0 :                                         php_error_docref(NULL, E_WARNING,"Request is compressed with unknown compression '%s'",Z_STRVAL_P(encoding));
    1628             :                                         zend_string_release(server);
    1629           0 :                                         return;
    1630             :                                 }
    1631             :                         }
    1632             :                         zend_string_release(server);
    1633             : 
    1634           3 :                         doc_request = soap_xmlParseFile("php://input");
    1635             : 
    1636           3 :                         if (zf) {
    1637           2 :                                 php_stream_filter_remove(zf, 1);
    1638             :                         }
    1639             :                 } else {
    1640           0 :                         zval_ptr_dtor(&retval);
    1641           0 :                         return;
    1642             :                 }
    1643             :         } else {
    1644         473 :                 doc_request = soap_xmlParseMemory(arg,arg_len);
    1645             :         }
    1646             : 
    1647         476 :         if (doc_request == NULL) {
    1648           0 :                 soap_server_fault("Client", "Bad Request", NULL, NULL, NULL);
    1649             :         }
    1650         476 :         if (xmlGetIntSubset(doc_request) != NULL) {
    1651           3 :                 xmlNodePtr env = get_node(doc_request->children,"Envelope");
    1652           3 :                 if (env && env->ns) {
    1653           3 :                         if (strcmp((char*)env->ns->href, SOAP_1_1_ENV_NAMESPACE) == 0) {
    1654           0 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_1;
    1655           3 :                         } else if (strcmp((char*)env->ns->href,SOAP_1_2_ENV_NAMESPACE) == 0) {
    1656           3 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_2;
    1657             :                         }
    1658             :                 }
    1659           3 :                 xmlFreeDoc(doc_request);
    1660           3 :                 soap_server_fault("Server", "DTD are not supported by SOAP", NULL, NULL, NULL);
    1661             :         }
    1662             : 
    1663         473 :         old_sdl = SOAP_GLOBAL(sdl);
    1664         473 :         SOAP_GLOBAL(sdl) = service->sdl;
    1665         473 :         old_encoding = SOAP_GLOBAL(encoding);
    1666         473 :         SOAP_GLOBAL(encoding) = service->encoding;
    1667         473 :         old_class_map = SOAP_GLOBAL(class_map);
    1668         473 :         SOAP_GLOBAL(class_map) = service->class_map;
    1669         473 :         old_typemap = SOAP_GLOBAL(typemap);
    1670         473 :         SOAP_GLOBAL(typemap) = service->typemap;
    1671         473 :         old_features = SOAP_GLOBAL(features);
    1672         473 :         SOAP_GLOBAL(features) = service->features;
    1673         473 :         old_soap_version = SOAP_GLOBAL(soap_version);
    1674         473 :         function = deserialize_function_call(service->sdl, doc_request, service->actor, &function_name, &num_params, &params, &soap_version, &soap_headers);
    1675         455 :         xmlFreeDoc(doc_request);
    1676             : 
    1677         455 :         if (EG(exception)) {
    1678           1 :                 php_output_discard();
    1679           2 :                 _soap_server_exception(service, function, getThis());
    1680           1 :                 goto fail;
    1681             :         }
    1682             : 
    1683         454 :         service->soap_headers_ptr = &soap_headers;
    1684             : 
    1685         454 :         soap_obj = NULL;
    1686         454 :         if (service->type == SOAP_OBJECT) {
    1687           3 :                 soap_obj = &service->soap_object;
    1688           3 :                 function_table = &((Z_OBJCE_P(soap_obj))->function_table);
    1689         451 :         } else if (service->type == SOAP_CLASS) {
    1690             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1691             :                 /* If persistent then set soap_obj from from the previous created session (if available) */
    1692         292 :                 if (service->soap_class.persistence == SOAP_PERSISTENCE_SESSION) {
    1693             :                         zval *tmp_soap;
    1694             :                         zval *session_vars;
    1695             : 
    1696           2 :                         if (PS(session_status) != php_session_active &&
    1697           0 :                             PS(session_status) != php_session_disabled) {
    1698           0 :                                 php_session_start();
    1699             :                         }
    1700             : 
    1701             :                         /* Find the soap object and assign */
    1702           2 :                         session_vars = &PS(http_session_vars);
    1703           2 :                         ZVAL_DEREF(session_vars);
    1704           6 :                         if (Z_TYPE_P(session_vars) == IS_ARRAY &&
    1705           2 :                             (tmp_soap = zend_hash_str_find(Z_ARRVAL_P(session_vars), "_bogus_session_name", sizeof("_bogus_session_name")-1)) != NULL &&
    1706             :                             Z_TYPE_P(tmp_soap) == IS_OBJECT &&
    1707           1 :                             Z_OBJCE_P(tmp_soap) == service->soap_class.ce) {
    1708           1 :                                 soap_obj = tmp_soap;
    1709             :                         }
    1710             :                 }
    1711             : #endif
    1712             :                 /* If new session or something weird happned */
    1713         292 :                 if (soap_obj == NULL) {
    1714             :                         zval tmp_soap;
    1715             : 
    1716         291 :                         object_init_ex(&tmp_soap, service->soap_class.ce);
    1717             : 
    1718             :                         /* Call constructor */
    1719         291 :                         if (zend_hash_str_exists(&Z_OBJCE(tmp_soap)->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1)) {
    1720             :                                 zval c_ret, constructor;
    1721             : 
    1722           2 :                                 ZVAL_STRING(&constructor, ZEND_CONSTRUCTOR_FUNC_NAME);
    1723           1 :                                 if (call_user_function(NULL, &tmp_soap, &constructor, &c_ret, service->soap_class.argc, service->soap_class.argv) == FAILURE) {
    1724           0 :                                         php_error_docref(NULL, E_ERROR, "Error calling constructor");
    1725             :                                 }
    1726           1 :                                 if (EG(exception)) {
    1727           0 :                                         php_output_discard();
    1728           0 :                                         _soap_server_exception(service, function, getThis());
    1729             :                                         zval_dtor(&constructor);
    1730             :                                         zval_dtor(&c_ret);
    1731           0 :                                         zval_ptr_dtor(&tmp_soap);
    1732           0 :                                         goto fail;
    1733             :                                 }
    1734             :                                 zval_dtor(&constructor);
    1735             :                                 zval_dtor(&c_ret);
    1736             :                         } else {
    1737         290 :                                 int class_name_len = ZSTR_LEN(service->soap_class.ce->name);
    1738         290 :                                 char *class_name = emalloc(class_name_len+1);
    1739             : 
    1740         290 :                                 memcpy(class_name, ZSTR_VAL(service->soap_class.ce->name), class_name_len+1);
    1741         290 :                                 if (zend_hash_str_exists(&Z_OBJCE(tmp_soap)->function_table, php_strtolower(class_name, class_name_len), class_name_len)) {
    1742             :                                         zval c_ret, constructor;
    1743             : 
    1744           0 :                                         ZVAL_STR_COPY(&constructor, service->soap_class.ce->name);
    1745           0 :                                         if (call_user_function(NULL, &tmp_soap, &constructor, &c_ret, service->soap_class.argc, service->soap_class.argv) == FAILURE) {
    1746           0 :                                                 php_error_docref(NULL, E_ERROR, "Error calling constructor");
    1747             :                                         }
    1748             : 
    1749           0 :                                         if (EG(exception)) {
    1750           0 :                                                 php_output_discard();
    1751           0 :                                                 _soap_server_exception(service, function, getThis());
    1752             :                                                 zval_dtor(&constructor);
    1753             :                                                 zval_dtor(&c_ret);
    1754           0 :                                                 efree(class_name);
    1755           0 :                                                 zval_ptr_dtor(&tmp_soap);
    1756           0 :                                                 goto fail;
    1757             :                                         }
    1758             : 
    1759             :                                         zval_dtor(&constructor);
    1760             :                                         zval_dtor(&c_ret);
    1761             :                                 }
    1762         290 :                                 efree(class_name);
    1763             :                         }
    1764             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1765             :                         /* If session then update session hash with new object */
    1766         291 :                         if (service->soap_class.persistence == SOAP_PERSISTENCE_SESSION) {
    1767             :                                 zval *tmp_soap_pp;
    1768           1 :                                 zval *session_vars = &PS(http_session_vars);
    1769             : 
    1770           1 :                                 ZVAL_DEREF(session_vars);
    1771           3 :                                 if (Z_TYPE_P(session_vars) == IS_ARRAY &&
    1772           1 :                                     (tmp_soap_pp = zend_hash_str_update(Z_ARRVAL_P(session_vars), "_bogus_session_name", sizeof("_bogus_session_name")-1, &tmp_soap)) != NULL) {
    1773           1 :                                         soap_obj = tmp_soap_pp;
    1774             :                                 } else {
    1775           0 :                                         soap_obj = &tmp_soap;
    1776             :                                 }
    1777             :                         } else {
    1778         290 :                                 soap_obj = &tmp_soap;
    1779             :                         }
    1780             : #else
    1781             :                         soap_obj = &tmp_soap;
    1782             : #endif
    1783             : 
    1784             :                 }
    1785         292 :                 function_table = &((Z_OBJCE_P(soap_obj))->function_table);
    1786             :         } else {
    1787         159 :                 if (service->soap_functions.functions_all == TRUE) {
    1788           1 :                         function_table = EG(function_table);
    1789             :                 } else {
    1790         158 :                         function_table = service->soap_functions.ft;
    1791             :                 }
    1792             :         }
    1793             : 
    1794         454 :         doc_return = NULL;
    1795             : 
    1796             :         /* Process soap headers */
    1797         454 :         if (soap_headers != NULL) {
    1798          38 :                 soapHeader *header = soap_headers;
    1799         112 :                 while (header != NULL) {
    1800          42 :                         soapHeader *h = header;
    1801             : 
    1802          42 :                         header = header->next;
    1803             : #if 0
    1804             :                         if (service->sdl && !h->function && !h->hdr) {
    1805             :                                 if (h->mustUnderstand) {
    1806             :                                         soap_server_fault("MustUnderstand","Header not understood", NULL, NULL, NULL);
    1807             :                                 } else {
    1808             :                                         continue;
    1809             :                                 }
    1810             :                         }
    1811             : #endif
    1812          42 :                         fn_name = estrndup(Z_STRVAL(h->function_name),Z_STRLEN(h->function_name));
    1813          97 :                         if (zend_hash_str_exists(function_table, php_strtolower(fn_name, Z_STRLEN(h->function_name)), Z_STRLEN(h->function_name)) ||
    1814          14 :                             ((service->type == SOAP_CLASS || service->type == SOAP_OBJECT) &&
    1815          14 :                              zend_hash_str_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
    1816          56 :                                 if (service->type == SOAP_CLASS || service->type == SOAP_OBJECT) {
    1817          28 :                                         call_status = call_user_function(NULL, soap_obj, &h->function_name, &h->retval, h->num_params, h->parameters);
    1818             :                                 } else {
    1819           0 :                                         call_status = call_user_function(EG(function_table), NULL, &h->function_name, &h->retval, h->num_params, h->parameters);
    1820             :                                 }
    1821          28 :                                 if (call_status != SUCCESS) {
    1822           0 :                                         php_error_docref(NULL, E_WARNING, "Function '%s' call failed", Z_STRVAL(h->function_name));
    1823           0 :                                         return;
    1824             :                                 }
    1825          64 :                                 if (Z_TYPE(h->retval) == IS_OBJECT &&
    1826           8 :                                     instanceof_function(Z_OBJCE(h->retval), soap_fault_class_entry)) {
    1827             :                                         zval *tmp;
    1828             : 
    1829           1 :                                         if ((tmp = zend_hash_str_find(Z_OBJPROP(h->retval), "headerfault", sizeof("headerfault")-1)) != NULL &&
    1830             :                                             Z_TYPE_P(tmp) != IS_NULL) {
    1831             :                                         }
    1832           1 :                                         php_output_discard();
    1833           1 :                                         soap_server_fault_ex(function, &h->retval, h);
    1834           1 :                                         efree(fn_name);
    1835           1 :                                         if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);}
    1836           1 :                                         goto fail;
    1837          27 :                                 } else if (EG(exception)) {
    1838           0 :                                         php_output_discard();
    1839           0 :                                         _soap_server_exception(service, function, getThis());
    1840           0 :                                         efree(fn_name);
    1841           0 :                                         if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);}
    1842           0 :                                         goto fail;
    1843             :                                 }
    1844          14 :                         } else if (h->mustUnderstand) {
    1845           5 :                                 soap_server_fault("MustUnderstand","Header not understood", NULL, NULL, NULL);
    1846             :                         }
    1847          36 :                         efree(fn_name);
    1848             :                 }
    1849             :         }
    1850             : 
    1851         448 :         fn_name = estrndup(Z_STRVAL(function_name),Z_STRLEN(function_name));
    1852         895 :         if (zend_hash_str_exists(function_table, php_strtolower(fn_name, Z_STRLEN(function_name)), Z_STRLEN(function_name)) ||
    1853           3 :             ((service->type == SOAP_CLASS || service->type == SOAP_OBJECT) &&
    1854           2 :              zend_hash_str_exists(function_table, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
    1855         737 :                 if (service->type == SOAP_CLASS || service->type == SOAP_OBJECT) {
    1856         289 :                         call_status = call_user_function(NULL, soap_obj, &function_name, &retval, num_params, params);
    1857         289 :                         if (service->type == SOAP_CLASS) {
    1858             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1859         286 :                                 if (service->soap_class.persistence != SOAP_PERSISTENCE_SESSION) {
    1860         284 :                                         zval_ptr_dtor(soap_obj);
    1861         284 :                                         soap_obj = NULL;
    1862             :                                 }
    1863             : #else
    1864             :                                 zval_ptr_dtor(soap_obj);
    1865             :                                 soap_obj = NULL;
    1866             : #endif
    1867             :                         }
    1868             :                 } else {
    1869         159 :                         call_status = call_user_function(EG(function_table), NULL, &function_name, &retval, num_params, params);
    1870             :                 }
    1871             :         } else {
    1872           0 :                 php_error(E_ERROR, "Function '%s' doesn't exist", Z_STRVAL(function_name));
    1873             :         }
    1874         442 :         efree(fn_name);
    1875             : 
    1876         442 :         if (EG(exception)) {
    1877           6 :                 php_output_discard();
    1878          12 :                 _soap_server_exception(service, function, getThis());
    1879           6 :                 if (service->type == SOAP_CLASS) {
    1880             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1881           1 :                         if (soap_obj && service->soap_class.persistence != SOAP_PERSISTENCE_SESSION) {
    1882             : #else
    1883             :                         if (soap_obj) {
    1884             : #endif
    1885           0 :                                 zval_ptr_dtor(soap_obj);
    1886             :                         }
    1887             :                 }
    1888           6 :                 goto fail;
    1889             :         }
    1890             : 
    1891         436 :         if (call_status == SUCCESS) {
    1892             :                 char *response_name;
    1893             : 
    1894         553 :                 if (Z_TYPE(retval) == IS_OBJECT &&
    1895         117 :                     instanceof_function(Z_OBJCE(retval), soap_fault_class_entry)) {
    1896          59 :                         php_output_discard();
    1897          59 :                         soap_server_fault_ex(function, &retval, NULL);
    1898          59 :                         goto fail;
    1899             :                 }
    1900             : 
    1901         623 :                 if (function && function->responseName) {
    1902         246 :                         response_name = estrdup(function->responseName);
    1903             :                 } else {
    1904         131 :                         response_name = emalloc(Z_STRLEN(function_name) + sizeof("Response"));
    1905         131 :                         memcpy(response_name,Z_STRVAL(function_name),Z_STRLEN(function_name));
    1906         131 :                         memcpy(response_name+Z_STRLEN(function_name),"Response",sizeof("Response"));
    1907             :                 }
    1908         377 :                 doc_return = serialize_response_call(function, response_name, service->uri, &retval, soap_headers, soap_version);
    1909         376 :                 efree(response_name);
    1910             :         } else {
    1911           0 :                 php_error_docref(NULL, E_WARNING, "Function '%s' call failed", Z_STRVAL(function_name));
    1912           0 :                 return;
    1913             :         }
    1914             : 
    1915         376 :         if (EG(exception)) {
    1916           1 :                 php_output_discard();
    1917           2 :                 _soap_server_exception(service, function, getThis());
    1918           1 :                 if (service->type == SOAP_CLASS) {
    1919             : #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
    1920           1 :                         if (soap_obj && service->soap_class.persistence != SOAP_PERSISTENCE_SESSION) {
    1921             : #else
    1922             :                         if (soap_obj) {
    1923             : #endif
    1924           0 :                                 zval_ptr_dtor(soap_obj);
    1925             :                         }
    1926             :                 }
    1927           1 :                 goto fail;
    1928             :         }
    1929             : 
    1930             :         /* Flush buffer */
    1931         375 :         php_output_discard();
    1932             : 
    1933         375 :         if (doc_return) {
    1934             :                 /* xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); */
    1935         293 :                 xmlDocDumpMemory(doc_return, &buf, &size);
    1936             : 
    1937         293 :                 if (size == 0) {
    1938           0 :                         php_error_docref(NULL, E_ERROR, "Dump memory failed");
    1939             :                 }
    1940             : 
    1941         293 :                 if (soap_version == SOAP_1_2) {
    1942          50 :                         sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
    1943             :                 } else {
    1944         243 :                         sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
    1945             :                 }
    1946             : 
    1947         293 :                 xmlFreeDoc(doc_return);
    1948             : 
    1949         293 :                 if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
    1950           0 :                         sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
    1951             :                 } else {
    1952         293 :                         snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);
    1953         293 :                         sapi_add_header(cont_len, strlen(cont_len), 1);
    1954             :                 }
    1955         293 :                 php_write(buf, size);
    1956         293 :                 xmlFree(buf);
    1957             :         } else {
    1958          82 :                 sapi_add_header("HTTP/1.1 202 Accepted", sizeof("HTTP/1.1 202 Accepted")-1, 1);
    1959          82 :                 sapi_add_header("Content-Length: 0", sizeof("Content-Length: 0")-1, 1);
    1960             :         }
    1961             : 
    1962             : fail:
    1963         443 :         SOAP_GLOBAL(soap_version) = old_soap_version;
    1964         443 :         SOAP_GLOBAL(encoding) = old_encoding;
    1965         443 :         SOAP_GLOBAL(sdl) = old_sdl;
    1966         443 :         SOAP_GLOBAL(class_map) = old_class_map;
    1967         443 :         SOAP_GLOBAL(typemap) = old_typemap;
    1968         443 :         SOAP_GLOBAL(features) = old_features;
    1969             : 
    1970             :         /* Free soap headers */
    1971         443 :         zval_ptr_dtor(&retval);
    1972         929 :         while (soap_headers != NULL) {
    1973          43 :                 soapHeader *h = soap_headers;
    1974             :                 int i;
    1975             : 
    1976          43 :                 soap_headers = soap_headers->next;
    1977          43 :                 if (h->parameters) {
    1978          37 :                         i = h->num_params;
    1979         112 :                         while (i > 0) {
    1980          38 :                                 zval_ptr_dtor(&h->parameters[--i]);
    1981             :                         }
    1982          37 :                         efree(h->parameters);
    1983             :                 }
    1984          43 :                 zval_dtor(&h->function_name);
    1985          43 :                 zval_dtor(&h->retval);
    1986          43 :                 efree(h);
    1987             :         }
    1988         443 :         service->soap_headers_ptr = NULL;
    1989             : 
    1990             :         /* Free Memory */
    1991         443 :         if (num_params > 0) {
    1992         819 :                 for (i = 0; i < num_params;i++) {
    1993         447 :                         zval_ptr_dtor(&params[i]);
    1994             :                 }
    1995         372 :                 efree(params);
    1996             :         }
    1997             :         zval_dtor(&function_name);
    1998             : 
    1999         443 :         SOAP_SERVER_END_CODE();
    2000             : }
    2001             : /* }}} */
    2002             : 
    2003             : 
    2004             : /* {{{ proto SoapServer::fault ( staring code, string string [, string actor [, mixed details [, string name]]] )
    2005             :    Issue SoapFault indicating an error */
    2006           2 : PHP_METHOD(SoapServer, fault)
    2007             : {
    2008           2 :         char *code, *string, *actor=NULL, *name=NULL;
    2009           2 :         size_t code_len, string_len, actor_len = 0, name_len = 0;
    2010           2 :         zval* details = NULL;
    2011             :         soapServicePtr service;
    2012             :         xmlCharEncodingHandlerPtr old_encoding;
    2013             : 
    2014           2 :         SOAP_SERVER_BEGIN_CODE();
    2015           6 :         FETCH_THIS_SERVICE(service);
    2016           2 :         old_encoding = SOAP_GLOBAL(encoding);
    2017           2 :         SOAP_GLOBAL(encoding) = service->encoding;
    2018             : 
    2019           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|szs",
    2020             :             &code, &code_len, &string, &string_len, &actor, &actor_len, &details,
    2021             :             &name, &name_len) == FAILURE) {
    2022           0 :                 return;
    2023             :         }
    2024             : 
    2025           2 :         soap_server_fault(code, string, actor, details, name);
    2026             : 
    2027           0 :         SOAP_GLOBAL(encoding) = old_encoding;
    2028           0 :         SOAP_SERVER_END_CODE();
    2029             : }
    2030             : /* }}} */
    2031             : 
    2032           6 : PHP_METHOD(SoapServer, addSoapHeader)
    2033             : {
    2034             :         soapServicePtr service;
    2035             :         zval *fault;
    2036             :         soapHeader **p;
    2037             : 
    2038           6 :         SOAP_SERVER_BEGIN_CODE();
    2039             : 
    2040          18 :         FETCH_THIS_SERVICE(service);
    2041             : 
    2042          12 :         if (!service || !service->soap_headers_ptr) {
    2043           0 :                 php_error_docref(NULL, E_WARNING, "The SoapServer::addSoapHeader function may be called only during SOAP request processing");
    2044           0 :                 return;
    2045             :         }
    2046             : 
    2047           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &fault, soap_header_class_entry) == FAILURE) {
    2048           0 :                 return;
    2049             :         }
    2050             : 
    2051           6 :         p = service->soap_headers_ptr;
    2052          15 :         while (*p != NULL) {
    2053           3 :                 p = &(*p)->next;
    2054             :         }
    2055           6 :         *p = emalloc(sizeof(soapHeader));
    2056           6 :         memset(*p, 0, sizeof(soapHeader));
    2057           6 :         ZVAL_NULL(&(*p)->function_name);
    2058           6 :         (*p)->retval = *fault;
    2059           6 :         zval_copy_ctor(&(*p)->retval);
    2060             : 
    2061           6 :         SOAP_SERVER_END_CODE();
    2062             : }
    2063             : 
    2064          98 : static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader *hdr)
    2065             : {
    2066             :         int soap_version;
    2067             :         xmlChar *buf;
    2068             :         char cont_len[30];
    2069             :         int size;
    2070             :         xmlDocPtr doc_return;
    2071             :         zval *agent_name;
    2072          98 :         int use_http_error_status = 1;
    2073             : 
    2074          98 :         soap_version = SOAP_GLOBAL(soap_version);
    2075             : 
    2076          98 :         doc_return = serialize_response_call(function, NULL, NULL, fault, hdr, soap_version);
    2077             : 
    2078          98 :         xmlDocDumpMemory(doc_return, &buf, &size);
    2079             : 
    2080         196 :         if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
    2081          98 :                 (agent_name = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) != NULL &&
    2082             :                 Z_TYPE_P(agent_name) == IS_STRING) {
    2083           0 :                 if (strncmp(Z_STRVAL_P(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) {
    2084           0 :                         use_http_error_status = 0;
    2085             :                 }
    2086             :         }
    2087             :         /*
    2088             :            Want to return HTTP 500 but apache wants to over write
    2089             :            our fault code with their own handling... Figure this out later
    2090             :         */
    2091          98 :         if (use_http_error_status) {
    2092          98 :                 sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error")-1, 1);
    2093             :         }
    2094          98 :         if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
    2095           0 :                 sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
    2096             :         } else {
    2097          98 :                 snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);
    2098          98 :                 sapi_add_header(cont_len, strlen(cont_len), 1);
    2099             :         }
    2100          98 :         if (soap_version == SOAP_1_2) {
    2101          26 :                 sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
    2102             :         } else {
    2103          72 :                 sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
    2104             :         }
    2105             : 
    2106          98 :         php_write(buf, size);
    2107             : 
    2108          98 :         xmlFreeDoc(doc_return);
    2109          98 :         xmlFree(buf);
    2110          98 :         zend_clear_exception();
    2111          98 : }
    2112             : 
    2113          23 : static void soap_server_fault(char* code, char* string, char *actor, zval* details, char* name)
    2114             : {
    2115             :         zval ret;
    2116             : 
    2117          23 :         ZVAL_NULL(&ret);
    2118          23 :         set_soap_fault(&ret, NULL, code, string, actor, details, name);
    2119             :         /* TODO: Which function */
    2120          23 :         soap_server_fault_ex(NULL, &ret, NULL);
    2121          23 :         zend_bailout();
    2122           0 : }
    2123             : 
    2124      424186 : static void soap_error_handler(int error_num, const char *error_filename, const uint error_lineno, const char *format, va_list args)
    2125             : {
    2126             :         zend_bool _old_in_compilation;
    2127             :         zend_execute_data *_old_current_execute_data;
    2128             :         int _old_http_response_code;
    2129             :         char *_old_http_status_line;
    2130             : 
    2131      424186 :         _old_in_compilation = CG(in_compilation);
    2132      424186 :         _old_current_execute_data = EG(current_execute_data);
    2133      424186 :         _old_http_response_code = SG(sapi_headers).http_response_code;
    2134      424186 :         _old_http_status_line = SG(sapi_headers).http_status_line;
    2135             : 
    2136      424186 :         if (!PG(modules_activated) || !SOAP_GLOBAL(use_soap_error_handler) || !EG(objects_store).object_buckets) {
    2137      423614 :                 call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2138      422603 :                 return;
    2139             :         }
    2140             : 
    2141        1148 :         if (Z_OBJ(SOAP_GLOBAL(error_object)) &&
    2142         572 :             instanceof_function(Z_OBJCE(SOAP_GLOBAL(error_object)), soap_class_entry)) {
    2143             :                 zval *tmp;
    2144          11 :                 int use_exceptions = 0;
    2145             : 
    2146          13 :                 if ((tmp = zend_hash_str_find(Z_OBJPROP(SOAP_GLOBAL(error_object)), "_exceptions", sizeof("_exceptions")-1)) == NULL ||
    2147             :                      Z_TYPE_P(tmp) != IS_FALSE) {
    2148           9 :                      use_exceptions = 1;
    2149             :                 }
    2150             : 
    2151          11 :                 if ((error_num == E_USER_ERROR ||
    2152             :                      error_num == E_COMPILE_ERROR ||
    2153             :                      error_num == E_CORE_ERROR ||
    2154             :                      error_num == E_ERROR ||
    2155             :                      error_num == E_PARSE) &&
    2156             :                     use_exceptions) {
    2157             :                         zval fault;
    2158           5 :                         char* code = SOAP_GLOBAL(error_code);
    2159             :                         char buffer[1024];
    2160             :                         size_t buffer_len;
    2161             : #ifdef va_copy
    2162             :                         va_list argcopy;
    2163             : #endif
    2164             :                         zend_object **old_objects;
    2165           5 :                         int old = PG(display_errors);
    2166             : 
    2167             : #ifdef va_copy
    2168           5 :                         va_copy(argcopy, args);
    2169           5 :                         buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, argcopy);
    2170           5 :                         va_end(argcopy);
    2171             : #else
    2172             :                         buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, args);
    2173             : #endif
    2174           5 :                         buffer[sizeof(buffer)-1]=0;
    2175           5 :                         if (buffer_len > sizeof(buffer) - 1 || buffer_len == (size_t)-1) {
    2176           0 :                                 buffer_len = sizeof(buffer) - 1;
    2177             :                         }
    2178             : 
    2179           5 :                         if (code == NULL) {
    2180           0 :                                 code = "Client";
    2181             :                         }
    2182           5 :                         add_soap_fault_ex(&fault, &SOAP_GLOBAL(error_object), code, buffer, NULL, NULL);
    2183             :                         Z_ADDREF(fault);
    2184           5 :                         zend_throw_exception_object(&fault);
    2185             : 
    2186           5 :                         old_objects = EG(objects_store).object_buckets;
    2187           5 :                         EG(objects_store).object_buckets = NULL;
    2188           5 :                         PG(display_errors) = 0;
    2189           5 :                         SG(sapi_headers).http_status_line = NULL;
    2190           5 :                         zend_try {
    2191           5 :                                 call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2192           5 :                         } zend_catch {
    2193           5 :                                 CG(in_compilation) = _old_in_compilation;
    2194           5 :                                 EG(current_execute_data) = _old_current_execute_data;
    2195           5 :                                 if (SG(sapi_headers).http_status_line) {
    2196           0 :                                         efree(SG(sapi_headers).http_status_line);
    2197             :                                 }
    2198           5 :                                 SG(sapi_headers).http_status_line = _old_http_status_line;
    2199           5 :                                 SG(sapi_headers).http_response_code = _old_http_response_code;
    2200           5 :                         } zend_end_try();
    2201           5 :                         EG(objects_store).object_buckets = old_objects;
    2202           5 :                         PG(display_errors) = old;
    2203           5 :                         zend_bailout();
    2204          14 :                 } else if (!use_exceptions ||
    2205           4 :                            !SOAP_GLOBAL(error_code) ||
    2206           4 :                            strcmp(SOAP_GLOBAL(error_code),"WSDL") != 0) {
    2207             :                         /* Ignore libxml warnings during WSDL parsing */
    2208           4 :                         call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2209             :                 }
    2210             :         } else {
    2211         561 :                 int old = PG(display_errors);
    2212         561 :                 int fault = 0;
    2213             :                 zval fault_obj;
    2214             : #ifdef va_copy
    2215             :                 va_list argcopy;
    2216             : #endif
    2217             : 
    2218         561 :                 if (error_num == E_USER_ERROR ||
    2219             :                     error_num == E_COMPILE_ERROR ||
    2220             :                     error_num == E_CORE_ERROR ||
    2221             :                     error_num == E_ERROR ||
    2222             :                     error_num == E_PARSE) {
    2223             : 
    2224           8 :                         char* code = SOAP_GLOBAL(error_code);
    2225             :                         char buffer[1024];
    2226             :                         zval outbuf;
    2227             :                         zval *tmp;
    2228             :                         soapServicePtr service;
    2229             : 
    2230           8 :                         ZVAL_UNDEF(&outbuf);
    2231           8 :                         if (code == NULL) {
    2232           0 :                                 code = "Server";
    2233             :                         }
    2234          40 :                         if (Z_OBJ(SOAP_GLOBAL(error_object)) &&
    2235           8 :                             instanceof_function(Z_OBJCE(SOAP_GLOBAL(error_object)), soap_server_class_entry) &&
    2236           8 :                         (tmp = zend_hash_str_find(Z_OBJPROP(SOAP_GLOBAL(error_object)), "service", sizeof("service")-1)) != NULL &&
    2237           8 :                                 (service = (soapServicePtr)zend_fetch_resource_ex(tmp, "service", le_service)) &&
    2238           8 :                                 !service->send_errors) {
    2239           0 :                                 strcpy(buffer, "Internal Error");
    2240             :                         } else {
    2241             :                                 size_t buffer_len;
    2242             :                                 zval outbuflen;
    2243             : 
    2244             : #ifdef va_copy
    2245           8 :                                 va_copy(argcopy, args);
    2246           8 :                                 buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, argcopy);
    2247           8 :                                 va_end(argcopy);
    2248             : #else
    2249             :                                 buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, args);
    2250             : #endif
    2251           8 :                                 buffer[sizeof(buffer)-1]=0;
    2252           8 :                                 if (buffer_len > sizeof(buffer) - 1 || buffer_len == (size_t)-1) {
    2253           0 :                                         buffer_len = sizeof(buffer) - 1;
    2254             :                                 }
    2255             : 
    2256             :                                 /* Get output buffer and send as fault detials */
    2257           8 :                                 if (php_output_get_length(&outbuflen) != FAILURE && Z_LVAL(outbuflen) != 0) {
    2258           0 :                                         php_output_get_contents(&outbuf);
    2259             :                                 }
    2260           8 :                                 php_output_discard();
    2261             : 
    2262             :                         }
    2263           8 :                         ZVAL_NULL(&fault_obj);
    2264           8 :                         set_soap_fault(&fault_obj, NULL, code, buffer, NULL, &outbuf, NULL);
    2265           8 :                         fault = 1;
    2266             :                 }
    2267             : 
    2268         561 :                 PG(display_errors) = 0;
    2269         561 :                 SG(sapi_headers).http_status_line = NULL;
    2270         561 :                 zend_try {
    2271         561 :                         call_old_error_handler(error_num, error_filename, error_lineno, format, args);
    2272           8 :                 } zend_catch {
    2273           8 :                         CG(in_compilation) = _old_in_compilation;
    2274           8 :                         EG(current_execute_data) = _old_current_execute_data;
    2275           8 :                         if (SG(sapi_headers).http_status_line) {
    2276           0 :                                 efree(SG(sapi_headers).http_status_line);
    2277             :                         }
    2278           8 :                         SG(sapi_headers).http_status_line = _old_http_status_line;
    2279           8 :                         SG(sapi_headers).http_response_code = _old_http_response_code;
    2280         561 :                 } zend_end_try();
    2281         561 :                 PG(display_errors) = old;
    2282             : 
    2283         561 :                 if (fault) {
    2284           8 :                         soap_server_fault_ex(NULL, &fault_obj, NULL);
    2285           8 :                         zend_bailout();
    2286             :                 }
    2287             :         }
    2288             : }
    2289             : 
    2290           0 : PHP_FUNCTION(use_soap_error_handler)
    2291             : {
    2292           0 :         zend_bool handler = 1;
    2293             : 
    2294           0 :         ZVAL_BOOL(return_value, SOAP_GLOBAL(use_soap_error_handler));
    2295           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &handler) == SUCCESS) {
    2296           0 :                 SOAP_GLOBAL(use_soap_error_handler) = handler;
    2297             :         }
    2298           0 : }
    2299             : 
    2300           0 : PHP_FUNCTION(is_soap_fault)
    2301             : {
    2302             :         zval *fault;
    2303             : 
    2304           0 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &fault) == SUCCESS &&
    2305           0 :             Z_TYPE_P(fault) == IS_OBJECT &&
    2306           0 :             instanceof_function(Z_OBJCE_P(fault), soap_fault_class_entry)) {
    2307           0 :                 RETURN_TRUE;
    2308             :         }
    2309           0 :         RETURN_FALSE
    2310             : }
    2311             : 
    2312             : /* SoapClient functions */
    2313             : 
    2314             : /* {{{ proto object SoapClient::SoapClient ( mixed wsdl [, array options])
    2315             :    SoapClient constructor */
    2316         390 : PHP_METHOD(SoapClient, SoapClient)
    2317             : {
    2318             : 
    2319         390 :         zval *wsdl, *options = NULL;
    2320         390 :         int  soap_version = SOAP_1_1;
    2321         390 :         php_stream_context *context = NULL;
    2322             :         zend_long cache_wsdl;
    2323         390 :         sdlPtr sdl = NULL;
    2324         390 :         HashTable *typemap_ht = NULL;
    2325         780 :         zval *this_ptr = getThis();
    2326             : 
    2327         390 :         SOAP_CLIENT_BEGIN_CODE();
    2328             : 
    2329         390 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z|a", &wsdl, &options) == FAILURE) {
    2330           0 :                 php_error_docref(NULL, E_ERROR, "Invalid parameters");
    2331             :         }
    2332             : 
    2333         859 :         if (Z_TYPE_P(wsdl) != IS_STRING && Z_TYPE_P(wsdl) != IS_NULL) {
    2334           0 :                 php_error_docref(NULL, E_ERROR, "$wsdl must be string or null");
    2335             :         }
    2336             : 
    2337         390 :         cache_wsdl = SOAP_GLOBAL(cache_enabled) ? SOAP_GLOBAL(cache_mode) : 0;
    2338             : 
    2339         390 :         if (options != NULL) {
    2340         368 :                 HashTable *ht = Z_ARRVAL_P(options);
    2341             :                 zval *tmp, tmp2;
    2342             : 
    2343         736 :                 if (Z_TYPE_P(wsdl) == IS_NULL) {
    2344             :                         /* Fetching non-WSDL mode options */
    2345         237 :                         if ((tmp = zend_hash_str_find(ht, "uri", sizeof("uri")-1)) != NULL &&
    2346             :                             Z_TYPE_P(tmp) == IS_STRING) {
    2347         158 :                                 add_property_str(this_ptr, "uri", zend_string_copy(Z_STR_P(tmp)));
    2348             :                         } else {
    2349           0 :                                 php_error_docref(NULL, E_ERROR, "'uri' option is required in nonWSDL mode");
    2350             :                         }
    2351             : 
    2352          81 :                         if ((tmp = zend_hash_str_find(ht, "style", sizeof("style")-1)) != NULL &&
    2353             :                                         Z_TYPE_P(tmp) == IS_LONG &&
    2354           1 :                                         (Z_LVAL_P(tmp) == SOAP_RPC || Z_LVAL_P(tmp) == SOAP_DOCUMENT)) {
    2355           1 :                                 add_property_long(this_ptr, "style", Z_LVAL_P(tmp));
    2356             :                         }
    2357             : 
    2358          82 :                         if ((tmp = zend_hash_str_find(ht, "use", sizeof("use")-1)) != NULL &&
    2359             :                                         Z_TYPE_P(tmp) == IS_LONG &&
    2360           2 :                                         (Z_LVAL_P(tmp) == SOAP_LITERAL || Z_LVAL_P(tmp) == SOAP_ENCODED)) {
    2361           1 :                                 add_property_long(this_ptr, "use", Z_LVAL_P(tmp));
    2362             :                         }
    2363             :                 }
    2364             : 
    2365         369 :                 if ((tmp = zend_hash_str_find(ht, "stream_context", sizeof("stream_context")-1)) != NULL &&
    2366             :                                 Z_TYPE_P(tmp) == IS_RESOURCE) {
    2367           1 :                         context = php_stream_context_from_zval(tmp, 1);
    2368             :                         Z_ADDREF_P(tmp);
    2369             :                 }
    2370             : 
    2371         530 :                 if ((tmp = zend_hash_str_find(ht, "location", sizeof("location")-1)) != NULL &&
    2372             :                     Z_TYPE_P(tmp) == IS_STRING) {
    2373         162 :                         add_property_str(this_ptr, "location", zend_string_copy(Z_STR_P(tmp)));
    2374         574 :                 } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    2375           0 :                         php_error_docref(NULL, E_ERROR, "'location' option is required in nonWSDL mode");
    2376             :                 }
    2377             : 
    2378         368 :                 if ((tmp = zend_hash_str_find(ht, "soap_version", sizeof("soap_version")-1)) != NULL) {
    2379           2 :                         if (Z_TYPE_P(tmp) == IS_LONG ||
    2380           0 :                             (Z_LVAL_P(tmp) == SOAP_1_1 && Z_LVAL_P(tmp) == SOAP_1_2)) {
    2381           2 :                                 soap_version = Z_LVAL_P(tmp);
    2382             :                         }
    2383             :                 }
    2384         369 :                 if ((tmp = zend_hash_str_find(ht, "login", sizeof("login")-1)) != NULL &&
    2385             :                     Z_TYPE_P(tmp) == IS_STRING) {
    2386           2 :                         add_property_str(this_ptr, "_login", zend_string_copy(Z_STR_P(tmp)));
    2387           2 :                         if ((tmp = zend_hash_str_find(ht, "password", sizeof("password")-1)) != NULL &&
    2388             :                             Z_TYPE_P(tmp) == IS_STRING) {
    2389           2 :                                 add_property_str(this_ptr, "_password", zend_string_copy(Z_STR_P(tmp)));
    2390             :                         }
    2391           1 :                         if ((tmp = zend_hash_str_find(ht, "authentication", sizeof("authentication")-1)) != NULL &&
    2392             :                             Z_TYPE_P(tmp) == IS_LONG &&
    2393           0 :                             Z_LVAL_P(tmp) == SOAP_AUTHENTICATION_DIGEST) {
    2394           0 :                                 add_property_null(this_ptr, "_digest");
    2395             :                         }
    2396             :                 }
    2397         369 :                 if ((tmp = zend_hash_str_find(ht, "proxy_host", sizeof("proxy_host")-1)) != NULL &&
    2398             :                     Z_TYPE_P(tmp) == IS_STRING) {
    2399           2 :                         add_property_str(this_ptr, "_proxy_host", zend_string_copy(Z_STR_P(tmp)));
    2400           1 :                         if ((tmp = zend_hash_str_find(ht, "proxy_port", sizeof("proxy_port")-1)) != NULL) {
    2401           1 :                                 if (Z_TYPE_P(tmp) != IS_LONG) {
    2402           2 :                                         ZVAL_LONG(&tmp2, zval_get_long(tmp));
    2403           1 :                                         tmp = &tmp2;
    2404             :                                 }
    2405           1 :                                 add_property_long(this_ptr, "_proxy_port", Z_LVAL_P(tmp));
    2406             :                         }
    2407           1 :                         if ((tmp = zend_hash_str_find(ht, "proxy_login", sizeof("proxy_login")-1)) != NULL &&
    2408             :                             Z_TYPE_P(tmp) == IS_STRING) {
    2409           0 :                                 add_property_str(this_ptr, "_proxy_login", zend_string_copy(Z_STR_P(tmp)));
    2410           0 :                                 if ((tmp = zend_hash_str_find(ht, "proxy_password", sizeof("proxy_password")-1)) != NULL &&
    2411             :                                     Z_TYPE_P(tmp) == IS_STRING) {
    2412           0 :                                         add_property_str(this_ptr, "_proxy_password", zend_string_copy(Z_STR_P(tmp)));
    2413             :                                 }
    2414             :                         }
    2415             :                 }
    2416         368 :                 if ((tmp = zend_hash_str_find(ht, "local_cert", sizeof("local_cert")-1)) != NULL &&
    2417             :                     Z_TYPE_P(tmp) == IS_STRING) {
    2418           0 :                   if (!context) {
    2419           0 :                         context = php_stream_context_alloc();
    2420             :                   }
    2421           0 :                         php_stream_context_set_option(context, "ssl", "local_cert", tmp);
    2422           0 :                         if ((tmp = zend_hash_str_find(ht, "passphrase", sizeof("passphrase")-1)) != NULL &&
    2423             :                             Z_TYPE_P(tmp) == IS_STRING) {
    2424           0 :                                 php_stream_context_set_option(context, "ssl", "passphrase", tmp);
    2425             :                         }
    2426             :                 }
    2427        1347 :                 if ((tmp = zend_hash_str_find(ht, "trace", sizeof("trace")-1)) != NULL &&
    2428             :                     (Z_TYPE_P(tmp) == IS_TRUE ||
    2429         325 :                      (Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == 1))) {
    2430         329 :                         add_property_long(this_ptr, "trace", 1);
    2431             :                 }
    2432             : 
    2433        1320 :                 if ((tmp = zend_hash_str_find(ht, "exceptions", sizeof("exceptions")-1)) != NULL &&
    2434             :                     (Z_TYPE_P(tmp) == IS_FALSE ||
    2435         316 :                      (Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == 0))) {
    2436         319 :                         add_property_bool(this_ptr, "_exceptions", 0);
    2437             :                 }
    2438             : 
    2439         368 :                 if ((tmp = zend_hash_str_find(ht, "compression", sizeof("compression")-1)) != NULL &&
    2440             :                     Z_TYPE_P(tmp) == IS_LONG &&
    2441           0 :               zend_hash_str_exists(EG(function_table), "gzinflate", sizeof("gzinflate")-1) &&
    2442           0 :               zend_hash_str_exists(EG(function_table), "gzdeflate", sizeof("gzdeflate")-1) &&
    2443           0 :               zend_hash_str_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1) &&
    2444           0 :               zend_hash_str_exists(EG(function_table), "gzcompress", sizeof("gzcompress")-1) &&
    2445           0 :               zend_hash_str_exists(EG(function_table), "gzencode", sizeof("gzencode")-1)) {
    2446           0 :                         add_property_long(this_ptr, "compression", Z_LVAL_P(tmp));
    2447             :                 }
    2448         381 :                 if ((tmp = zend_hash_str_find(ht, "encoding", sizeof("encoding")-1)) != NULL &&
    2449             :                     Z_TYPE_P(tmp) == IS_STRING) {
    2450             :                         xmlCharEncodingHandlerPtr encoding;
    2451             : 
    2452          13 :                         encoding = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp));
    2453          13 :                         if (encoding == NULL) {
    2454           0 :                                 php_error_docref(NULL, E_ERROR, "Invalid 'encoding' option - '%s'", Z_STRVAL_P(tmp));
    2455             :                         } else {
    2456          13 :                                 xmlCharEncCloseFunc(encoding);
    2457          26 :                                 add_property_str(this_ptr, "_encoding", zend_string_copy(Z_STR_P(tmp)));
    2458             :                         }
    2459             :                 }
    2460         379 :                 if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL &&
    2461             :                         Z_TYPE_P(tmp) == IS_ARRAY) {
    2462          11 :                         add_property_zval(this_ptr, "_classmap", tmp);
    2463             :                 }
    2464             : 
    2465         382 :                 if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL &&
    2466             :                         Z_TYPE_P(tmp) == IS_ARRAY &&
    2467           7 :                         zend_hash_num_elements(Z_ARRVAL_P(tmp)) > 0) {
    2468           7 :                         typemap_ht = Z_ARRVAL_P(tmp);
    2469             :                 }
    2470             : 
    2471         455 :                 if ((tmp = zend_hash_str_find(ht, "features", sizeof("features")-1)) != NULL &&
    2472             :                         Z_TYPE_P(tmp) == IS_LONG) {
    2473          87 :                         add_property_long(this_ptr, "_features", Z_LVAL_P(tmp));
    2474             :             }
    2475             : 
    2476         368 :                 if ((tmp = zend_hash_str_find(ht, "connection_timeout", sizeof("connection_timeout")-1)) != NULL) {
    2477           0 :                         if (Z_TYPE_P(tmp) != IS_LONG) {
    2478           0 :                                 ZVAL_LONG(&tmp2, zval_get_long(tmp));
    2479           0 :                                 tmp = &tmp2;
    2480             :                         }
    2481           0 :                         if (Z_LVAL_P(tmp) > 0) {
    2482           0 :                                 add_property_long(this_ptr, "_connection_timeout", Z_LVAL_P(tmp));
    2483             :                         }
    2484             :                 }
    2485             : 
    2486         368 :                 if (context) {
    2487           1 :                         add_property_resource(this_ptr, "_stream_context", context->res);
    2488             :                 }
    2489             : 
    2490         379 :                 if ((tmp = zend_hash_str_find(ht, "cache_wsdl", sizeof("cache_wsdl")-1)) != NULL &&
    2491             :                     Z_TYPE_P(tmp) == IS_LONG) {
    2492          11 :                         cache_wsdl = Z_LVAL_P(tmp);
    2493             :                 }
    2494             : 
    2495         368 :                 if ((tmp = zend_hash_str_find(ht, "user_agent", sizeof("user_agent")-1)) != NULL &&
    2496             :                     Z_TYPE_P(tmp) == IS_STRING) {
    2497           0 :                         add_property_str(this_ptr, "_user_agent", zend_string_copy(Z_STR_P(tmp)));
    2498             :                 }
    2499             : 
    2500         368 :                 if ((tmp = zend_hash_str_find(ht, "keep_alive", sizeof("keep_alive")-1)) != NULL &&
    2501             :                                 (Z_TYPE_P(tmp) == IS_FALSE ||
    2502           0 :                                  (Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == 0))) {
    2503           0 :                         add_property_long(this_ptr, "_keep_alive", 0);
    2504             :                 }
    2505             : 
    2506         368 :                 if ((tmp = zend_hash_str_find(ht, "ssl_method", sizeof("ssl_method")-1)) != NULL &&
    2507             :                         Z_TYPE_P(tmp) == IS_LONG) {
    2508           0 :                         add_property_long(this_ptr, "_ssl_method", Z_LVAL_P(tmp));
    2509             :                 }
    2510          44 :         } else if (Z_TYPE_P(wsdl) == IS_NULL) {
    2511           0 :                 php_error_docref(NULL, E_ERROR, "'location' and 'uri' options are required in nonWSDL mode");
    2512             :         }
    2513             : 
    2514         390 :         add_property_long(this_ptr, "_soap_version", soap_version);
    2515             : 
    2516         780 :         if (Z_TYPE_P(wsdl) != IS_NULL) {
    2517             :                 int    old_soap_version;
    2518             :                 zend_resource *res;
    2519             : 
    2520         311 :                 old_soap_version = SOAP_GLOBAL(soap_version);
    2521         311 :                 SOAP_GLOBAL(soap_version) = soap_version;
    2522             : 
    2523         311 :                 sdl = get_sdl(this_ptr, Z_STRVAL_P(wsdl), cache_wsdl);
    2524         306 :                 res = zend_register_resource(sdl, le_sdl);
    2525             : 
    2526         306 :                 add_property_resource(this_ptr, "sdl", res);
    2527             : 
    2528         306 :                 SOAP_GLOBAL(soap_version) = old_soap_version;
    2529             :         }
    2530             : 
    2531         385 :         if (typemap_ht) {
    2532           7 :                 HashTable *typemap = soap_create_typemap(sdl, typemap_ht);
    2533           7 :                 if (typemap) {
    2534             :                         zend_resource *res;
    2535             : 
    2536           7 :                         res = zend_register_resource(typemap, le_typemap);
    2537           7 :                         add_property_resource(this_ptr, "typemap", res);
    2538             :                 }
    2539             :         }
    2540           5 :         SOAP_CLIENT_END_CODE();
    2541         389 : }
    2542             : /* }}} */
    2543             : 
    2544         402 : static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *action, int version, int one_way, zval *response)
    2545             : {
    2546         402 :         int    ret = TRUE;
    2547             :         char  *buf;
    2548             :         int    buf_size;
    2549             :         zval   func;
    2550             :         zval  params[5];
    2551             :         zval  *trace;
    2552             :         zval  *fault;
    2553         402 :         int    _bailout = 0;
    2554             : 
    2555         402 :         ZVAL_NULL(response);
    2556             : 
    2557         402 :         xmlDocDumpMemory(request, (xmlChar**)&buf, &buf_size);
    2558         402 :         if (!buf) {
    2559           0 :                 add_soap_fault(this_ptr, "HTTP", "Error build soap request", NULL, NULL);
    2560           0 :                 return FALSE;
    2561             :         }
    2562             : 
    2563         402 :         zend_try {
    2564        1418 :                 if ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL &&
    2565         338 :                     (Z_TYPE_P(trace) == IS_TRUE || (Z_TYPE_P(trace) == IS_LONG && Z_LVAL_P(trace) != 0))) {
    2566         338 :                         add_property_stringl(this_ptr, "__last_request", buf, buf_size);
    2567             :                 }
    2568             : 
    2569         804 :                 ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1);
    2570         804 :                 ZVAL_STRINGL(&params[0], buf, buf_size);
    2571         402 :                 if (location == NULL) {
    2572           0 :                         ZVAL_NULL(&params[1]);
    2573             :                 } else {
    2574         804 :                         ZVAL_STRING(&params[1], location);
    2575             :                 }
    2576         402 :                 if (action == NULL) {
    2577           4 :                         ZVAL_NULL(&params[2]);
    2578             :                 } else {
    2579         796 :                         ZVAL_STRING(&params[2], action);
    2580             :                 }
    2581         402 :                 ZVAL_LONG(&params[3], version);
    2582         402 :                 ZVAL_LONG(&params[4], one_way);
    2583             : 
    2584         402 :                 if (call_user_function(NULL, this_ptr, &func, response, 5, params) != SUCCESS) {
    2585           1 :                         add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() failed", NULL, NULL);
    2586           1 :                         ret = FALSE;
    2587         393 :                 } else if (Z_TYPE_P(response) != IS_STRING) {
    2588         321 :                         if (EG(exception) && instanceof_function(EG(exception)->ce, zend_ce_error)) {
    2589             :                                 zval rv;
    2590             :                                 zend_string *msg;
    2591             :                                 zval exception_object;
    2592             : 
    2593           1 :                                 ZVAL_OBJ(&exception_object, EG(exception));
    2594           2 :                                 msg = zval_get_string(zend_read_property(zend_ce_error, &exception_object, "message", sizeof("message")-1, 0, &rv));
    2595             :                                 /* change class */
    2596           1 :                                 EG(exception)->ce = soap_fault_class_entry;
    2597           1 :                                 set_soap_fault(&exception_object, NULL, "Client", ZSTR_VAL(msg), NULL, NULL, NULL);
    2598             :                                 zend_string_release(msg);
    2599         319 :                         } else if ((fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) == NULL) {
    2600           0 :                                 add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() returned non string value", NULL, NULL);
    2601             :                         }
    2602         320 :                         ret = FALSE;
    2603         130 :                 } else if ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL &&
    2604          19 :                     (Z_TYPE_P(trace) == IS_TRUE || (Z_TYPE_P(trace) == IS_LONG && Z_LVAL_P(trace) != 0))) {
    2605          38 :                         add_property_str(this_ptr, "__last_response", zend_string_copy(Z_STR_P(response)));
    2606             :                 }
    2607           8 :         } zend_catch {
    2608           8 :                 _bailout = 1;
    2609         402 :         } zend_end_try();
    2610         402 :         zval_ptr_dtor(&func);
    2611         402 :         zval_ptr_dtor(&params[4]);
    2612         402 :         zval_ptr_dtor(&params[3]);
    2613         402 :         zval_ptr_dtor(&params[2]);
    2614         402 :         zval_ptr_dtor(&params[1]);
    2615         402 :         zval_ptr_dtor(&params[0]);
    2616         402 :         xmlFree(buf);
    2617         402 :         if (_bailout) {
    2618           8 :                 zend_bailout();
    2619             :         }
    2620         394 :         if (ret && (fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) != NULL) {
    2621           0 :                 ret = FALSE;
    2622             :         }
    2623         394 :         return ret;
    2624             : }
    2625             : 
    2626         404 : static void do_soap_call(zend_execute_data *execute_data,
    2627             :                          zval* this_ptr,
    2628             :                          char* function,
    2629             :                          size_t function_len,
    2630             :                          int arg_count,
    2631             :                          zval* real_args,
    2632             :                          zval* return_value,
    2633             :                          char* location,
    2634             :                          char* soap_action,
    2635             :                          char* call_uri,
    2636             :                          HashTable* soap_headers,
    2637             :                          zval* output_headers
    2638             :                         )
    2639             : {
    2640             :         zval *tmp;
    2641             :         zval *trace;
    2642         404 :         sdlPtr sdl = NULL;
    2643         404 :         sdlPtr old_sdl = NULL;
    2644             :         sdlFunctionPtr fn;
    2645         404 :         xmlDocPtr request = NULL;
    2646         404 :         int ret = FALSE;
    2647             :         int soap_version;
    2648             :         zval response;
    2649             :         xmlCharEncodingHandlerPtr old_encoding;
    2650             :         HashTable *old_class_map;
    2651             :         int old_features;
    2652         404 :         HashTable *old_typemap, *typemap = NULL;
    2653         404 :         smart_str action = {0};
    2654             : 
    2655         404 :         SOAP_CLIENT_BEGIN_CODE();
    2656             : 
    2657        1423 :         if ((trace = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace")-1)) != NULL &&
    2658         339 :                 (Z_TYPE_P(trace) == IS_TRUE || (Z_TYPE_P(trace) == IS_LONG && Z_LVAL_P(trace) != 0))) {
    2659         339 :                 zend_hash_str_del(Z_OBJPROP_P(this_ptr), "__last_request", sizeof("__last_request")-1);
    2660         339 :                 zend_hash_str_del(Z_OBJPROP_P(this_ptr), "__last_response", sizeof("__last_response")-1);
    2661             :         }
    2662        1208 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_soap_version", sizeof("_soap_version")-1)) != NULL &&
    2663         401 :                 Z_TYPE_P(tmp) == IS_LONG && Z_LVAL_P(tmp) == SOAP_1_2) {
    2664           2 :                 soap_version = SOAP_1_2;
    2665             :         } else {
    2666         402 :                 soap_version = SOAP_1_1;
    2667             :         }
    2668             : 
    2669         404 :         if (location == NULL) {
    2670         511 :                 if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location")-1)) != NULL &&
    2671             :                     Z_TYPE_P(tmp) == IS_STRING) {
    2672         108 :                   location = Z_STRVAL_P(tmp);
    2673             :                 }
    2674             :         }
    2675             : 
    2676         404 :         if (FIND_SDL_PROPERTY(this_ptr,tmp) != NULL) {
    2677         302 :                 FETCH_SDL_RES(sdl,tmp);
    2678             :         }
    2679         404 :         if (FIND_TYPEMAP_PROPERTY(this_ptr,tmp) != NULL) {
    2680           7 :                 FETCH_TYPEMAP_RES(typemap,tmp);
    2681             :         }
    2682             : 
    2683         404 :         clear_soap_fault(this_ptr);
    2684             : 
    2685         404 :         SOAP_GLOBAL(soap_version) = soap_version;
    2686         404 :         old_sdl = SOAP_GLOBAL(sdl);
    2687         404 :         SOAP_GLOBAL(sdl) = sdl;
    2688         404 :         old_encoding = SOAP_GLOBAL(encoding);
    2689         430 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_encoding", sizeof("_encoding")-1)) != NULL &&
    2690             :             Z_TYPE_P(tmp) == IS_STRING) {
    2691          13 :                 SOAP_GLOBAL(encoding) = xmlFindCharEncodingHandler(Z_STRVAL_P(tmp));
    2692             :         } else {
    2693         391 :                 SOAP_GLOBAL(encoding) = NULL;
    2694             :         }
    2695         404 :         old_class_map = SOAP_GLOBAL(class_map);
    2696         426 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_classmap", sizeof("_classmap")-1)) != NULL &&
    2697             :             Z_TYPE_P(tmp) == IS_ARRAY) {
    2698          11 :                 SOAP_GLOBAL(class_map) = Z_ARRVAL_P(tmp);
    2699             :         } else {
    2700         393 :                 SOAP_GLOBAL(class_map) = NULL;
    2701             :         }
    2702         404 :         old_typemap = SOAP_GLOBAL(typemap);
    2703         404 :         SOAP_GLOBAL(typemap) = typemap;
    2704         404 :         old_features = SOAP_GLOBAL(features);
    2705         578 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_features", sizeof("_features")-1)) != NULL &&
    2706             :             Z_TYPE_P(tmp) == IS_LONG) {
    2707          87 :                 SOAP_GLOBAL(features) = Z_LVAL_P(tmp);
    2708             :         } else {
    2709         317 :                 SOAP_GLOBAL(features) = 0;
    2710             :         }
    2711             : 
    2712         404 :         zend_try {
    2713         404 :                 if (sdl != NULL) {
    2714         302 :                         fn = get_function(sdl, function);
    2715         302 :                         if (fn != NULL) {
    2716         302 :                                 sdlBindingPtr binding = fn->binding;
    2717         302 :                                 int one_way = 0;
    2718             : 
    2719         389 :                                 if (fn->responseName == NULL &&
    2720          87 :                                     fn->responseParameters == NULL &&
    2721             :                                     soap_headers == NULL) {
    2722          87 :                                         one_way = 1;
    2723             :                                 }
    2724             : 
    2725         302 :                                 if (location == NULL) {
    2726         295 :                                         location = binding->location;
    2727             :                                 }
    2728         302 :                                 if (binding->bindingType == BINDING_SOAP) {
    2729         301 :                                         sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
    2730         301 :                                         request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers);
    2731         299 :                                         ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response);
    2732             :                                 } else {
    2733           1 :                                         request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers);
    2734           1 :                                         ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response);
    2735             :                                 }
    2736             : 
    2737         294 :                                 xmlFreeDoc(request);
    2738         294 :                                 request = NULL;
    2739             : 
    2740         343 :                                 if (ret && Z_TYPE(response) == IS_STRING) {
    2741          49 :                                         encode_reset_ns();
    2742          49 :                                         ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers);
    2743          49 :                                         encode_finish();
    2744             :                                 }
    2745             : 
    2746             :                                 zval_dtor(&response);
    2747             : 
    2748             :                         } else {
    2749           0 :                                 smart_str error = {0};
    2750             :                                 smart_str_appends(&error,"Function (\"");
    2751           0 :                                 smart_str_appends(&error,function);
    2752             :                                 smart_str_appends(&error,"\") is not a valid method for this service");
    2753             :                                 smart_str_0(&error);
    2754           0 :                                 add_soap_fault(this_ptr, "Client", ZSTR_VAL(error.s), NULL, NULL);
    2755             :                                 smart_str_free(&error);
    2756             :                         }
    2757             :                 } else {
    2758             :                         zval *uri;
    2759             : 
    2760         204 :                         if ((uri = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri")-1)) == NULL || Z_TYPE_P(uri) != IS_STRING) {
    2761           0 :                                 add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL);
    2762         102 :                         } else if (location == NULL) {
    2763           0 :                                 add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL);
    2764             :                         } else {
    2765         102 :                                 if (call_uri == NULL) {
    2766          43 :                                         call_uri = Z_STRVAL_P(uri);
    2767             :                                 }
    2768         102 :                                 request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers);
    2769             : 
    2770         102 :                                 if (soap_action == NULL) {
    2771          44 :                                         smart_str_appends(&action, call_uri);
    2772             :                                         smart_str_appendc(&action, '#');
    2773          44 :                                         smart_str_appends(&action, function);
    2774             :                                 } else {
    2775          58 :                                         smart_str_appends(&action, soap_action);
    2776             :                                 }
    2777             :                                 smart_str_0(&action);
    2778             : 
    2779         102 :                                 ret = do_request(this_ptr, request, location, ZSTR_VAL(action.s), soap_version, 0, &response);
    2780             : 
    2781             :                                 smart_str_free(&action);
    2782         100 :                                 xmlFreeDoc(request);
    2783         100 :                                 request = NULL;
    2784             : 
    2785         124 :                                 if (ret && Z_TYPE(response) == IS_STRING) {
    2786          24 :                                         encode_reset_ns();
    2787          24 :                                         ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers);
    2788          24 :                                         encode_finish();
    2789             :                                 }
    2790             : 
    2791             :                                 zval_dtor(&response);
    2792             :                         }
    2793             :                 }
    2794             : 
    2795         394 :                 if (!ret) {
    2796             :                         zval* fault;
    2797         326 :                         if ((fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) != NULL) {
    2798         325 :                                 ZVAL_COPY(return_value, fault);
    2799             :                         } else {
    2800           1 :                                 add_soap_fault_ex(return_value, this_ptr, "Client", "Unknown Error", NULL, NULL);
    2801             :                                 Z_ADDREF_P(return_value);
    2802             :                         }
    2803             :                 } else {
    2804             :                         zval* fault;
    2805          68 :                         if ((fault = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault")-1)) != NULL) {
    2806           0 :                                 ZVAL_COPY(return_value, fault);
    2807             :                         }
    2808             :                 }
    2809             : 
    2810        1778 :                 if (!EG(exception) &&
    2811             :                     Z_TYPE_P(return_value) == IS_OBJECT &&
    2812         350 :                     instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry) &&
    2813         324 :                     ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions")-1)) == NULL ||
    2814             :                            Z_TYPE_P(tmp) != IS_FALSE)) {
    2815             :                         Z_ADDREF_P(return_value);
    2816           5 :                         zend_throw_exception_object(return_value);
    2817             :                 }
    2818             : 
    2819          10 :         } zend_catch {
    2820          10 :                 _bailout = 1;
    2821         404 :         } zend_end_try();
    2822             : 
    2823         404 :         if (SOAP_GLOBAL(encoding) != NULL) {
    2824          13 :                 xmlCharEncCloseFunc(SOAP_GLOBAL(encoding));
    2825             :         }
    2826             : 
    2827         404 :         SOAP_GLOBAL(features) = old_features;
    2828         404 :         SOAP_GLOBAL(typemap) = old_typemap;
    2829         404 :         SOAP_GLOBAL(class_map) = old_class_map;
    2830         404 :         SOAP_GLOBAL(encoding) = old_encoding;
    2831         404 :         SOAP_GLOBAL(sdl) = old_sdl;
    2832         404 :         if (_bailout) {
    2833             :                 smart_str_free(&action);
    2834          10 :                 if (request) {
    2835           8 :                         xmlFreeDoc(request);
    2836             :                 }
    2837          10 :                 _bailout = 0;
    2838          10 :                 zend_bailout();
    2839             :         }
    2840          10 :         SOAP_CLIENT_END_CODE();
    2841         395 : }
    2842             : 
    2843           4 : static void verify_soap_headers_array(HashTable *ht)
    2844             : {
    2845             :         zval *tmp;
    2846             : 
    2847          16 :         ZEND_HASH_FOREACH_VAL(ht, tmp) {
    2848          12 :                 if (Z_TYPE_P(tmp) != IS_OBJECT ||
    2849           6 :                     !instanceof_function(Z_OBJCE_P(tmp), soap_header_class_entry)) {
    2850           0 :                         php_error_docref(NULL, E_ERROR, "Invalid SOAP header");
    2851             :                 }
    2852             :         } ZEND_HASH_FOREACH_END();
    2853           4 : }
    2854             : 
    2855             : 
    2856             : /* {{{ proto mixed SoapClient::__call ( string function_name, array arguments [, array options [, array input_headers [, array output_headers]]])
    2857             :    Calls a SOAP function */
    2858         404 : PHP_METHOD(SoapClient, __call)
    2859             : {
    2860         404 :         char *function, *location=NULL, *soap_action = NULL, *uri = NULL;
    2861             :         size_t function_len;
    2862         404 :         int i = 0;
    2863         404 :         HashTable* soap_headers = NULL;
    2864         404 :         zval *options = NULL;
    2865         404 :         zval *headers = NULL;
    2866         404 :         zval *output_headers = NULL;
    2867             :         zval *args;
    2868         404 :         zval *real_args = NULL;
    2869             :         zval *param;
    2870             :         int arg_count;
    2871             :         zval *tmp;
    2872         404 :         zend_bool free_soap_headers = 0;
    2873             :         zval *this_ptr;
    2874             : 
    2875         404 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "sa|a!zz/",
    2876             :                 &function, &function_len, &args, &options, &headers, &output_headers) == FAILURE) {
    2877           0 :                 return;
    2878             :         }
    2879             : 
    2880         404 :         if (options) {
    2881          60 :                 HashTable *hto = Z_ARRVAL_P(options);
    2882          61 :                 if ((tmp = zend_hash_str_find(hto, "location", sizeof("location")-1)) != NULL &&
    2883             :                         Z_TYPE_P(tmp) == IS_STRING) {
    2884           1 :                         location = Z_STRVAL_P(tmp);
    2885             :                 }
    2886             : 
    2887         118 :                 if ((tmp = zend_hash_str_find(hto, "soapaction", sizeof("soapaction")-1)) != NULL &&
    2888             :                         Z_TYPE_P(tmp) == IS_STRING) {
    2889          58 :                         soap_action = Z_STRVAL_P(tmp);
    2890             :                 }
    2891             : 
    2892         119 :                 if ((tmp = zend_hash_str_find(hto, "uri", sizeof("uri")-1)) != NULL &&
    2893             :                         Z_TYPE_P(tmp) == IS_STRING) {
    2894          59 :                         uri = Z_STRVAL_P(tmp);
    2895             :                 }
    2896             :         }
    2897             : 
    2898         416 :         if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
    2899          24 :         } else if (Z_TYPE_P(headers) == IS_ARRAY) {
    2900           2 :                 soap_headers = Z_ARRVAL_P(headers);
    2901           2 :                 verify_soap_headers_array(soap_headers);
    2902           2 :                 free_soap_headers = 0;
    2903          40 :         } else if (Z_TYPE_P(headers) == IS_OBJECT &&
    2904          10 :                    instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry)) {
    2905          10 :             soap_headers = emalloc(sizeof(HashTable));
    2906          10 :                 zend_hash_init(soap_headers, 0, NULL, ZVAL_PTR_DTOR, 0);
    2907          10 :                 zend_hash_next_index_insert(soap_headers, headers);
    2908          10 :                 Z_ADDREF_P(headers);
    2909          10 :                 free_soap_headers = 1;
    2910             :         } else{
    2911           0 :                 php_error_docref(NULL, E_WARNING, "Invalid SOAP header");
    2912           0 :                 return;
    2913             :         }
    2914             : 
    2915             :         /* Add default headers */
    2916         808 :         this_ptr = getThis();
    2917         411 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers")-1)) != NULL && Z_TYPE_P(tmp) == IS_ARRAY) {
    2918           6 :                 HashTable *default_headers = Z_ARRVAL_P(tmp);
    2919           6 :                 if (soap_headers) {
    2920           1 :                         if (!free_soap_headers) {
    2921           1 :                                 soap_headers = zend_array_dup(soap_headers);
    2922           1 :                                 free_soap_headers = 1;
    2923             :                         }
    2924           5 :                         ZEND_HASH_FOREACH_VAL(default_headers, tmp) {
    2925           2 :                                 if(Z_TYPE_P(tmp) == IS_OBJECT) {
    2926             :                                         Z_ADDREF_P(tmp);
    2927           2 :                                         zend_hash_next_index_insert(soap_headers, tmp);
    2928             :                                 }
    2929             :                         } ZEND_HASH_FOREACH_END();
    2930             :                 } else {
    2931           5 :                         soap_headers = Z_ARRVAL_P(tmp);
    2932           5 :                         free_soap_headers = 0;
    2933             :                 }
    2934             :         }
    2935             : 
    2936         404 :         arg_count = zend_hash_num_elements(Z_ARRVAL_P(args));
    2937             : 
    2938         404 :         if (arg_count > 0) {
    2939         358 :                 real_args = safe_emalloc(sizeof(zval), arg_count, 0);
    2940        1254 :                 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), param) {
    2941             :                         /*zval_add_ref(param);*/
    2942         448 :                         ZVAL_DEREF(param);
    2943         448 :                         ZVAL_COPY_VALUE(&real_args[i], param);
    2944         448 :                         i++;
    2945             :                 } ZEND_HASH_FOREACH_END();
    2946             :         }
    2947         404 :         if (output_headers) {
    2948           0 :                 array_init(output_headers);
    2949             :         }
    2950         404 :         do_soap_call(execute_data, this_ptr, function, function_len, arg_count, real_args, return_value, location, soap_action, uri, soap_headers, output_headers);
    2951         395 :         if (arg_count > 0) {
    2952         349 :                 efree(real_args);
    2953             :         }
    2954             : 
    2955         395 :         if (soap_headers && free_soap_headers) {
    2956          11 :                 zend_hash_destroy(soap_headers);
    2957          11 :                 efree(soap_headers);
    2958             :         }
    2959             : }
    2960             : /* }}} */
    2961             : 
    2962             : 
    2963             : /* {{{ proto array SoapClient::__getFunctions ( void )
    2964             :    Returns list of SOAP functions */
    2965           4 : PHP_METHOD(SoapClient, __getFunctions)
    2966             : {
    2967             :         sdlPtr sdl;
    2968             : 
    2969          12 :         FETCH_THIS_SDL(sdl);
    2970             : 
    2971           4 :         if (zend_parse_parameters_none() == FAILURE) {
    2972           0 :                 return;
    2973             :         }
    2974             : 
    2975           4 :         if (sdl) {
    2976           4 :                 smart_str buf = {0};
    2977             :                 sdlFunctionPtr function;
    2978             : 
    2979           4 :                 array_init(return_value);
    2980          18 :                 ZEND_HASH_FOREACH_PTR(&sdl->functions, function) {
    2981           7 :                         function_to_string(function, &buf);
    2982           7 :                         add_next_index_stringl(return_value, ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
    2983             :                         smart_str_free(&buf);
    2984             :                 } ZEND_HASH_FOREACH_END();
    2985             :         }
    2986             : }
    2987             : /* }}} */
    2988             : 
    2989             : 
    2990             : /* {{{ proto array SoapClient::__getTypes ( void )
    2991             :    Returns list of SOAP types */
    2992           4 : PHP_METHOD(SoapClient, __getTypes)
    2993             : {
    2994             :         sdlPtr sdl;
    2995             : 
    2996          12 :         FETCH_THIS_SDL(sdl);
    2997             : 
    2998           4 :         if (zend_parse_parameters_none() == FAILURE) {
    2999           0 :                 return;
    3000             :         }
    3001             : 
    3002           4 :         if (sdl) {
    3003             :                 sdlTypePtr type;
    3004           4 :                 smart_str buf = {0};
    3005             : 
    3006           4 :                 array_init(return_value);
    3007           4 :                 if (sdl->types) {
    3008         108 :                         ZEND_HASH_FOREACH_PTR(sdl->types, type) {
    3009          52 :                                 type_to_string(type, &buf, 0);
    3010          52 :                                 add_next_index_stringl(return_value, ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
    3011             :                                 smart_str_free(&buf);
    3012             :                         } ZEND_HASH_FOREACH_END();
    3013             :                 }
    3014             :         }
    3015             : }
    3016             : /* }}} */
    3017             : 
    3018             : 
    3019             : /* {{{ proto string SoapClient::__getLastRequest ( void )
    3020             :    Returns last SOAP request */
    3021         529 : PHP_METHOD(SoapClient, __getLastRequest)
    3022             : {
    3023             :         zval *tmp;
    3024             : 
    3025         529 :         if (zend_parse_parameters_none() == FAILURE) {
    3026           0 :                 return;
    3027             :         }
    3028             : 
    3029        2116 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_request", sizeof("__last_request")-1)) != NULL &&
    3030             :             Z_TYPE_P(tmp) == IS_STRING) {
    3031         529 :                 RETURN_STR_COPY(Z_STR_P(tmp));
    3032             :         }
    3033           0 :         RETURN_NULL();
    3034             : }
    3035             : /* }}} */
    3036             : 
    3037             : 
    3038             : /* {{{ proto object SoapClient::__getLastResponse ( void )
    3039             :    Returns last SOAP response */
    3040           6 : PHP_METHOD(SoapClient, __getLastResponse)
    3041             : {
    3042             :         zval *tmp;
    3043             : 
    3044           6 :         if (zend_parse_parameters_none() == FAILURE) {
    3045           0 :                 return;
    3046             :         }
    3047             : 
    3048          24 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_response", sizeof("__last_response")-1)) != NULL &&
    3049             :             Z_TYPE_P(tmp) == IS_STRING) {
    3050           6 :                 RETURN_STR_COPY(Z_STR_P(tmp));
    3051             :         }
    3052           0 :         RETURN_NULL();
    3053             : }
    3054             : /* }}} */
    3055             : 
    3056             : 
    3057             : /* {{{ proto string SoapClient::__getLastRequestHeaders(void)
    3058             :    Returns last SOAP request headers */
    3059           0 : PHP_METHOD(SoapClient, __getLastRequestHeaders)
    3060             : {
    3061             :         zval *tmp;
    3062             : 
    3063           0 :         if (zend_parse_parameters_none() == FAILURE) {
    3064           0 :                 return;
    3065             :         }
    3066             : 
    3067           0 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_request_headers", sizeof("__last_request_headers")-1)) != NULL &&
    3068             :             Z_TYPE_P(tmp) == IS_STRING) {
    3069           0 :                 RETURN_STR_COPY(Z_STR_P(tmp));
    3070             :         }
    3071           0 :         RETURN_NULL();
    3072             : }
    3073             : /* }}} */
    3074             : 
    3075             : 
    3076             : /* {{{ proto string SoapClient::__getLastResponseHeaders(void)
    3077             :    Returns last SOAP response headers */
    3078           0 : PHP_METHOD(SoapClient, __getLastResponseHeaders)
    3079             : {
    3080             :         zval *tmp;
    3081             : 
    3082           0 :         if (zend_parse_parameters_none() == FAILURE) {
    3083           0 :                 return;
    3084             :         }
    3085             : 
    3086           0 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()), "__last_response_headers", sizeof("__last_response_headers")-1)) != NULL &&
    3087             :             Z_TYPE_P(tmp) == IS_STRING) {
    3088           0 :                 RETURN_STR_COPY(Z_STR_P(tmp));
    3089             :         }
    3090           0 :         RETURN_NULL();
    3091             : }
    3092             : /* }}} */
    3093             : 
    3094             : 
    3095             : /* {{{ proto string SoapClient::__doRequest()
    3096             :    SoapClient::__doRequest() */
    3097         321 : PHP_METHOD(SoapClient, __doRequest)
    3098             : {
    3099             :         zend_string *buf;
    3100             :         char      *location, *action;
    3101             :         size_t     location_size, action_size;
    3102             :         zend_long  version;
    3103         321 :         zend_long  one_way = 0;
    3104         642 :         zval      *this_ptr = getThis();
    3105             : 
    3106         321 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sssl|l",
    3107             :             &buf,
    3108             :             &location, &location_size,
    3109             :             &action, &action_size,
    3110             :             &version, &one_way) == FAILURE) {
    3111           0 :                 return;
    3112             :         }
    3113         321 :         if (SOAP_GLOBAL(features) & SOAP_WAIT_ONE_WAY_CALLS) {
    3114           0 :                 one_way = 0;
    3115             :         }
    3116         321 :         if (one_way) {
    3117          85 :                 if (make_http_soap_request(this_ptr, buf, location, action, version, NULL)) {
    3118           0 :                         RETURN_EMPTY_STRING();
    3119             :                 }
    3120         236 :         } else if (make_http_soap_request(this_ptr, buf, location, action, version,
    3121             :             return_value)) {
    3122           2 :                 return;
    3123             :         }
    3124         319 :         RETURN_NULL();
    3125             : }
    3126             : /* }}} */
    3127             : 
    3128             : /* {{{ proto void SoapClient::__setCookie(string name [, strung value])
    3129             :    Sets cookie thet will sent with SOAP request.
    3130             :    The call to this function will effect all following calls of SOAP methods.
    3131             :    If value is not specified cookie is removed. */
    3132           1 : PHP_METHOD(SoapClient, __setCookie)
    3133             : {
    3134             :         char *name;
    3135           1 :         char *val = NULL;
    3136           1 :         size_t  name_len, val_len = 0;
    3137             :         zval *cookies;
    3138           2 :         zval *this_ptr = getThis();
    3139             : 
    3140           1 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s", &name, &name_len, &val, &val_len) == FAILURE) {
    3141           0 :                 return;
    3142             :         }
    3143             : 
    3144           1 :         if (val == NULL) {
    3145           0 :                 if ((cookies = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1)) != NULL &&
    3146             :                     Z_TYPE_P(cookies) == IS_ARRAY) {
    3147           0 :                         zend_hash_str_del(Z_ARRVAL_P(cookies), name, name_len);
    3148             :                 }
    3149             :         } else {
    3150             :                 zval zcookie;
    3151             : 
    3152           1 :                 if ((cookies = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1)) == NULL ||
    3153             :                     Z_TYPE_P(cookies) != IS_ARRAY) {
    3154             :                         zval tmp_cookies;
    3155             : 
    3156           1 :                         array_init(&tmp_cookies);
    3157           1 :                         cookies = zend_hash_str_update(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies")-1, &tmp_cookies);
    3158             :                 }
    3159             : 
    3160           1 :                 array_init(&zcookie);
    3161           1 :                 add_index_stringl(&zcookie, 0, val, val_len);
    3162           1 :                 add_assoc_zval_ex(cookies, name, name_len, &zcookie);
    3163             :         }
    3164             : }
    3165             : /* }}} */
    3166             : 
    3167             : /* {{{ proto array SoapClient::__getCookies ( void )
    3168             :    Returns list of cookies */
    3169           1 : PHP_METHOD(SoapClient, __getCookies)
    3170             : {
    3171             :         zval *cookies;
    3172             : 
    3173           1 :         if (zend_parse_parameters_none() == FAILURE) {
    3174           0 :                 return;
    3175             :         }
    3176             : 
    3177             : 
    3178           4 :         if ((cookies = zend_hash_str_find(Z_OBJPROP_P(getThis()), "_cookies", sizeof("_cookies")-1)) != NULL &&
    3179             :             Z_TYPE_P(cookies) == IS_ARRAY) {
    3180           1 :                 RETURN_ARR(zend_array_dup(Z_ARRVAL_P(cookies)));
    3181             :         } else {
    3182           0 :                 array_init(return_value);
    3183             :         }
    3184             : }
    3185             : /* }}} */
    3186             : 
    3187             : /* {{{ proto void SoapClient::__setSoapHeaders(array SoapHeaders)
    3188             :    Sets SOAP headers for subsequent calls (replaces any previous
    3189             :    values).
    3190             :    If no value is specified, all of the headers are removed. */
    3191           4 : PHP_METHOD(SoapClient, __setSoapHeaders)
    3192             : {
    3193           4 :         zval *headers = NULL;
    3194           8 :         zval *this_ptr = getThis();
    3195             : 
    3196           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|z", &headers) == FAILURE) {
    3197           0 :                 return;
    3198             :         }
    3199             : 
    3200           8 :         if (headers == NULL || Z_TYPE_P(headers) == IS_NULL) {
    3201           1 :                 zend_hash_str_del(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers")-1);
    3202           6 :         } else if (Z_TYPE_P(headers) == IS_ARRAY) {
    3203             :                 zval *default_headers;
    3204             : 
    3205           2 :                 verify_soap_headers_array(Z_ARRVAL_P(headers));
    3206           2 :                 if ((default_headers = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "__default_headers", sizeof("__default_headers")-1)) == NULL) {
    3207           2 :                         add_property_zval(this_ptr, "__default_headers", headers);
    3208             :                 }
    3209           4 :         } else if (Z_TYPE_P(headers) == IS_OBJECT &&
    3210           1 :                    instanceof_function(Z_OBJCE_P(headers), soap_header_class_entry)) {
    3211             :                 zval default_headers;
    3212             : 
    3213           1 :                 array_init(&default_headers);
    3214           1 :                 Z_ADDREF_P(headers);
    3215           1 :                 add_next_index_zval(&default_headers, headers);
    3216           1 :                 add_property_zval(this_ptr, "__default_headers", &default_headers);
    3217             :                 Z_DELREF_P(&default_headers);
    3218             :         } else{
    3219           0 :                 php_error_docref(NULL, E_WARNING, "Invalid SOAP header");
    3220             :         }
    3221           4 :         RETURN_TRUE;
    3222             : }
    3223             : /* }}} */
    3224             : 
    3225             : 
    3226             : 
    3227             : /* {{{ proto string SoapClient::__setLocation([string new_location])
    3228             :    Sets the location option (the endpoint URL that will be touched by the
    3229             :    following SOAP requests).
    3230             :    If new_location is not specified or null then SoapClient will use endpoint
    3231             :    from WSDL file.
    3232             :    The function returns old value of location options. */
    3233           6 : PHP_METHOD(SoapClient, __setLocation)
    3234             : {
    3235           6 :         char *location = NULL;
    3236           6 :         size_t  location_len = 0;
    3237             :         zval *tmp;
    3238          12 :         zval *this_ptr = getThis();
    3239             : 
    3240           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s", &location, &location_len) == FAILURE) {
    3241           0 :                 return;
    3242             :         }
    3243             : 
    3244          14 :         if ((tmp = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "location", sizeof("location")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
    3245           4 :                 RETVAL_STR_COPY(Z_STR_P(tmp));
    3246             :         } else {
    3247           2 :                 RETVAL_NULL();
    3248             :         }
    3249             : 
    3250           9 :         if (location && location_len) {
    3251           3 :                 add_property_stringl(this_ptr, "location", location, location_len);
    3252             :         } else {
    3253           3 :                 zend_hash_str_del(Z_OBJPROP_P(this_ptr), "location", sizeof("location")-1);
    3254             :         }
    3255             : }
    3256             : /* }}} */
    3257             : 
    3258         404 : static void clear_soap_fault(zval *obj)
    3259             : {
    3260         808 :         if (obj != NULL && Z_TYPE_P(obj) == IS_OBJECT) {
    3261         404 :                 zend_hash_str_del(Z_OBJPROP_P(obj), "__soap_fault", sizeof("__soap_fault")-1);
    3262             :         }
    3263         404 : }
    3264             : 
    3265           8 : static void add_soap_fault_ex(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail)
    3266             : {
    3267           8 :         ZVAL_NULL(fault);
    3268           8 :         set_soap_fault(fault, NULL, fault_code, fault_string, fault_actor, fault_detail, NULL);
    3269           8 :         add_property_zval(obj, "__soap_fault", fault);
    3270             :         Z_DELREF_P(fault);
    3271           8 : }
    3272             : 
    3273         325 : void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail)
    3274             : {
    3275             :         zval fault;
    3276             : 
    3277         325 :         ZVAL_NULL(&fault);
    3278         325 :         set_soap_fault(&fault, NULL, fault_code, fault_string, fault_actor, fault_detail, NULL);
    3279         325 :         add_property_zval(obj, "__soap_fault", &fault);
    3280             :         Z_DELREF(fault);
    3281         325 : }
    3282             : 
    3283         433 : static void set_soap_fault(zval *obj, char *fault_code_ns, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, char *name)
    3284             : {
    3285         433 :         if (Z_TYPE_P(obj) != IS_OBJECT) {
    3286         364 :                 object_init_ex(obj, soap_fault_class_entry);
    3287             :         }
    3288             : 
    3289         433 :         add_property_string(obj, "faultstring", fault_string ? fault_string : "");
    3290         433 :         zend_update_property_string(zend_ce_exception, obj, "message", sizeof("message")-1, (fault_string ? fault_string : ""));
    3291             : 
    3292         433 :         if (fault_code != NULL) {
    3293         433 :                 int soap_version = SOAP_GLOBAL(soap_version);
    3294             : 
    3295         433 :                 if (fault_code_ns) {
    3296           0 :                         add_property_string(obj, "faultcode", fault_code);
    3297           0 :                         add_property_string(obj, "faultcodens", fault_code_ns);
    3298             :                 } else {
    3299         433 :                         if (soap_version == SOAP_1_1) {
    3300         405 :                                 add_property_string(obj, "faultcode", fault_code);
    3301        1467 :                                 if (strcmp(fault_code,"Client") == 0 ||
    3302         397 :                                     strcmp(fault_code,"Server") == 0 ||
    3303         333 :                                     strcmp(fault_code,"VersionMismatch") == 0 ||
    3304         332 :                                   strcmp(fault_code,"MustUnderstand") == 0) {
    3305          74 :                                         add_property_string(obj, "faultcodens", SOAP_1_1_ENV_NAMESPACE);
    3306             :                                 }
    3307          28 :                         } else if (soap_version == SOAP_1_2) {
    3308          28 :                                 if (strcmp(fault_code,"Client") == 0) {
    3309           9 :                                         add_property_string(obj, "faultcode", "Sender");
    3310           9 :                                         add_property_string(obj, "faultcodens", SOAP_1_2_ENV_NAMESPACE);
    3311          19 :                                 } else if (strcmp(fault_code,"Server") == 0) {
    3312           8 :                                         add_property_string(obj, "faultcode", "Receiver");
    3313           8 :                                         add_property_string(obj, "faultcodens", SOAP_1_2_ENV_NAMESPACE);
    3314          33 :                                 } else if (strcmp(fault_code,"VersionMismatch") == 0 ||
    3315          10 :                                            strcmp(fault_code,"MustUnderstand") == 0 ||
    3316           6 :                                            strcmp(fault_code,"DataEncodingUnknown") == 0) {
    3317           6 :                                         add_property_string(obj, "faultcode", fault_code);
    3318           6 :                                         add_property_string(obj, "faultcodens", SOAP_1_2_ENV_NAMESPACE);
    3319             :                                 } else {
    3320           5 :                                         add_property_string(obj, "faultcode", fault_code);
    3321             :                                 }
    3322             :                         }
    3323             :                 }
    3324             :         }
    3325         433 :         if (fault_actor != NULL) {
    3326           1 :                 add_property_string(obj, "faultactor", fault_actor);
    3327             :         }
    3328         493 :         if (fault_detail != NULL && Z_TYPE_P(fault_detail) != IS_UNDEF) {
    3329          51 :                 add_property_zval(obj, "detail", fault_detail);
    3330             :         }
    3331         433 :         if (name != NULL) {
    3332          55 :                 add_property_string(obj, "_name", name);
    3333             :         }
    3334         433 : }
    3335             : 
    3336         484 : static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, int *num_params, zval **parameters)
    3337             : {
    3338         484 :         int cur_param = 0,num_of_params = 0;
    3339         484 :         zval *tmp_parameters = NULL;
    3340             : 
    3341         484 :         if (function != NULL) {
    3342             :                 sdlParamPtr param;
    3343             :                 xmlNodePtr val;
    3344         414 :                 int     use_names = 0;
    3345             : 
    3346         414 :                 if (function->requestParameters == NULL) {
    3347           0 :                         return;
    3348             :                 }
    3349         414 :                 num_of_params = zend_hash_num_elements(function->requestParameters);
    3350        1274 :                 ZEND_HASH_FOREACH_PTR(function->requestParameters, param) {
    3351         430 :                         if (get_node(params, param->paramName) != NULL) {
    3352         309 :                                 use_names = 1;
    3353             :                         }
    3354             :                 } ZEND_HASH_FOREACH_END();
    3355         414 :                 if (use_names) {
    3356         252 :                         tmp_parameters = safe_emalloc(num_of_params, sizeof(zval), 0);
    3357         865 :                         ZEND_HASH_FOREACH_PTR(function->requestParameters, param) {
    3358         309 :                                 val = get_node(params, param->paramName);
    3359         309 :                                 if (!val) {
    3360             :                                         /* TODO: may be "nil" is not OK? */
    3361           0 :                                         ZVAL_NULL(&tmp_parameters[cur_param]);
    3362             :                                 } else {
    3363         309 :                                         master_to_zval(&tmp_parameters[cur_param], param->encode, val);
    3364             :                                 }
    3365         304 :                                 cur_param++;
    3366             :                         } ZEND_HASH_FOREACH_END();
    3367         247 :                         *parameters = tmp_parameters;
    3368         247 :                         *num_params = num_of_params;
    3369         247 :                         return;
    3370             :                 }
    3371             :         }
    3372         232 :         if (params) {
    3373             :                 xmlNodePtr trav;
    3374             : 
    3375         157 :                 num_of_params = 0;
    3376         157 :                 trav = params;
    3377         491 :                 while (trav != NULL) {
    3378         177 :                         if (trav->type == XML_ELEMENT_NODE) {
    3379         175 :                                 num_of_params++;
    3380             :                         }
    3381         177 :                         trav = trav->next;
    3382             :                 }
    3383             : 
    3384         687 :                 if (num_of_params == 1 &&
    3385             :                     function &&
    3386         118 :                     function->binding &&
    3387         118 :                     function->binding->bindingType == BINDING_SOAP &&
    3388         118 :                     ((sdlSoapBindingFunctionPtr)function->bindingAttributes)->style == SOAP_DOCUMENT &&
    3389          87 :                     (function->requestParameters == NULL ||
    3390          87 :                      zend_hash_num_elements(function->requestParameters) == 0) &&
    3391           1 :                     strcmp((char *)params->name, function->functionName) == 0) {
    3392           1 :                         num_of_params = 0;
    3393         156 :                 } else if (num_of_params > 0) {
    3394         154 :                         tmp_parameters = safe_emalloc(num_of_params, sizeof(zval), 0);
    3395             : 
    3396         154 :                         trav = params;
    3397         481 :                         while (trav != 0 && cur_param < num_of_params) {
    3398         174 :                                 if (trav->type == XML_ELEMENT_NODE) {
    3399             :                                         encodePtr enc;
    3400         174 :                                         sdlParamPtr param = NULL;
    3401         294 :                                         if (function != NULL &&
    3402         120 :                                             (param = zend_hash_index_find_ptr(function->requestParameters, cur_param)) == NULL) {
    3403           0 :                                                                                         soap_server_fault("Client", "Error cannot find parameter", NULL, NULL, NULL);
    3404             :                                         }
    3405         174 :                                         if (param == NULL) {
    3406          54 :                                                 enc = NULL;
    3407             :                                         } else {
    3408         120 :                                                 enc = param->encode;
    3409             :                                         }
    3410         174 :                                         master_to_zval(&tmp_parameters[cur_param], enc, trav);
    3411         173 :                                         cur_param++;
    3412             :                                 }
    3413         173 :                                 trav = trav->next;
    3414             :                         }
    3415             :                 }
    3416             :         }
    3417         231 :         if (num_of_params > cur_param) {
    3418           0 :                 soap_server_fault("Client","Missing parameter", NULL, NULL, NULL);
    3419             :         }
    3420         231 :         (*parameters) = tmp_parameters;
    3421         231 :         (*num_params) = num_of_params;
    3422             : }
    3423             : 
    3424         479 : static sdlFunctionPtr find_function(sdlPtr sdl, xmlNodePtr func, zval* function_name)
    3425             : {
    3426             :         sdlFunctionPtr function;
    3427             : 
    3428         479 :         function = get_function(sdl, (char*)func->name);
    3429         479 :         if (function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    3430         339 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3431         339 :                 if (fnb->style == SOAP_DOCUMENT) {
    3432          90 :                         if (func->children != NULL ||
    3433          13 :                             (function->requestParameters != NULL &&
    3434          13 :                              zend_hash_num_elements(function->requestParameters) > 0)) {
    3435          63 :                                 function = NULL;
    3436             :                         }
    3437             :                 }
    3438             :         }
    3439         479 :         if (sdl != NULL && function == NULL) {
    3440         140 :                 function = get_doc_function(sdl, func);
    3441             :         }
    3442             : 
    3443         479 :         if (function != NULL) {
    3444         774 :                 ZVAL_STRING(function_name, (char *)function->functionName);
    3445             :         } else {
    3446         184 :                 ZVAL_STRING(function_name, (char *)func->name);
    3447             :         }
    3448             : 
    3449         479 :         return function;
    3450             : }
    3451             : 
    3452         473 : static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, char* actor, zval *function_name, int *num_params, zval **parameters, int *version, soapHeader **headers)
    3453             : {
    3454         473 :         char* envelope_ns = NULL;
    3455             :         xmlNodePtr trav,env,head,body,func;
    3456             :         xmlAttrPtr attr;
    3457             :         sdlFunctionPtr function;
    3458             : 
    3459         473 :         encode_reset_ns();
    3460             : 
    3461             :         /* Get <Envelope> element */
    3462         473 :         env = NULL;
    3463         473 :         trav = request->children;
    3464        1417 :         while (trav != NULL) {
    3465         473 :                 if (trav->type == XML_ELEMENT_NODE) {
    3466         872 :                         if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_1_ENV_NAMESPACE)) {
    3467         399 :                                 env = trav;
    3468         399 :                                 *version = SOAP_1_1;
    3469         399 :                                 envelope_ns = SOAP_1_1_ENV_NAMESPACE;
    3470         399 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_1;
    3471         146 :                         } else if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_2_ENV_NAMESPACE)) {
    3472          72 :                                 env = trav;
    3473          72 :                                 *version = SOAP_1_2;
    3474          72 :                                 envelope_ns = SOAP_1_2_ENV_NAMESPACE;
    3475          72 :                                 SOAP_GLOBAL(soap_version) = SOAP_1_2;
    3476             :                         } else {
    3477           2 :                                 soap_server_fault("VersionMismatch", "Wrong Version", NULL, NULL, NULL);
    3478             :                         }
    3479             :                 }
    3480         471 :                 trav = trav->next;
    3481             :         }
    3482         471 :         if (env == NULL) {
    3483           0 :                 soap_server_fault("Client", "looks like we got XML without \"Envelope\" element", NULL, NULL, NULL);
    3484             :         }
    3485             : 
    3486         471 :         attr = env->properties;
    3487        1224 :         while (attr != NULL) {
    3488         284 :                 if (attr->ns == NULL) {
    3489           1 :                         soap_server_fault("Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL, NULL, NULL);
    3490         283 :                 } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
    3491           1 :                         if (*version == SOAP_1_2) {
    3492           1 :                                 soap_server_fault("Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL, NULL);
    3493           0 :                         } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3494           0 :                                 soap_server_fault("Client", "Unknown data encoding style", NULL, NULL, NULL);
    3495             :                         }
    3496             :                 }
    3497         282 :                 attr = attr->next;
    3498             :         }
    3499             : 
    3500             :         /* Get <Header> element */
    3501         469 :         head = NULL;
    3502         469 :         trav = env->children;
    3503         939 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    3504           1 :                 trav = trav->next;
    3505             :         }
    3506         469 :         if (trav != NULL && node_is_equal_ex(trav,"Header",envelope_ns)) {
    3507          49 :                 head = trav;
    3508          49 :                 trav = trav->next;
    3509             :         }
    3510             : 
    3511             :         /* Get <Body> element */
    3512         469 :         body = NULL;
    3513         938 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    3514           0 :                 trav = trav->next;
    3515             :         }
    3516         469 :         if (trav != NULL && node_is_equal_ex(trav,"Body",envelope_ns)) {
    3517         468 :                 body = trav;
    3518         468 :                 trav = trav->next;
    3519             :         }
    3520         938 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
    3521           0 :                 trav = trav->next;
    3522             :         }
    3523         469 :         if (body == NULL) {
    3524           1 :                 soap_server_fault("Client", "Body must be present in a SOAP envelope", NULL, NULL, NULL);
    3525             :         }
    3526         468 :         attr = body->properties;
    3527         937 :         while (attr != NULL) {
    3528           2 :                 if (attr->ns == NULL) {
    3529           0 :                         if (*version == SOAP_1_2) {
    3530           0 :                                 soap_server_fault("Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL, NULL, NULL);
    3531             :                         }
    3532           2 :                 } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
    3533           1 :                         if (*version == SOAP_1_2) {
    3534           1 :                                 soap_server_fault("Client", "encodingStyle cannot be specified on the Body", NULL, NULL, NULL);
    3535           0 :                         } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3536           0 :                                 soap_server_fault("Client", "Unknown data encoding style", NULL, NULL, NULL);
    3537             :                         }
    3538             :                 }
    3539           1 :                 attr = attr->next;
    3540             :         }
    3541             : 
    3542         467 :         if (trav != NULL && *version == SOAP_1_2) {
    3543           1 :                 soap_server_fault("Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL, NULL);
    3544             :         }
    3545             : 
    3546         466 :         func = NULL;
    3547         466 :         trav = body->children;
    3548         961 :         while (trav != NULL) {
    3549         465 :                 if (trav->type == XML_ELEMENT_NODE) {
    3550             : /*
    3551             :                         if (func != NULL) {
    3552             :                                 soap_server_fault("Client", "looks like we got \"Body\" with several functions call", NULL, NULL, NULL);
    3553             :                         }
    3554             : */
    3555         436 :                         func = trav;
    3556         436 :                         break; /* FIXME: the rest of body is ignored */
    3557             :                 }
    3558          29 :                 trav = trav->next;
    3559             :         }
    3560         466 :         if (func == NULL) {
    3561          30 :                 function = get_doc_function(sdl, NULL);
    3562          30 :                 if (function != NULL) {
    3563          60 :                         ZVAL_STRING(function_name, (char *)function->functionName);
    3564             :                 } else {
    3565           0 :                         soap_server_fault("Client", "looks like we got \"Body\" without function call", NULL, NULL, NULL);
    3566             :                 }
    3567             :         } else {
    3568         436 :                 if (*version == SOAP_1_1) {
    3569         398 :                         attr = get_attribute_ex(func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE);
    3570         398 :                         if (attr && strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3571           0 :                                 soap_server_fault("Client","Unknown Data Encoding Style", NULL, NULL, NULL);
    3572             :                         }
    3573             :                 } else {
    3574          38 :                         attr = get_attribute_ex(func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE);
    3575          38 :                         if (attr && strcmp((char*)attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) {
    3576           1 :                                 soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL, NULL);
    3577             :                         }
    3578             :                 }
    3579         435 :                 function = find_function(sdl, func, function_name);
    3580         435 :                 if (sdl != NULL && function == NULL) {
    3581           1 :                         if (*version == SOAP_1_2) {
    3582           1 :                                 soap_server_fault("rpc:ProcedureNotPresent","Procedure not present", NULL, NULL, NULL);
    3583             :                         } else {
    3584           0 :                                 php_error(E_ERROR, "Procedure '%s' not present", func->name);
    3585             :                         }
    3586             :                 }
    3587             :         }
    3588             : 
    3589         464 :         *headers = NULL;
    3590         464 :         if (head) {
    3591          47 :                 soapHeader *h, *last = NULL;
    3592             : 
    3593          47 :                 attr = head->properties;
    3594          94 :                 while (attr != NULL) {
    3595           0 :                         if (attr->ns == NULL) {
    3596           0 :                                 soap_server_fault("Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL, NULL, NULL);
    3597           0 :                         } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
    3598           0 :                                 if (*version == SOAP_1_2) {
    3599           0 :                                         soap_server_fault("Client", "encodingStyle cannot be specified on the Header", NULL, NULL, NULL);
    3600           0 :                                 } else if (strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3601           0 :                                         soap_server_fault("Client", "Unknown data encoding style", NULL, NULL, NULL);
    3602             :                                 }
    3603             :                         }
    3604           0 :                         attr = attr->next;
    3605             :                 }
    3606          47 :                 trav = head->children;
    3607         142 :                 while (trav != NULL) {
    3608          51 :                         if (trav->type == XML_ELEMENT_NODE) {
    3609          51 :                                 xmlNodePtr hdr_func = trav;
    3610          51 :                                 int mustUnderstand = 0;
    3611             : 
    3612          51 :                                 if (*version == SOAP_1_1) {
    3613          13 :                                         attr = get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE);
    3614          13 :                                         if (attr && strcmp((char*)attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
    3615           0 :                                                 soap_server_fault("Client","Unknown Data Encoding Style", NULL, NULL, NULL);
    3616             :                                         }
    3617          13 :                                         attr = get_attribute_ex(hdr_func->properties,"actor",envelope_ns);
    3618          13 :                                         if (attr != NULL) {
    3619           2 :                                                 if (strcmp((char*)attr->children->content,SOAP_1_1_ACTOR_NEXT) != 0 &&
    3620           0 :                                                     (actor == NULL || strcmp((char*)attr->children->content,actor) != 0)) {
    3621             :                                                   goto ignore_header;
    3622             :                                                 }
    3623             :                                         }
    3624          38 :                                 } else if (*version == SOAP_1_2) {
    3625          38 :                                         attr = get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE);
    3626          38 :                                         if (attr && strcmp((char*)attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) {
    3627           0 :                                                 soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL, NULL);
    3628             :                                         }
    3629          38 :                                         attr = get_attribute_ex(hdr_func->properties,"role",envelope_ns);
    3630          38 :                                         if (attr != NULL) {
    3631          52 :                                                 if (strcmp((char*)attr->children->content,SOAP_1_2_ACTOR_UNLIMATERECEIVER) != 0 &&
    3632          16 :                                                     strcmp((char*)attr->children->content,SOAP_1_2_ACTOR_NEXT) != 0 &&
    3633          10 :                                                     (actor == NULL || strcmp((char*)attr->children->content,actor) != 0)) {
    3634             :                                                   goto ignore_header;
    3635             :                                                 }
    3636             :                                         }
    3637             :                                 }
    3638          47 :                                 attr = get_attribute_ex(hdr_func->properties,"mustUnderstand",envelope_ns);
    3639          47 :                                 if (attr) {
    3640          53 :                                         if (strcmp((char*)attr->children->content,"1") == 0 ||
    3641          10 :                                             strcmp((char*)attr->children->content,"true") == 0) {
    3642          18 :                                                 mustUnderstand = 1;
    3643          17 :                                         } else if (strcmp((char*)attr->children->content,"0") == 0 ||
    3644           6 :                                                    strcmp((char*)attr->children->content,"false") == 0) {
    3645           4 :                                                 mustUnderstand = 0;
    3646             :                                         } else {
    3647           3 :                                                 soap_server_fault("Client","mustUnderstand value is not boolean", NULL, NULL, NULL);
    3648             :                                         }
    3649             :                                 }
    3650          44 :                                 h = emalloc(sizeof(soapHeader));
    3651          44 :                                 memset(h, 0, sizeof(soapHeader));
    3652          44 :                                 h->mustUnderstand = mustUnderstand;
    3653          44 :                                 h->function = find_function(sdl, hdr_func, &h->function_name);
    3654          44 :                                 if (!h->function && sdl && function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    3655             :                                         sdlSoapBindingFunctionHeaderPtr hdr;
    3656          28 :                                         sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3657          28 :                                         if (fnb->input.headers) {
    3658          23 :                                                 smart_str key = {0};
    3659             : 
    3660          23 :                                                 if (hdr_func->ns) {
    3661          23 :                                                         smart_str_appends(&key, (char*)hdr_func->ns->href);
    3662             :                                                         smart_str_appendc(&key, ':');
    3663             :                                                 }
    3664          23 :                                                 smart_str_appendl(&key, Z_STRVAL(h->function_name), Z_STRLEN(h->function_name));
    3665             :                                                 smart_str_0(&key);
    3666          46 :                                                 if ((hdr = zend_hash_find_ptr(fnb->input.headers, key.s)) != NULL) {
    3667          21 :                                                         h->hdr = hdr;
    3668             :                                                 }
    3669             :                                                 smart_str_free(&key);
    3670             :                                         }
    3671             :                                 }
    3672          44 :                                 if (h->hdr) {
    3673          21 :                                         h->num_params = 1;
    3674          21 :                                         h->parameters = emalloc(sizeof(zval));
    3675          21 :                                         master_to_zval(&h->parameters[0], h->hdr->encode, hdr_func);
    3676             :                                 } else {
    3677          23 :                                         if (h->function && h->function->binding && h->function->binding->bindingType == BINDING_SOAP) {
    3678          15 :                                                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)h->function->bindingAttributes;
    3679          15 :                                                 if (fnb->style == SOAP_RPC) {
    3680           0 :                                                         hdr_func = hdr_func->children;
    3681             :                                                 }
    3682             :                                         }
    3683          23 :                                         deserialize_parameters(hdr_func, h->function, &h->num_params, &h->parameters);
    3684             :                                 }
    3685          44 :                                 ZVAL_NULL(&h->retval);
    3686          44 :                                 if (last == NULL) {
    3687          40 :                                         *headers = h;
    3688             :                                 } else {
    3689           4 :                                         last->next = h;
    3690             :                                 }
    3691          44 :                                 last = h;
    3692             :                         }
    3693             : ignore_header:
    3694          48 :                         trav = trav->next;
    3695             :                 }
    3696             :         }
    3697             : 
    3698         860 :         if (function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    3699         399 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3700         399 :                 if (fnb->style == SOAP_RPC) {
    3701         275 :                         func = func->children;
    3702             :                 }
    3703             :         } else {
    3704          62 :                 func = func->children;
    3705             :         }
    3706         461 :         deserialize_parameters(func, function, num_params, parameters);
    3707             : 
    3708         455 :         encode_finish();
    3709             : 
    3710         455 :         return function;
    3711             : }
    3712             : 
    3713          32 : static void set_soap_header_attributes(xmlNodePtr h, HashTable *ht, int version)
    3714             : {
    3715             :         zval *tmp;
    3716             : 
    3717          64 :         if ((tmp = zend_hash_str_find(ht, "mustUnderstand", sizeof("mustUnderstand")-1)) != NULL &&
    3718             :             Z_TYPE_P(tmp) == IS_TRUE) {
    3719           8 :                 if (version == SOAP_1_1) {
    3720           8 :                         xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":mustUnderstand"), BAD_CAST("1"));
    3721             :                 } else {
    3722           0 :                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":mustUnderstand"), BAD_CAST("true"));
    3723             :                 }
    3724             :         }
    3725          32 :         if ((tmp = zend_hash_str_find(ht, "actor", sizeof("actor")-1)) != NULL) {
    3726           2 :                 if (Z_TYPE_P(tmp) == IS_STRING) {
    3727           0 :                         if (version == SOAP_1_1) {
    3728           0 :                                 xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(Z_STRVAL_P(tmp)));
    3729             :                         } else {
    3730           0 :                                 xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(Z_STRVAL_P(tmp)));
    3731             :                         }
    3732           2 :                 } else if (Z_TYPE_P(tmp) == IS_LONG) {
    3733           2 :                         if (version == SOAP_1_1) {
    3734           2 :                                 if (Z_LVAL_P(tmp) == SOAP_ACTOR_NEXT) {
    3735           2 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_1_ENV_NS_PREFIX":actor"), BAD_CAST(SOAP_1_1_ACTOR_NEXT));
    3736             :                                 }
    3737             :                         } else {
    3738           0 :                                 if (Z_LVAL_P(tmp) == SOAP_ACTOR_NEXT) {
    3739           0 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_NEXT));
    3740           0 :                                 } else if (Z_LVAL_P(tmp) == SOAP_ACTOR_NONE) {
    3741           0 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_NONE));
    3742           0 :                                 } else if (Z_LVAL_P(tmp) == SOAP_ACTOR_UNLIMATERECEIVER) {
    3743           0 :                                         xmlSetProp(h, BAD_CAST(SOAP_1_2_ENV_NS_PREFIX":role"), BAD_CAST(SOAP_1_2_ACTOR_UNLIMATERECEIVER));
    3744             :                                 }
    3745             :                         }
    3746             :                 }
    3747             :         }
    3748          32 : }
    3749             : 
    3750         391 : static int serialize_response_call2(xmlNodePtr body, sdlFunctionPtr function, char *function_name, char *uri, zval *ret, int version, int main, xmlNodePtr *node)
    3751             : {
    3752         391 :         xmlNodePtr method = NULL, param;
    3753         391 :         sdlParamPtr parameter = NULL;
    3754             :         int param_count;
    3755             :         int style, use;
    3756         391 :         xmlNsPtr ns = NULL;
    3757             : 
    3758         733 :         if (function != NULL && function->binding->bindingType == BINDING_SOAP) {
    3759         342 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    3760             : 
    3761         342 :                 style = fnb->style;
    3762         342 :                 use = fnb->output.use;
    3763         342 :                 if (style == SOAP_RPC) {
    3764         239 :                         ns = encode_add_ns(body, fnb->output.ns);
    3765         239 :                         if (function->responseName) {
    3766         157 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->responseName), NULL);
    3767          82 :                         } else if (function->responseParameters) {
    3768           0 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->functionName), NULL);
    3769             :                         }
    3770             :                 }
    3771             :         } else {
    3772          49 :                 style = main?SOAP_RPC:SOAP_DOCUMENT;
    3773          49 :                 use = main?SOAP_ENCODED:SOAP_LITERAL;
    3774          49 :                 if (style == SOAP_RPC) {
    3775          49 :                         ns = encode_add_ns(body, uri);
    3776          49 :                         method = xmlNewChild(body, ns, BAD_CAST(function_name), NULL);
    3777             :                 }
    3778             :         }
    3779             : 
    3780         391 :         if (function != NULL) {
    3781         342 :                 if (function->responseParameters) {
    3782         260 :                         param_count = zend_hash_num_elements(function->responseParameters);
    3783             :                 } else {
    3784          82 :                   param_count = 0;
    3785             :                 }
    3786             :         } else {
    3787          49 :           param_count = 1;
    3788             :         }
    3789             : 
    3790         391 :         if (param_count == 1) {
    3791         276 :                 parameter = get_param(function, NULL, 0, TRUE);
    3792             : 
    3793         276 :                 if (style == SOAP_RPC) {
    3794             :                   xmlNode *rpc_result;
    3795         218 :                         if (main && version == SOAP_1_2) {
    3796          23 :                                 xmlNs *rpc_ns = xmlNewNs(body, BAD_CAST(RPC_SOAP12_NAMESPACE), BAD_CAST(RPC_SOAP12_NS_PREFIX));
    3797          23 :                                 rpc_result = xmlNewChild(method, rpc_ns, BAD_CAST("result"), NULL);
    3798          23 :                                 param = serialize_parameter(parameter, ret, 0, "return", use, method);
    3799          23 :                                 xmlNodeSetContent(rpc_result,param->name);
    3800             :                         } else {
    3801         172 :                                 param = serialize_parameter(parameter, ret, 0, "return", use, method);
    3802             :                         }
    3803             :                 } else {
    3804          81 :                         param = serialize_parameter(parameter, ret, 0, "return", use, body);
    3805         162 :                         if (function && function->binding->bindingType == BINDING_SOAP) {
    3806          81 :                                 if (parameter && parameter->element) {
    3807          76 :                                         ns = encode_add_ns(param, parameter->element->namens);
    3808          76 :                                         xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    3809          76 :                                         xmlSetNs(param, ns);
    3810             :                                 }
    3811           0 :                         } else if (strcmp((char*)param->name,"return") == 0) {
    3812           0 :                                 ns = encode_add_ns(param, uri);
    3813           0 :                                 xmlNodeSetName(param, BAD_CAST(function_name));
    3814           0 :                                 xmlSetNs(param, ns);
    3815             :                         }
    3816             :                 }
    3817         119 :         } else if (param_count > 1 && Z_TYPE_P(ret) == IS_ARRAY) {
    3818             :                 zval *data;
    3819           4 :                 int i = 0;
    3820             :                 zend_string *param_name;
    3821           4 :                 zend_ulong param_index = i;
    3822             : 
    3823          28 :                 ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(ret), param_index, param_name, data) {
    3824          12 :                         parameter = get_param(function, ZSTR_VAL(param_name), param_index, TRUE);
    3825          12 :                         if (style == SOAP_RPC) {
    3826          12 :                                 param = serialize_parameter(parameter, data, i, ZSTR_VAL(param_name), use, method);
    3827             :                         } else {
    3828           0 :                                 param = serialize_parameter(parameter, data, i, ZSTR_VAL(param_name), use, body);
    3829           0 :                                 if (function && function->binding->bindingType == BINDING_SOAP) {
    3830           0 :                                         if (parameter && parameter->element) {
    3831           0 :                                                 ns = encode_add_ns(param, parameter->element->namens);
    3832           0 :                                                 xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    3833           0 :                                                 xmlSetNs(param, ns);
    3834             :                                         }
    3835             :                                 }
    3836             :                         }
    3837             : 
    3838          12 :                         i++;
    3839          12 :                         param_index = i;
    3840             :                 } ZEND_HASH_FOREACH_END();
    3841             :         }
    3842         390 :         if (use == SOAP_ENCODED && version == SOAP_1_2 && method != NULL) {
    3843          26 :                 xmlSetNsProp(method, body->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
    3844             :         }
    3845         390 :         if (node) {
    3846          14 :                 *node = method;
    3847             :         }
    3848         390 :         return use;
    3849             : }
    3850             : 
    3851         475 : static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function_name, char *uri, zval *ret, soapHeader* headers, int version)
    3852             : {
    3853             :         xmlDocPtr doc;
    3854         475 :         xmlNodePtr envelope = NULL, body, param;
    3855         475 :         xmlNsPtr ns = NULL;
    3856         475 :         int use = SOAP_LITERAL;
    3857         475 :         xmlNodePtr head = NULL;
    3858             : 
    3859         475 :         encode_reset_ns();
    3860             : 
    3861         475 :         doc = xmlNewDoc(BAD_CAST("1.0"));
    3862         475 :         doc->charset = XML_CHAR_ENCODING_UTF8;
    3863         475 :         doc->encoding = xmlCharStrdup("UTF-8");
    3864             : 
    3865         475 :         if (version == SOAP_1_1) {
    3866         399 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    3867         399 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENV_NAMESPACE), BAD_CAST(SOAP_1_1_ENV_NS_PREFIX));
    3868         399 :                 xmlSetNs(envelope,ns);
    3869          76 :         } else if (version == SOAP_1_2) {
    3870          76 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    3871          76 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENV_NAMESPACE), BAD_CAST(SOAP_1_2_ENV_NS_PREFIX));
    3872          76 :                 xmlSetNs(envelope,ns);
    3873             :         } else {
    3874           0 :                 soap_server_fault("Server", "Unknown SOAP version", NULL, NULL, NULL);
    3875             :         }
    3876         475 :         xmlDocSetRootElement(doc, envelope);
    3877             : 
    3878         729 :         if (Z_TYPE_P(ret) == IS_OBJECT &&
    3879         156 :             instanceof_function(Z_OBJCE_P(ret), soap_fault_class_entry)) {
    3880             :           char *detail_name;
    3881             :                 HashTable* prop;
    3882             :                 zval *tmp;
    3883          98 :                 sdlFaultPtr fault = NULL;
    3884          98 :                 char *fault_ns = NULL;
    3885             : 
    3886          98 :                 prop = Z_OBJPROP_P(ret);
    3887             : 
    3888          99 :                 if (headers &&
    3889           1 :                     (tmp = zend_hash_str_find(prop, "headerfault", sizeof("headerfault")-1)) != NULL) {
    3890           1 :                         encodePtr hdr_enc = NULL;
    3891           1 :                         int hdr_use = SOAP_LITERAL;
    3892           1 :                         zval *hdr_ret  = tmp;
    3893           1 :                         char *hdr_ns   = headers->hdr?headers->hdr->ns:NULL;
    3894           1 :                         char *hdr_name = Z_STRVAL(headers->function_name);
    3895             : 
    3896           1 :                         head = xmlNewChild(envelope, ns, BAD_CAST("Header"), NULL);
    3897           2 :                         if (Z_TYPE_P(hdr_ret) == IS_OBJECT &&
    3898           1 :                             instanceof_function(Z_OBJCE_P(hdr_ret), soap_header_class_entry)) {
    3899           1 :                                 HashTable* ht = Z_OBJPROP_P(hdr_ret);
    3900             :                                 sdlSoapBindingFunctionHeaderPtr hdr;
    3901           1 :                                 smart_str key = {0};
    3902             : 
    3903           2 :                                 if ((tmp = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
    3904             :                               Z_TYPE_P(tmp) == IS_STRING) {
    3905           1 :                                         smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
    3906             :                                         smart_str_appendc(&key, ':');
    3907           1 :                                         hdr_ns = Z_STRVAL_P(tmp);
    3908             :                                 }
    3909           2 :                                 if ((tmp = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
    3910             :                                     Z_TYPE_P(tmp) == IS_STRING) {
    3911           1 :                                         smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
    3912           1 :                                         hdr_name = Z_STRVAL_P(tmp);
    3913             :                                 }
    3914             :                                 smart_str_0(&key);
    3915           2 :                                 if (headers->hdr && headers->hdr->headerfaults &&
    3916           1 :                                     (hdr = zend_hash_find_ptr(headers->hdr->headerfaults, key.s)) != NULL) {
    3917           1 :                                         hdr_enc = hdr->encode;
    3918           1 :                                         hdr_use = hdr->use;
    3919             :                                 }
    3920             :                                 smart_str_free(&key);
    3921           1 :                                 if ((tmp = zend_hash_str_find(ht, "data", sizeof("data")-1)) != NULL) {
    3922           1 :                                         hdr_ret = tmp;
    3923             :                                 } else {
    3924           0 :                                         hdr_ret = NULL;
    3925             :                                 }
    3926             :                         }
    3927             : 
    3928           1 :                         if (headers->function) {
    3929           0 :                                 if (serialize_response_call2(head, headers->function, Z_STRVAL(headers->function_name), uri, hdr_ret, version, 0, NULL) == SOAP_ENCODED) {
    3930           0 :                                         use = SOAP_ENCODED;
    3931             :                                 }
    3932             :                         } else {
    3933           1 :                                 xmlNodePtr xmlHdr = master_to_xml(hdr_enc, hdr_ret, hdr_use, head);
    3934           1 :                                 if (hdr_name) {
    3935           1 :                                         xmlNodeSetName(xmlHdr, BAD_CAST(hdr_name));
    3936             :                                 }
    3937           1 :                                 if (hdr_ns) {
    3938           1 :                                         xmlNsPtr nsptr = encode_add_ns(xmlHdr, hdr_ns);
    3939           1 :                                         xmlSetNs(xmlHdr, nsptr);
    3940             :                                 }
    3941             :                         }
    3942             :                 }
    3943             : 
    3944          98 :                 body = xmlNewChild(envelope, ns, BAD_CAST("Body"), NULL);
    3945          98 :                 param = xmlNewChild(body, ns, BAD_CAST("Fault"), NULL);
    3946             : 
    3947         187 :                 if ((tmp = zend_hash_str_find(prop, "faultcodens", sizeof("faultcodens")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
    3948          89 :                         fault_ns = Z_STRVAL_P(tmp);
    3949             :                 }
    3950          98 :                 use = SOAP_LITERAL;
    3951         206 :                 if ((tmp = zend_hash_str_find(prop, "_name", sizeof("_name")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) {
    3952             :                         sdlFaultPtr tmp_fault;
    3953         108 :                         if (function && function->faults &&
    3954          54 :                             (tmp_fault = zend_hash_find_ptr(function->faults, Z_STR_P(tmp))) != NULL) {
    3955          54 :                                 fault = tmp_fault;
    3956         162 :                                 if (function->binding &&
    3957          54 :                                     function->binding->bindingType == BINDING_SOAP &&
    3958          54 :                                     fault->bindingAttributes) {
    3959          53 :                                         sdlSoapBindingFunctionFaultPtr fb = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    3960          53 :                                         use = fb->use;
    3961          53 :                                         if (fault_ns == NULL) {
    3962           0 :                                                 fault_ns = fb->ns;
    3963             :                                         }
    3964             :                                 }
    3965             :                         }
    3966          44 :                 } else if (function && function->faults &&
    3967           0 :                            zend_hash_num_elements(function->faults) == 1) {
    3968             : 
    3969           0 :                         zend_hash_internal_pointer_reset(function->faults);
    3970           0 :                         fault = zend_hash_get_current_data_ptr(function->faults);
    3971           0 :                         if (function->binding &&
    3972           0 :                             function->binding->bindingType == BINDING_SOAP &&
    3973           0 :                             fault->bindingAttributes) {
    3974           0 :                                 sdlSoapBindingFunctionFaultPtr fb = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    3975           0 :                                 use = fb->use;
    3976           0 :                                 if (fault_ns == NULL) {
    3977           0 :                                         fault_ns = fb->ns;
    3978             :                                 }
    3979             :                         }
    3980             :                 }
    3981             : 
    3982          98 :                 if (fault_ns == NULL &&
    3983             :                     fault &&
    3984           0 :                     fault->details &&
    3985           0 :                     zend_hash_num_elements(fault->details) == 1) {
    3986             :                         sdlParamPtr sparam;
    3987             : 
    3988           0 :                         zend_hash_internal_pointer_reset(fault->details);
    3989           0 :                         sparam = zend_hash_get_current_data_ptr(fault->details);
    3990           0 :                         if (sparam->element) {
    3991           0 :                                 fault_ns = sparam->element->namens;
    3992             :                         }
    3993             :                 }
    3994             : 
    3995          98 :                 if (version == SOAP_1_1) {
    3996         144 :                         if ((tmp = zend_hash_str_find(prop, "faultcode", sizeof("faultcode")-1)) != NULL &&
    3997             :                             Z_TYPE_P(tmp) == IS_STRING) {
    3998          72 :                                 xmlNodePtr node = xmlNewNode(NULL, BAD_CAST("faultcode"));
    3999          72 :                                 zend_string *str = php_escape_html_entities((unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 0, 0, NULL);
    4000          72 :                                 xmlAddChild(param, node);
    4001          72 :                                 if (fault_ns) {
    4002          66 :                                         xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
    4003          66 :                                         xmlChar *code = xmlBuildQName(BAD_CAST(ZSTR_VAL(str)), nsptr->prefix, NULL, 0);
    4004          66 :                                         xmlNodeSetContent(node, code);
    4005          66 :                                         xmlFree(code);
    4006             :                                 } else {
    4007           6 :                                         xmlNodeSetContentLen(node, BAD_CAST(ZSTR_VAL(str)), (int)ZSTR_LEN(str));
    4008             :                                 }
    4009             :                                 zend_string_release(str);
    4010             :                         }
    4011          72 :                         if ((tmp = zend_hash_str_find(prop, "faultstring", sizeof("faultstring")-1)) != NULL) {
    4012          72 :                                 xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), tmp, SOAP_LITERAL, param);
    4013          72 :                                 xmlNodeSetName(node, BAD_CAST("faultstring"));
    4014             :                         }
    4015          72 :                         if ((tmp = zend_hash_str_find(prop, "faultactor", sizeof("faultactor")-1)) != NULL) {
    4016           0 :                                 xmlNodePtr node = master_to_xml(get_conversion(IS_STRING), tmp, SOAP_LITERAL, param);
    4017           0 :                                 xmlNodeSetName(node, BAD_CAST("faultactor"));
    4018             :                         }
    4019          72 :                         detail_name = "detail";
    4020             :                 } else {
    4021          52 :                         if ((tmp = zend_hash_str_find(prop, "faultcode", sizeof("faultcode")-1)) != NULL &&
    4022             :                             Z_TYPE_P(tmp) == IS_STRING) {
    4023          26 :                                 xmlNodePtr node = xmlNewChild(param, ns, BAD_CAST("Code"), NULL);
    4024          26 :                                 zend_string *str = php_escape_html_entities((unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 0, 0, NULL);
    4025          26 :                                 node = xmlNewChild(node, ns, BAD_CAST("Value"), NULL);
    4026          26 :                                 if (fault_ns) {
    4027          23 :                                         xmlNsPtr nsptr = encode_add_ns(node, fault_ns);
    4028          23 :                                         xmlChar *code = xmlBuildQName(BAD_CAST(ZSTR_VAL(str)), nsptr->prefix, NULL, 0);
    4029          23 :                                         xmlNodeSetContent(node, code);
    4030          23 :                                         xmlFree(code);
    4031             :                                 } else {
    4032           3 :                                         xmlNodeSetContentLen(node, BAD_CAST(ZSTR_VAL(str)), (int)ZSTR_LEN(str));
    4033             :                                 }
    4034             :                                 zend_string_release(str);
    4035             :                         }
    4036          26 :                         if ((tmp = zend_hash_str_find(prop, "faultstring", sizeof("faultstring")-1)) != NULL) {
    4037          26 :                                 xmlNodePtr node = xmlNewChild(param, ns, BAD_CAST("Reason"), NULL);
    4038          26 :                                 node = master_to_xml(get_conversion(IS_STRING), tmp, SOAP_LITERAL, node);
    4039          26 :                                 xmlNodeSetName(node, BAD_CAST("Text"));
    4040          26 :                                 xmlSetNs(node, ns);
    4041             :                         }
    4042          26 :                         detail_name = SOAP_1_2_ENV_NS_PREFIX":Detail";
    4043             :                 }
    4044         152 :                 if (fault && fault->details && zend_hash_num_elements(fault->details) == 1) {
    4045             :                         xmlNodePtr node;
    4046          54 :                         zval *detail = NULL;
    4047             :                         sdlParamPtr sparam;
    4048             :                         xmlNodePtr x;
    4049             : 
    4050         102 :                         if ((tmp = zend_hash_str_find(prop, "detail", sizeof("detail")-1)) != NULL &&
    4051             :                             Z_TYPE_P(tmp) != IS_NULL) {
    4052          48 :                                 detail = tmp;
    4053             :                         }
    4054          54 :                         node = xmlNewNode(NULL, BAD_CAST(detail_name));
    4055          54 :                         xmlAddChild(param, node);
    4056             : 
    4057          54 :                         zend_hash_internal_pointer_reset(fault->details);
    4058         108 :                         sparam = zend_hash_get_current_data_ptr(fault->details);
    4059             : 
    4060         133 :                         if (detail &&
    4061             :                             Z_TYPE_P(detail) == IS_OBJECT &&
    4062          18 :                             sparam->element &&
    4063          10 :                             zend_hash_num_elements(Z_OBJPROP_P(detail)) == 1 &&
    4064           3 :                             (tmp = zend_hash_str_find(Z_OBJPROP_P(detail), sparam->element->name, strlen(sparam->element->name))) != NULL) {
    4065           0 :                                 detail = tmp;
    4066             :                         }
    4067             : 
    4068          54 :                         x = serialize_parameter(sparam, detail, 1, NULL, use, node);
    4069             : 
    4070         216 :                         if (function &&
    4071          54 :                             function->binding &&
    4072          54 :                             function->binding->bindingType == BINDING_SOAP &&
    4073          54 :                             function->bindingAttributes) {
    4074          54 :                                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    4075          81 :                                 if (fnb->style == SOAP_RPC && !sparam->element) {
    4076          27 :                                   if (fault->bindingAttributes) {
    4077          27 :                                                 sdlSoapBindingFunctionFaultPtr fb = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    4078          27 :                                                 if (fb->ns) {
    4079          27 :                                                         xmlNsPtr ns = encode_add_ns(x, fb->ns);
    4080          27 :                                                         xmlSetNs(x, ns);
    4081             :                                                 }
    4082             :                                         }
    4083             :                                 } else {
    4084          27 :                                         if (sparam->element) {
    4085          27 :                                                 ns = encode_add_ns(x, sparam->element->namens);
    4086          27 :                                                 xmlNodeSetName(x, BAD_CAST(sparam->element->name));
    4087          27 :                                                 xmlSetNs(x, ns);
    4088             :                                         }
    4089             :                                 }
    4090             :                         }
    4091          54 :                         if (use == SOAP_ENCODED && version == SOAP_1_2) {
    4092           0 :                                 xmlSetNsProp(x, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
    4093             :                         }
    4094          44 :                 } else if ((tmp = zend_hash_str_find(prop, "detail", sizeof("detail")-1)) != NULL &&
    4095             :                     Z_TYPE_P(tmp) != IS_NULL) {
    4096           0 :                         serialize_zval(tmp, NULL, detail_name, use, param);
    4097             :                 }
    4098             :         } else {
    4099             : 
    4100         377 :                 if (headers) {
    4101             :                         soapHeader *h;
    4102             : 
    4103          35 :                         head = xmlNewChild(envelope, ns, BAD_CAST("Header"), NULL);
    4104          35 :                         h = headers;
    4105         112 :                         while (h != NULL) {
    4106          84 :                                 if (Z_TYPE(h->retval) != IS_NULL) {
    4107          27 :                                         encodePtr hdr_enc = NULL;
    4108          27 :                                         int hdr_use = SOAP_LITERAL;
    4109          27 :                                         zval *hdr_ret = &h->retval;
    4110          27 :                                         char *hdr_ns   = h->hdr?h->hdr->ns:NULL;
    4111          27 :                                         char *hdr_name = Z_STRVAL(h->function_name);
    4112          27 :                                         HashTable *ht = NULL;
    4113             : 
    4114          67 :                                         if (Z_TYPE(h->retval) == IS_OBJECT &&
    4115          13 :                                             instanceof_function(Z_OBJCE(h->retval), soap_header_class_entry)) {
    4116             :                                                 zval *tmp;
    4117             :                                                 sdlSoapBindingFunctionHeaderPtr hdr;
    4118          13 :                                                 smart_str key = {0};
    4119             : 
    4120          13 :                                                 ht = Z_OBJPROP(h->retval);
    4121          26 :                                                 if ((tmp = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
    4122             :                                               Z_TYPE_P(tmp) == IS_STRING) {
    4123          13 :                                                         smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
    4124             :                                                         smart_str_appendc(&key, ':');
    4125          13 :                                                         hdr_ns = Z_STRVAL_P(tmp);
    4126             :                                                 }
    4127          26 :                                                 if ((tmp = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
    4128             :                                                     Z_TYPE_P(tmp) == IS_STRING) {
    4129          13 :                                                         smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
    4130          13 :                                                         hdr_name = Z_STRVAL_P(tmp);
    4131             :                                                 }
    4132             :                                                 smart_str_0(&key);
    4133          13 :                                                 if (function && function->binding && function->binding->bindingType == BINDING_SOAP) {
    4134           8 :                                                         sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    4135             : 
    4136          16 :                                                         if (fnb->output.headers &&
    4137           8 :                                                             (hdr = zend_hash_find_ptr(fnb->output.headers, key.s)) != NULL) {
    4138           8 :                                                                 hdr_enc = hdr->encode;
    4139           8 :                                                                 hdr_use = hdr->use;
    4140             :                                                         }
    4141             :                                                 }
    4142             :                                                 smart_str_free(&key);
    4143          13 :                                                 if ((tmp = zend_hash_str_find(ht, "data", sizeof("data")-1)) != NULL) {
    4144          13 :                                                         hdr_ret = tmp;
    4145             :                                                 } else {
    4146           0 :                                                         hdr_ret = NULL;
    4147             :                                                 }
    4148             :                                         }
    4149             : 
    4150          27 :                                         if (h->function) {
    4151          14 :                                                 xmlNodePtr xmlHdr = NULL;
    4152             : 
    4153          14 :                                                 if (serialize_response_call2(head, h->function, Z_STRVAL(h->function_name), uri, hdr_ret, version, 0, &xmlHdr) == SOAP_ENCODED) {
    4154           0 :                                                         use = SOAP_ENCODED;
    4155             :                                                 }
    4156          14 :                                                 if (ht) {
    4157           0 :                                                         set_soap_header_attributes(xmlHdr, ht, version);
    4158             :                                                 }
    4159             :                                         } else {
    4160          13 :                                                 xmlNodePtr xmlHdr = master_to_xml(hdr_enc, hdr_ret, hdr_use, head);
    4161          13 :                                                 if (hdr_name) {
    4162          13 :                                                         xmlNodeSetName(xmlHdr, BAD_CAST(hdr_name));
    4163             :                                                 }
    4164          13 :                                                 if (hdr_ns) {
    4165          13 :                                                         xmlNsPtr nsptr = encode_add_ns(xmlHdr,hdr_ns);
    4166          13 :                                                         xmlSetNs(xmlHdr, nsptr);
    4167             :                                                 }
    4168          13 :                                                 if (ht) {
    4169          13 :                                                         set_soap_header_attributes(xmlHdr, ht, version);
    4170             :                                                 }
    4171             :                                         }
    4172             :                                 }
    4173          42 :                                 h = h->next;
    4174             :                         }
    4175             : 
    4176          35 :                         if (head->children == NULL) {
    4177          12 :                                 xmlUnlinkNode(head);
    4178          12 :                                 xmlFreeNode(head);
    4179             :                         }
    4180             :                 }
    4181             : 
    4182         377 :                 body = xmlNewChild(envelope, ns, BAD_CAST("Body"), NULL);
    4183             : 
    4184         377 :                 if (serialize_response_call2(body, function, function_name, uri, ret, version, 1, NULL) == SOAP_ENCODED) {
    4185         205 :                         use = SOAP_ENCODED;
    4186             :                 }
    4187             : 
    4188             :         }
    4189             : 
    4190         474 :         if (use == SOAP_ENCODED) {
    4191         232 :                 xmlNewNs(envelope, BAD_CAST(XSD_NAMESPACE), BAD_CAST(XSD_NS_PREFIX));
    4192         232 :                 if (version == SOAP_1_1) {
    4193         206 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENC_NAMESPACE), BAD_CAST(SOAP_1_1_ENC_NS_PREFIX));
    4194         206 :                         xmlSetNsProp(envelope, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_1_ENC_NAMESPACE));
    4195          26 :                 } else if (version == SOAP_1_2) {
    4196          26 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENC_NAMESPACE), BAD_CAST(SOAP_1_2_ENC_NS_PREFIX));
    4197             :                 }
    4198             :         }
    4199             : 
    4200         474 :         encode_finish();
    4201             : 
    4202         556 :         if (function && function->responseName == NULL &&
    4203          82 :             body->children == NULL && head == NULL) {
    4204          82 :                 xmlFreeDoc(doc);
    4205          82 :                 return NULL;
    4206             :         }
    4207         392 :         return doc;
    4208             : }
    4209             : 
    4210         404 : static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function, char *function_name, char *uri, zval *arguments, int arg_count, int version, HashTable *soap_headers)
    4211             : {
    4212             :         xmlDoc *doc;
    4213         404 :         xmlNodePtr envelope = NULL, body, method = NULL, head = NULL;
    4214         404 :         xmlNsPtr ns = NULL;
    4215             :         zval *zstyle, *zuse;
    4216             :         int i, style, use;
    4217         404 :         HashTable *hdrs = NULL;
    4218             : 
    4219         404 :         encode_reset_ns();
    4220             : 
    4221         404 :         doc = xmlNewDoc(BAD_CAST("1.0"));
    4222         404 :         doc->encoding = xmlCharStrdup("UTF-8");
    4223         404 :         doc->charset = XML_CHAR_ENCODING_UTF8;
    4224         404 :         if (version == SOAP_1_1) {
    4225         402 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    4226         402 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENV_NAMESPACE), BAD_CAST(SOAP_1_1_ENV_NS_PREFIX));
    4227         402 :                 xmlSetNs(envelope, ns);
    4228           2 :         } else if (version == SOAP_1_2) {
    4229           2 :                 envelope = xmlNewDocNode(doc, NULL, BAD_CAST("Envelope"), NULL);
    4230           2 :                 ns = xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENV_NAMESPACE), BAD_CAST(SOAP_1_2_ENV_NS_PREFIX));
    4231           2 :                 xmlSetNs(envelope, ns);
    4232             :         } else {
    4233           0 :                 soap_error0(E_ERROR, "Unknown SOAP version");
    4234             :         }
    4235         404 :         xmlDocSetRootElement(doc, envelope);
    4236             : 
    4237         404 :         if (soap_headers) {
    4238          17 :                 head = xmlNewChild(envelope, ns, BAD_CAST("Header"), NULL);
    4239             :         }
    4240             : 
    4241         404 :         body = xmlNewChild(envelope, ns, BAD_CAST("Body"), NULL);
    4242             : 
    4243         705 :         if (function && function->binding->bindingType == BINDING_SOAP) {
    4244         301 :                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)function->bindingAttributes;
    4245             : 
    4246         301 :                 hdrs = fnb->input.headers;
    4247         301 :                 style = fnb->style;
    4248             :                 /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
    4249             :                 /*style = SOAP_RPC;*/
    4250         301 :                 use = fnb->input.use;
    4251         301 :                 if (style == SOAP_RPC) {
    4252         198 :                         ns = encode_add_ns(body, fnb->input.ns);
    4253         198 :                         if (function->requestName) {
    4254         198 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->requestName), NULL);
    4255             :                         } else {
    4256           0 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->functionName), NULL);
    4257             :                         }
    4258             :                 }
    4259             :         } else {
    4260         111 :                 if ((zstyle = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "style", sizeof("style")-1)) != NULL &&
    4261             :                     Z_TYPE_P(zstyle) == IS_LONG) {
    4262           4 :                         style = Z_LVAL_P(zstyle);
    4263             :                 } else {
    4264          99 :                         style = SOAP_RPC;
    4265             :                 }
    4266             :                 /*FIXME: how to pass method name if style is SOAP_DOCUMENT */
    4267             :                 /*style = SOAP_RPC;*/
    4268         103 :                 if (style == SOAP_RPC) {
    4269         103 :                         ns = encode_add_ns(body, uri);
    4270         103 :                         if (function_name) {
    4271         102 :                                 method = xmlNewChild(body, ns, BAD_CAST(function_name), NULL);
    4272           2 :                         } else if (function && function->requestName) {
    4273           1 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->requestName), NULL);
    4274           0 :                         } else if (function && function->functionName) {
    4275           0 :                                 method = xmlNewChild(body, ns, BAD_CAST(function->functionName), NULL);
    4276             :                         } else {
    4277           0 :                                 method = body;
    4278             :                         }
    4279             :                 } else {
    4280           0 :                         method = body;
    4281             :                 }
    4282             : 
    4283         111 :                 if ((zuse = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use")-1)) != NULL &&
    4284           4 :                      Z_TYPE_P(zuse) == IS_LONG && Z_LVAL_P(zuse) == SOAP_LITERAL) {
    4285           0 :                         use = SOAP_LITERAL;
    4286             :                 } else {
    4287         103 :                         use = SOAP_ENCODED;
    4288             :                 }
    4289             :         }
    4290             : 
    4291         850 :         for (i = 0;i < arg_count;i++) {
    4292             :                 xmlNodePtr param;
    4293         448 :                 sdlParamPtr parameter = get_param(function, NULL, i, FALSE);
    4294             : 
    4295         448 :                 if (style == SOAP_RPC) {
    4296         357 :                         param = serialize_parameter(parameter, &arguments[i], i, NULL, use, method);
    4297          91 :                 } else if (style == SOAP_DOCUMENT) {
    4298          91 :                         param = serialize_parameter(parameter, &arguments[i], i, NULL, use, body);
    4299          90 :                         if (function && function->binding->bindingType == BINDING_SOAP) {
    4300          90 :                                 if (parameter && parameter->element) {
    4301          83 :                                         ns = encode_add_ns(param, parameter->element->namens);
    4302          83 :                                         xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    4303          83 :                                         xmlSetNs(param, ns);
    4304             :                                 }
    4305             :                         }
    4306             :                 }
    4307             :         }
    4308             : 
    4309         402 :         if (function && function->requestParameters) {
    4310         299 :                 int n = zend_hash_num_elements(function->requestParameters);
    4311             : 
    4312         299 :                 if (n > arg_count) {
    4313          20 :                         for (i = arg_count; i < n; i++) {
    4314             :                                 xmlNodePtr param;
    4315          10 :                                 sdlParamPtr parameter = get_param(function, NULL, i, FALSE);
    4316             : 
    4317          10 :                                 if (style == SOAP_RPC) {
    4318           1 :                                         param = serialize_parameter(parameter, NULL, i, NULL, use, method);
    4319           9 :                                 } else if (style == SOAP_DOCUMENT) {
    4320           9 :                                         param = serialize_parameter(parameter, NULL, i, NULL, use, body);
    4321           9 :                                         if (function && function->binding->bindingType == BINDING_SOAP) {
    4322           9 :                                                 if (parameter && parameter->element) {
    4323           9 :                                                         ns = encode_add_ns(param, parameter->element->namens);
    4324           9 :                                                         xmlNodeSetName(param, BAD_CAST(parameter->element->name));
    4325           9 :                                                         xmlSetNs(param, ns);
    4326             :                                                 }
    4327             :                                         }
    4328             :                                 }
    4329             :                         }
    4330             :                 }
    4331             :         }
    4332             : 
    4333         402 :         if (head) {
    4334             :                 zval* header;
    4335             : 
    4336          59 :                 ZEND_HASH_FOREACH_VAL(soap_headers, header) {
    4337             :                         HashTable *ht;
    4338             :                         zval *name, *ns, *tmp;
    4339             : 
    4340          21 :                         if (Z_TYPE_P(header) != IS_OBJECT) {
    4341           1 :                                 continue;
    4342             :                         }
    4343             : 
    4344          20 :                         ht = Z_OBJPROP_P(header);
    4345          77 :                         if ((name = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
    4346             :                             Z_TYPE_P(name) == IS_STRING &&
    4347          19 :                             (ns = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
    4348             :                             Z_TYPE_P(ns) == IS_STRING) {
    4349             :                                 xmlNodePtr h;
    4350             :                                 xmlNsPtr nsptr;
    4351          19 :                                 int hdr_use = SOAP_LITERAL;
    4352          19 :                                 encodePtr enc = NULL;
    4353             : 
    4354          19 :                                 if (hdrs) {
    4355          11 :                                         smart_str key = {0};
    4356             :                                         sdlSoapBindingFunctionHeaderPtr hdr;
    4357             : 
    4358          11 :                                         smart_str_appendl(&key, Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    4359             :                                         smart_str_appendc(&key, ':');
    4360          11 :                                         smart_str_appendl(&key, Z_STRVAL_P(name), Z_STRLEN_P(name));
    4361             :                                         smart_str_0(&key);
    4362          22 :                                         if ((hdr = zend_hash_find_ptr(hdrs, key.s)) != NULL) {
    4363          10 :                                                 hdr_use = hdr->use;
    4364          10 :                                                 enc = hdr->encode;
    4365          10 :                                                 if (hdr_use == SOAP_ENCODED) {
    4366           0 :                                                         use = SOAP_ENCODED;
    4367             :                                                 }
    4368             :                                         }
    4369             :                                         smart_str_free(&key);
    4370             :                                 }
    4371             : 
    4372          19 :                                 if ((tmp = zend_hash_str_find(ht, "data", sizeof("data")-1)) != NULL) {
    4373          12 :                                         h = master_to_xml(enc, tmp, hdr_use, head);
    4374          12 :                                         xmlNodeSetName(h, BAD_CAST(Z_STRVAL_P(name)));
    4375             :                                 } else {
    4376           7 :                                         h = xmlNewNode(NULL, BAD_CAST(Z_STRVAL_P(name)));
    4377           7 :                                         xmlAddChild(head, h);
    4378             :                                 }
    4379          19 :                                 nsptr = encode_add_ns(h, Z_STRVAL_P(ns));
    4380          19 :                                 xmlSetNs(h, nsptr);
    4381          19 :                                 set_soap_header_attributes(h, ht, version);
    4382             :                         }
    4383             :                 } ZEND_HASH_FOREACH_END();
    4384             :         }
    4385             : 
    4386         402 :         if (use == SOAP_ENCODED) {
    4387         291 :                 xmlNewNs(envelope, BAD_CAST(XSD_NAMESPACE), BAD_CAST(XSD_NS_PREFIX));
    4388         291 :                 if (version == SOAP_1_1) {
    4389         289 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_1_ENC_NAMESPACE), BAD_CAST(SOAP_1_1_ENC_NS_PREFIX));
    4390         289 :                         xmlSetNsProp(envelope, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_1_ENC_NAMESPACE));
    4391           2 :                 } else if (version == SOAP_1_2) {
    4392           2 :                         xmlNewNs(envelope, BAD_CAST(SOAP_1_2_ENC_NAMESPACE), BAD_CAST(SOAP_1_2_ENC_NS_PREFIX));
    4393           2 :                         if (method) {
    4394           2 :                                 xmlSetNsProp(method, envelope->ns, BAD_CAST("encodingStyle"), BAD_CAST(SOAP_1_2_ENC_NAMESPACE));
    4395             :                         }
    4396             :                 }
    4397             :         }
    4398             : 
    4399         402 :         encode_finish();
    4400             : 
    4401         402 :         return doc;
    4402             : }
    4403             : 
    4404         800 : static xmlNodePtr serialize_parameter(sdlParamPtr param, zval *param_val, int index, char *name, int style, xmlNodePtr parent)
    4405             : {
    4406             :         char *paramName;
    4407             :         xmlNodePtr xmlParam;
    4408             :         char paramNameBuf[10];
    4409             : 
    4410        1808 :         if (param_val &&
    4411             :             Z_TYPE_P(param_val) == IS_OBJECT &&
    4412         224 :             Z_OBJCE_P(param_val) == soap_param_class_entry) {
    4413             :                 zval *param_name;
    4414             :                 zval *param_data;
    4415             : 
    4416          90 :                 if ((param_name = zend_hash_str_find(Z_OBJPROP_P(param_val), "param_name", sizeof("param_name")-1)) != NULL &&
    4417             :                     Z_TYPE_P(param_name) == IS_STRING &&
    4418          30 :                     (param_data = zend_hash_str_find(Z_OBJPROP_P(param_val), "param_data", sizeof("param_data")-1)) != NULL) {
    4419          30 :                         param_val = param_data;
    4420          30 :                         name = Z_STRVAL_P(param_name);
    4421             :                 }
    4422             :         }
    4423             : 
    4424        1455 :         if (param != NULL && param->paramName != NULL) {
    4425         655 :                 paramName = param->paramName;
    4426             :         } else {
    4427         145 :                 if (name == NULL) {
    4428          66 :                         paramName = paramNameBuf;
    4429          66 :                         snprintf(paramName, sizeof(paramNameBuf), "param%d",index);
    4430             :                 } else {
    4431          79 :                         paramName = name;
    4432             :                 }
    4433             :         }
    4434             : 
    4435         800 :         xmlParam = serialize_zval(param_val, param, paramName, style, parent);
    4436             : 
    4437         797 :         return xmlParam;
    4438             : }
    4439             : 
    4440         800 : static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, int style, xmlNodePtr parent)
    4441             : {
    4442             :         xmlNodePtr xmlParam;
    4443             :         encodePtr enc;
    4444             :         zval defval;
    4445             : 
    4446         800 :         ZVAL_UNDEF(&defval);
    4447         800 :         if (param != NULL) {
    4448         655 :                 enc = param->encode;
    4449         655 :                 if (val == NULL) {
    4450          16 :                         if (param->element) {
    4451          13 :                                 if (param->element->fixed) {
    4452           0 :                                         ZVAL_STRING(&defval, param->element->fixed);
    4453           0 :                                         val = &defval;
    4454          13 :                                 } else if (param->element->def && !param->element->nillable) {
    4455           2 :                                         ZVAL_STRING(&defval, param->element->def);
    4456           1 :                                         val = &defval;
    4457             :                                 }
    4458             :                         }
    4459             :                 }
    4460             :         } else {
    4461         145 :                 enc = NULL;
    4462             :         }
    4463         800 :         xmlParam = master_to_xml(enc, val, style, parent);
    4464         797 :         zval_ptr_dtor(&defval);
    4465         797 :         if (!strcmp((char*)xmlParam->name, "BOGUS")) {
    4466         790 :                 xmlNodeSetName(xmlParam, BAD_CAST(paramName));
    4467             :         }
    4468         797 :         return xmlParam;
    4469             : }
    4470             : 
    4471         746 : static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, int response)
    4472             : {
    4473             :         sdlParamPtr tmp;
    4474             :         HashTable   *ht;
    4475             : 
    4476         746 :         if (function == NULL) {
    4477         145 :                 return NULL;
    4478             :         }
    4479             : 
    4480         601 :         if (response == FALSE) {
    4481         362 :                 ht = function->requestParameters;
    4482             :         } else {
    4483         239 :                 ht = function->responseParameters;
    4484             :         }
    4485             : 
    4486         601 :         if (ht == NULL) {
    4487           0 :           return NULL;
    4488             :         }
    4489             : 
    4490         601 :         if (param_name != NULL) {
    4491          24 :                 if ((tmp = zend_hash_str_find_ptr(ht, param_name, strlen(param_name))) != NULL) {
    4492           0 :                         return tmp;
    4493             :                 } else {
    4494          48 :                         ZEND_HASH_FOREACH_PTR(ht, tmp) {
    4495          24 :                                 if (tmp->paramName && strcmp(param_name, tmp->paramName) == 0) {
    4496          12 :                                         return tmp;
    4497             :                                 }
    4498             :                         } ZEND_HASH_FOREACH_END();
    4499             :                 }
    4500             :         } else {
    4501        1178 :                 if ((tmp = zend_hash_index_find_ptr(ht, index)) != NULL) {
    4502         589 :                         return tmp;
    4503             :                 }
    4504             :         }
    4505           0 :         return NULL;
    4506             : }
    4507             : 
    4508         781 : static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name)
    4509             : {
    4510             :         sdlFunctionPtr tmp;
    4511             : 
    4512         781 :         int len = strlen(function_name);
    4513         781 :         char *str = estrndup(function_name,len);
    4514         781 :         php_strtolower(str,len);
    4515         781 :         if (sdl != NULL) {
    4516        1436 :                 if ((tmp = zend_hash_str_find_ptr(&sdl->functions, str, len)) != NULL) {
    4517         641 :                         efree(str);
    4518         641 :                         return tmp;
    4519          77 :                 } else if (sdl->requests != NULL && (tmp = zend_hash_str_find_ptr(sdl->requests, str, len)) != NULL) {
    4520           0 :                         efree(str);
    4521           0 :                         return tmp;
    4522             :                 }
    4523             :         }
    4524         140 :         efree(str);
    4525         140 :         return NULL;
    4526             : }
    4527             : 
    4528         170 : static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr params)
    4529             : {
    4530         170 :         if (sdl) {
    4531             :                 sdlFunctionPtr tmp;
    4532             :                 sdlParamPtr    param;
    4533             : 
    4534        2841 :                 ZEND_HASH_FOREACH_PTR(&sdl->functions, tmp) {
    4535        1406 :                         if (tmp->binding && tmp->binding->bindingType == BINDING_SOAP) {
    4536        1406 :                                 sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)tmp->bindingAttributes;
    4537        1406 :                                 if (fnb->style == SOAP_DOCUMENT) {
    4538        1097 :                                         if (params == NULL) {
    4539          66 :                                                 if (tmp->requestParameters == NULL ||
    4540          33 :                                                     zend_hash_num_elements(tmp->requestParameters) == 0) {
    4541          30 :                                                   return tmp;
    4542             :                                                 }
    4543        2128 :                                         } else if (tmp->requestParameters != NULL &&
    4544        1064 :                                                    zend_hash_num_elements(tmp->requestParameters) > 0) {
    4545        1028 :                                                 int ok = 1;
    4546        1028 :                                                 xmlNodePtr node = params;
    4547             : 
    4548        2169 :                                                 ZEND_HASH_FOREACH_PTR(tmp->requestParameters, param) {
    4549        1029 :                                                         if (param->element) {
    4550        1024 :                                                                 if (strcmp(param->element->name, (char*)node->name) != 0) {
    4551         917 :                                                                         ok = 0;
    4552         917 :                                                                         break;
    4553             :                                                                 }
    4554         214 :                                                                 if (param->element->namens != NULL && node->ns != NULL) {
    4555         107 :                                                                         if (strcmp(param->element->namens, (char*)node->ns->href) != 0) {
    4556           0 :                                                                                 ok = 0;
    4557           0 :                                                                                 break;
    4558             :                                                                         }
    4559           0 :                                                                 } else if ((void*)param->element->namens != (void*)node->ns) {
    4560           0 :                                                                         ok = 0;
    4561           0 :                                                                         break;
    4562             :                                                                 }
    4563           5 :                                                         } else if (strcmp(param->paramName, (char*)node->name) != 0) {
    4564           0 :                                                                 ok = 0;
    4565           0 :                                                                 break;
    4566             :                                                         }
    4567         112 :                                                         node = node->next;
    4568             :                                                 } ZEND_HASH_FOREACH_END();
    4569        1028 :                                                 if (ok /*&& node == NULL*/) {
    4570         111 :                                                         return tmp;
    4571             :                                                 }
    4572             :                                         }
    4573             :                                 }
    4574             :                         }
    4575             :                 } ZEND_HASH_FOREACH_END();
    4576             :         }
    4577          29 :         return NULL;
    4578             : }
    4579             : 
    4580           7 : static void function_to_string(sdlFunctionPtr function, smart_str *buf)
    4581             : {
    4582           7 :         int i = 0;
    4583             :         sdlParamPtr param;
    4584             : 
    4585          21 :         if (function->responseParameters &&
    4586           7 :             zend_hash_num_elements(function->responseParameters) > 0) {
    4587           7 :                 if (zend_hash_num_elements(function->responseParameters) == 1) {
    4588           7 :                         zend_hash_internal_pointer_reset(function->responseParameters);
    4589          14 :                         param = zend_hash_get_current_data_ptr(function->responseParameters);
    4590          14 :                         if (param->encode && param->encode->details.type_str) {
    4591           7 :                                 smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str));
    4592             :                                 smart_str_appendc(buf, ' ');
    4593             :                         } else {
    4594             :                                 smart_str_appendl(buf, "UNKNOWN ", 8);
    4595             :                         }
    4596             :                 } else {
    4597           0 :                         i = 0;
    4598             :                         smart_str_appendl(buf, "list(", 5);
    4599           0 :                         ZEND_HASH_FOREACH_PTR(function->responseParameters, param) {
    4600           0 :                                 if (i > 0) {
    4601             :                                         smart_str_appendl(buf, ", ", 2);
    4602             :                                 }
    4603           0 :                                 if (param->encode && param->encode->details.type_str) {
    4604           0 :                                         smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str));
    4605             :                                 } else {
    4606             :                                         smart_str_appendl(buf, "UNKNOWN", 7);
    4607             :                                 }
    4608             :                                 smart_str_appendl(buf, " $", 2);
    4609           0 :                                 smart_str_appendl(buf, param->paramName, strlen(param->paramName));
    4610           0 :                                 i++;
    4611             :                         } ZEND_HASH_FOREACH_END();
    4612             :                         smart_str_appendl(buf, ") ", 2);
    4613             :                 }
    4614             :         } else {
    4615             :                 smart_str_appendl(buf, "void ", 5);
    4616             :         }
    4617             : 
    4618           7 :         smart_str_appendl(buf, function->functionName, strlen(function->functionName));
    4619             : 
    4620             :         smart_str_appendc(buf, '(');
    4621           7 :         if (function->requestParameters) {
    4622           7 :                 i = 0;
    4623          21 :                 ZEND_HASH_FOREACH_PTR(function->requestParameters, param) {
    4624           7 :                         if (i > 0) {
    4625             :                                 smart_str_appendl(buf, ", ", 2);
    4626             :                         }
    4627          14 :                         if (param->encode && param->encode->details.type_str) {
    4628           7 :                                 smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str));
    4629             :                         } else {
    4630             :                                 smart_str_appendl(buf, "UNKNOWN", 7);
    4631             :                         }
    4632             :                         smart_str_appendl(buf, " $", 2);
    4633           7 :                         smart_str_appendl(buf, param->paramName, strlen(param->paramName));
    4634           7 :                         i++;
    4635             :                 } ZEND_HASH_FOREACH_END();
    4636             :         }
    4637             :         smart_str_appendc(buf, ')');
    4638             :         smart_str_0(buf);
    4639           7 : }
    4640             : 
    4641         118 : static void model_to_string(sdlContentModelPtr model, smart_str *buf, int level)
    4642             : {
    4643             :         int i;
    4644             : 
    4645         118 :         switch (model->kind) {
    4646             :                 case XSD_CONTENT_ELEMENT:
    4647          76 :                         type_to_string(model->u.element, buf, level);
    4648             :                         smart_str_appendl(buf, ";\n", 2);
    4649          76 :                         break;
    4650             :                 case XSD_CONTENT_ANY:
    4651           2 :                         for (i = 0;i < level;i++) {
    4652             :                                 smart_str_appendc(buf, ' ');
    4653             :                         }
    4654             :                         smart_str_appendl(buf, "<anyXML> any;\n", sizeof("<anyXML> any;\n")-1);
    4655           1 :                         break;
    4656             :                 case XSD_CONTENT_SEQUENCE:
    4657             :                 case XSD_CONTENT_ALL:
    4658             :                 case XSD_CONTENT_CHOICE: {
    4659             :                         sdlContentModelPtr tmp;
    4660             : 
    4661         195 :                         ZEND_HASH_FOREACH_PTR(model->u.content, tmp) {
    4662          77 :                                 model_to_string(tmp, buf, level);
    4663             :                         } ZEND_HASH_FOREACH_END();
    4664          41 :                         break;
    4665             :                 }
    4666             :                 case XSD_CONTENT_GROUP:
    4667           0 :                         model_to_string(model->u.group->model, buf, level);
    4668             :                 default:
    4669             :                   break;
    4670             :         }
    4671         118 : }
    4672             : 
    4673         128 : static void type_to_string(sdlTypePtr type, smart_str *buf, int level)
    4674             : {
    4675             :         int i;
    4676         128 :         smart_str spaces = {0};
    4677             : 
    4678         204 :         for (i = 0;i < level;i++) {
    4679             :                 smart_str_appendc(&spaces, ' ');
    4680             :         }
    4681         128 :         if (spaces.s) {
    4682          76 :                 smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s));
    4683             :         }
    4684         128 :         switch (type->kind) {
    4685             :                 case XSD_TYPEKIND_SIMPLE:
    4686          78 :                         if (type->encode) {
    4687          76 :                                 smart_str_appendl(buf, type->encode->details.type_str, strlen(type->encode->details.type_str));
    4688             :                                 smart_str_appendc(buf, ' ');
    4689             :                         } else {
    4690             :                                 smart_str_appendl(buf, "anyType ", sizeof("anyType ")-1);
    4691             :                         }
    4692          78 :                         smart_str_appendl(buf, type->name, strlen(type->name));
    4693          78 :                         break;
    4694             :                 case XSD_TYPEKIND_LIST:
    4695             :                         smart_str_appendl(buf, "list ", 5);
    4696           2 :                         smart_str_appendl(buf, type->name, strlen(type->name));
    4697           2 :                         if (type->elements) {
    4698             :                                 sdlTypePtr item_type;
    4699             : 
    4700             :                                 smart_str_appendl(buf, " {", 2);
    4701           6 :                                 ZEND_HASH_FOREACH_PTR(type->elements, item_type) {
    4702           2 :                                         smart_str_appendl(buf, item_type->name, strlen(item_type->name));
    4703             :                                 } ZEND_HASH_FOREACH_END();
    4704             :                                 smart_str_appendc(buf, '}');
    4705             :                         }
    4706           2 :                         break;
    4707             :                 case XSD_TYPEKIND_UNION:
    4708             :                         smart_str_appendl(buf, "union ", 6);
    4709           0 :                         smart_str_appendl(buf, type->name, strlen(type->name));
    4710           0 :                         if (type->elements) {
    4711             :                                 sdlTypePtr item_type;
    4712           0 :                                 int first = 0;
    4713             : 
    4714             :                                 smart_str_appendl(buf, " {", 2);
    4715           0 :                                 ZEND_HASH_FOREACH_PTR(type->elements, item_type) {
    4716           0 :                                         if (!first) {
    4717             :                                                 smart_str_appendc(buf, ',');
    4718           0 :                                                 first = 0;
    4719             :                                         }
    4720           0 :                                         smart_str_appendl(buf, item_type->name, strlen(item_type->name));
    4721             :                                 } ZEND_HASH_FOREACH_END();
    4722             :                                 smart_str_appendc(buf, '}');
    4723             :                         }
    4724           0 :                         break;
    4725             :                 case XSD_TYPEKIND_COMPLEX:
    4726             :                 case XSD_TYPEKIND_RESTRICTION:
    4727             :                 case XSD_TYPEKIND_EXTENSION:
    4728          52 :                         if (type->encode &&
    4729           2 :                             (type->encode->details.type == IS_ARRAY ||
    4730           1 :                              type->encode->details.type == SOAP_ENC_ARRAY)) {
    4731             :                           sdlAttributePtr attr;
    4732             :                           sdlExtraAttributePtr ext;
    4733             : 
    4734           3 :                                 if (type->attributes &&
    4735           1 :                                     (attr = zend_hash_str_find_ptr(type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
    4736             :                                       sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType")-1)) != NULL &&
    4737           1 :                                         attr->extraAttributes &&
    4738           0 :                                     (ext = zend_hash_str_find_ptr(attr->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType")-1)) != NULL) {
    4739           0 :                                         char *end = strchr(ext->val, '[');
    4740             :                                         int len;
    4741           0 :                                         if (end == NULL) {
    4742           0 :                                                 len = strlen(ext->val);
    4743             :                                         } else {
    4744           0 :                                                 len = end - ext->val;
    4745             :                                         }
    4746           0 :                                         if (len == 0) {
    4747             :                                                 smart_str_appendl(buf, "anyType", sizeof("anyType")-1);
    4748             :                                         } else {
    4749           0 :                                                 smart_str_appendl(buf, ext->val, len);
    4750             :                                         }
    4751             :                                         smart_str_appendc(buf, ' ');
    4752           0 :                                         smart_str_appendl(buf, type->name, strlen(type->name));
    4753           0 :                                         if (end != NULL) {
    4754           0 :                                                 smart_str_appends(buf, end);
    4755             :                                         }
    4756             :                                 } else {
    4757             :                                         sdlTypePtr elementType;
    4758           2 :                                         if (type->attributes &&
    4759           1 :                                             (attr = zend_hash_str_find_ptr(type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
    4760             :                                               sizeof(SOAP_1_2_ENC_NAMESPACE":itemType")-1)) != NULL &&
    4761           0 :                                                 attr->extraAttributes &&
    4762           0 :                                     (ext = zend_hash_str_find_ptr(attr->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arrayType")-1)) != NULL) {
    4763           0 :                                                 smart_str_appends(buf, ext->val);
    4764             :                                                 smart_str_appendc(buf, ' ');
    4765           1 :                                         } else if (type->elements &&
    4766           0 :                                                    zend_hash_num_elements(type->elements) == 1 &&
    4767           0 :                                                    (zend_hash_internal_pointer_reset(type->elements),
    4768           0 :                                                     (elementType = zend_hash_get_current_data_ptr(type->elements)) != NULL) &&
    4769           0 :                                                    elementType->encode && elementType->encode->details.type_str) {
    4770           0 :                                                 smart_str_appends(buf, elementType->encode->details.type_str);
    4771             :                                                 smart_str_appendc(buf, ' ');
    4772             :                                         } else {
    4773             :                                                 smart_str_appendl(buf, "anyType ", 8);
    4774             :                                         }
    4775           1 :                                         smart_str_appendl(buf, type->name, strlen(type->name));
    4776           2 :                                         if (type->attributes &&
    4777           1 :                                             (attr = zend_hash_str_find_ptr(type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
    4778             :                                               sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize")-1)) != NULL &&
    4779           0 :                                                 attr->extraAttributes &&
    4780           0 :                                             (ext = zend_hash_str_find_ptr(attr->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":arraySize")-1)) != NULL) {
    4781             :                                                 smart_str_appendc(buf, '[');
    4782           0 :                                                 smart_str_appends(buf, ext->val);
    4783             :                                                 smart_str_appendc(buf, ']');
    4784             :                                         } else {
    4785             :                                                 smart_str_appendl(buf, "[]", 2);
    4786             :                                         }
    4787             :                                 }
    4788             :                         } else {
    4789             :                                 smart_str_appendl(buf, "struct ", 7);
    4790          47 :                                 smart_str_appendl(buf, type->name, strlen(type->name));
    4791             :                                 smart_str_appendc(buf, ' ');
    4792             :                                 smart_str_appendl(buf, "{\n", 2);
    4793          95 :                                 if ((type->kind == XSD_TYPEKIND_RESTRICTION ||
    4794          48 :                                      type->kind == XSD_TYPEKIND_EXTENSION) && type->encode) {
    4795           1 :                                         encodePtr enc = type->encode;
    4796           7 :                                         while (enc && enc->details.sdl_type &&
    4797           1 :                                                enc != enc->details.sdl_type->encode &&
    4798           1 :                                                enc->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
    4799           1 :                                                enc->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
    4800           1 :                                                enc->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
    4801           1 :                                                 enc = enc->details.sdl_type->encode;
    4802             :                                         }
    4803           1 :                                         if (enc) {
    4804           0 :                                                 if (spaces.s) {
    4805           0 :                                                         smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s));
    4806             :                                                 }
    4807             :                                                 smart_str_appendc(buf, ' ');
    4808           0 :                                                 smart_str_appendl(buf, type->encode->details.type_str, strlen(type->encode->details.type_str));
    4809             :                                                 smart_str_appendl(buf, " _;\n", 4);
    4810             :                                         }
    4811             :                                 }
    4812          47 :                                 if (type->model) {
    4813          41 :                                         model_to_string(type->model, buf, level+1);
    4814             :                                 }
    4815          47 :                                 if (type->attributes) {
    4816             :                                         sdlAttributePtr attr;
    4817             : 
    4818           0 :                                         ZEND_HASH_FOREACH_PTR(type->attributes, attr) {
    4819           0 :                                                 if (spaces.s) {
    4820           0 :                                                         smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s));
    4821             :                                                 }
    4822             :                                                 smart_str_appendc(buf, ' ');
    4823           0 :                                                 if (attr->encode && attr->encode->details.type_str) {
    4824           0 :                                                         smart_str_appends(buf, attr->encode->details.type_str);
    4825             :                                                         smart_str_appendc(buf, ' ');
    4826             :                                                 } else {
    4827             :                                                         smart_str_appendl(buf, "UNKNOWN ", 8);
    4828             :                                                 }
    4829           0 :                                                 smart_str_appends(buf, attr->name);
    4830             :                                                 smart_str_appendl(buf, ";\n", 2);
    4831             :                                         } ZEND_HASH_FOREACH_END();
    4832             :                                 }
    4833          47 :                                 if (spaces.s) {
    4834           0 :                                         smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s));
    4835             :                                 }
    4836             :                                 smart_str_appendc(buf, '}');
    4837             :                         }
    4838             :                         break;
    4839             :                 default:
    4840             :                         break;
    4841             :         }
    4842             :         smart_str_free(&spaces);
    4843             :         smart_str_0(buf);
    4844         128 : }
    4845             : 
    4846           4 : static void delete_url(void *handle)
    4847             : {
    4848           4 :         php_url_free((php_url*)handle);
    4849           4 : }
    4850             : 
    4851         458 : static void delete_service(void *data)
    4852             : {
    4853         458 :         soapServicePtr service = (soapServicePtr)data;
    4854             : 
    4855         458 :         if (service->soap_functions.ft) {
    4856         457 :                 zend_hash_destroy(service->soap_functions.ft);
    4857         457 :                 efree(service->soap_functions.ft);
    4858             :         }
    4859             : 
    4860         458 :         if (service->typemap) {
    4861           8 :                 zend_hash_destroy(service->typemap);
    4862           8 :                 efree(service->typemap);
    4863             :         }
    4864             : 
    4865         458 :         if (service->soap_class.argc) {
    4866             :                 int i;
    4867           2 :                 for (i = 0; i < service->soap_class.argc;i++) {
    4868           1 :                         zval_ptr_dtor(&service->soap_class.argv[i]);
    4869             :                 }
    4870           1 :                 efree(service->soap_class.argv);
    4871             :         }
    4872             : 
    4873         458 :         if (service->actor) {
    4874          81 :                 efree(service->actor);
    4875             :         }
    4876         458 :         if (service->uri) {
    4877         458 :                 efree(service->uri);
    4878             :         }
    4879         458 :         if (service->sdl) {
    4880         410 :                 delete_sdl(service->sdl);
    4881             :         }
    4882         458 :         if (service->encoding) {
    4883           4 :                 xmlCharEncCloseFunc(service->encoding);
    4884             :         }
    4885         458 :         if (service->class_map) {
    4886          11 :                 zend_hash_destroy(service->class_map);
    4887          11 :                 FREE_HASHTABLE(service->class_map);
    4888             :         }
    4889         458 :         zval_ptr_dtor(&service->soap_object);
    4890         458 :         efree(service);
    4891         458 : }
    4892             : 
    4893           7 : static void delete_hashtable(void *data)
    4894             : {
    4895           7 :         HashTable *ht = (HashTable*)data;
    4896           7 :         zend_hash_destroy(ht);
    4897           7 :         efree(ht);
    4898           7 : }

Generated by: LCOV version 1.10

Generated at Wed, 24 Aug 2016 12:20:30 +0000 (7 hours ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.