1818
1919#include "php_soap.h"
2020
21+ static void master_to_zval_with_doc_cleanup (zval * ret , encodePtr encode , xmlNodePtr data , xmlDocPtr doc )
22+ {
23+ bool bailout = false;
24+
25+ ZVAL_UNDEF (ret );
26+
27+ /* SoapClient can turn decode errors into a bailout before parse_packet_soap() frees the response doc. */
28+ zend_try {
29+ master_to_zval (ret , encode , data );
30+ } zend_catch {
31+ bailout = true;
32+ } zend_end_try ();
33+
34+ if (bailout ) {
35+ if (!Z_ISUNDEF_P (ret )) {
36+ zval_ptr_dtor (ret );
37+ }
38+ xmlFreeDoc (doc );
39+ zend_bailout ();
40+ }
41+ }
42+
2143/* SOAP client calls this function to parse response from SOAP server */
2244bool parse_packet_soap (zval * this_ptr , char * buffer , int buffer_size , sdlFunctionPtr fn , char * fn_name , zval * return_value , zval * soap_headers )
2345{
@@ -191,22 +213,22 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
191213 tmp = get_node (fault -> children , "faultstring" );
192214 if (tmp != NULL && tmp -> children != NULL ) {
193215 zval zv ;
194- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
216+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
195217 convert_to_string (& zv )
196218 faultstring = Z_STR (zv );
197219 }
198220
199221 tmp = get_node (fault -> children , "faultactor" );
200222 if (tmp != NULL && tmp -> children != NULL ) {
201223 zval zv ;
202- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
224+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
203225 convert_to_string (& zv )
204226 faultactor = Z_STR (zv );
205227 }
206228
207229 tmp = get_node (fault -> children , "detail" );
208230 if (tmp != NULL ) {
209- master_to_zval (& details , NULL , tmp );
231+ master_to_zval_with_doc_cleanup (& details , NULL , tmp , response );
210232 }
211233 } else {
212234 tmp = get_node (fault -> children , "Code" );
@@ -223,15 +245,15 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
223245 tmp = get_node (tmp -> children ,"Text" );
224246 if (tmp != NULL && tmp -> children != NULL ) {
225247 zval zv ;
226- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
248+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
227249 convert_to_string (& zv )
228250 faultstring = Z_STR (zv );
229251 }
230252 }
231253
232254 tmp = get_node (fault -> children ,"Detail" );
233255 if (tmp != NULL ) {
234- master_to_zval (& details , NULL , tmp );
256+ master_to_zval_with_doc_cleanup (& details , NULL , tmp , response );
235257 }
236258 }
237259 add_soap_fault (this_ptr , faultcode , faultstring ? ZSTR_VAL (faultstring ) : NULL , faultactor ? ZSTR_VAL (faultactor ) : NULL , & details );
@@ -324,9 +346,9 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
324346 } else {
325347 /* Decoding value of parameter */
326348 if (param != NULL ) {
327- master_to_zval (& tmp , param -> encode , val );
349+ master_to_zval_with_doc_cleanup (& tmp , param -> encode , val , response );
328350 } else {
329- master_to_zval (& tmp , NULL , val );
351+ master_to_zval_with_doc_cleanup (& tmp , NULL , val , response );
330352 }
331353 }
332354 add_assoc_zval (return_value , param -> paramName , & tmp );
@@ -347,7 +369,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
347369 zval tmp ;
348370 zval * arr ;
349371
350- master_to_zval (& tmp , NULL , val );
372+ master_to_zval_with_doc_cleanup (& tmp , NULL , val , response );
351373 if (val -> name ) {
352374 if ((arr = zend_hash_str_find (Z_ARRVAL_P (return_value ), (char * )val -> name , strlen ((char * )val -> name ))) != NULL ) {
353375 add_next_index_zval (arr , & tmp );
@@ -412,7 +434,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
412434 }
413435 smart_str_free (& key );
414436 }
415- master_to_zval (& val , enc , trav );
437+ master_to_zval_with_doc_cleanup (& val , enc , trav , response );
416438 add_assoc_zval (soap_headers , (char * )trav -> name , & val );
417439 }
418440 trav = trav -> next ;
0 commit comments