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{
@@ -192,22 +214,22 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
192214 tmp = get_node (fault -> children , "faultstring" );
193215 if (tmp != NULL && tmp -> children != NULL ) {
194216 zval zv ;
195- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
217+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
196218 convert_to_string (& zv )
197219 faultstring = Z_STR (zv );
198220 }
199221
200222 tmp = get_node (fault -> children , "faultactor" );
201223 if (tmp != NULL && tmp -> children != NULL ) {
202224 zval zv ;
203- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
225+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
204226 convert_to_string (& zv )
205227 faultactor = Z_STR (zv );
206228 }
207229
208230 tmp = get_node (fault -> children , "detail" );
209231 if (tmp != NULL ) {
210- master_to_zval (& details , NULL , tmp );
232+ master_to_zval_with_doc_cleanup (& details , NULL , tmp , response );
211233 }
212234 } else {
213235 tmp = get_node (fault -> children , "Code" );
@@ -223,7 +245,7 @@ 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
@@ -238,7 +260,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
238260
239261 tmp = get_node (fault -> children ,"Detail" );
240262 if (tmp != NULL ) {
241- master_to_zval (& details , NULL , tmp );
263+ master_to_zval_with_doc_cleanup (& details , NULL , tmp , response );
242264 }
243265 }
244266 add_soap_fault (this_ptr , faultcode , faultstring ? ZSTR_VAL (faultstring ) : NULL , faultactor ? ZSTR_VAL (faultactor ) : NULL , & details , lang );
@@ -332,9 +354,9 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
332354 } else {
333355 /* Decoding value of parameter */
334356 if (param != NULL ) {
335- master_to_zval (& tmp , param -> encode , val );
357+ master_to_zval_with_doc_cleanup (& tmp , param -> encode , val , response );
336358 } else {
337- master_to_zval (& tmp , NULL , val );
359+ master_to_zval_with_doc_cleanup (& tmp , NULL , val , response );
338360 }
339361 }
340362 add_assoc_zval (return_value , param -> paramName , & tmp );
@@ -355,7 +377,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
355377 zval tmp ;
356378 zval * arr ;
357379
358- master_to_zval (& tmp , NULL , val );
380+ master_to_zval_with_doc_cleanup (& tmp , NULL , val , response );
359381 if (val -> name ) {
360382 if ((arr = zend_hash_str_find (Z_ARRVAL_P (return_value ), (char * )val -> name , strlen ((char * )val -> name ))) != NULL ) {
361383 add_next_index_zval (arr , & tmp );
@@ -420,7 +442,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
420442 }
421443 smart_str_free (& key );
422444 }
423- master_to_zval (& val , enc , trav );
445+ master_to_zval_with_doc_cleanup (& val , enc , trav , response );
424446 add_assoc_zval (soap_headers , (char * )trav -> name , & val );
425447 }
426448 trav = trav -> next ;
0 commit comments