1616
1717#include "php_soap.h"
1818
19+ static void master_to_zval_with_doc_cleanup (zval * ret , encodePtr encode , xmlNodePtr data , xmlDocPtr doc )
20+ {
21+ bool bailout = false;
22+
23+ ZVAL_UNDEF (ret );
24+
25+ /* SoapClient can turn decode errors into a bailout before parse_packet_soap() frees the response doc. */
26+ zend_try {
27+ master_to_zval (ret , encode , data );
28+ } zend_catch {
29+ bailout = true;
30+ } zend_end_try ();
31+
32+ if (bailout ) {
33+ if (!Z_ISUNDEF_P (ret )) {
34+ zval_ptr_dtor (ret );
35+ }
36+ xmlFreeDoc (doc );
37+ zend_bailout ();
38+ }
39+ }
40+
1941/* SOAP client calls this function to parse response from SOAP server */
2042bool parse_packet_soap (zval * this_ptr , char * buffer , int buffer_size , sdlFunctionPtr fn , char * fn_name , zval * return_value , zval * soap_headers )
2143{
@@ -190,22 +212,22 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
190212 tmp = get_node (fault -> children , "faultstring" );
191213 if (tmp != NULL && tmp -> children != NULL ) {
192214 zval zv ;
193- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
215+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
194216 convert_to_string (& zv )
195217 faultstring = Z_STR (zv );
196218 }
197219
198220 tmp = get_node (fault -> children , "faultactor" );
199221 if (tmp != NULL && tmp -> children != NULL ) {
200222 zval zv ;
201- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
223+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
202224 convert_to_string (& zv )
203225 faultactor = Z_STR (zv );
204226 }
205227
206228 tmp = get_node (fault -> children , "detail" );
207229 if (tmp != NULL ) {
208- master_to_zval (& details , NULL , tmp );
230+ master_to_zval_with_doc_cleanup (& details , NULL , tmp , response );
209231 }
210232 } else {
211233 tmp = get_node (fault -> children , "Code" );
@@ -221,7 +243,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
221243 tmp = get_node (tmp -> children ,"Text" );
222244 if (tmp != NULL && tmp -> children != NULL ) {
223245 zval zv ;
224- master_to_zval (& zv , get_conversion (IS_STRING ), tmp );
246+ master_to_zval_with_doc_cleanup (& zv , get_conversion (IS_STRING ), tmp , response );
225247 convert_to_string (& zv )
226248 faultstring = Z_STR (zv );
227249
@@ -236,7 +258,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
236258
237259 tmp = get_node (fault -> children ,"Detail" );
238260 if (tmp != NULL ) {
239- master_to_zval (& details , NULL , tmp );
261+ master_to_zval_with_doc_cleanup (& details , NULL , tmp , response );
240262 }
241263 }
242264 add_soap_fault (this_ptr , faultcode , faultstring ? ZSTR_VAL (faultstring ) : NULL , faultactor ? ZSTR_VAL (faultactor ) : NULL , & details , lang );
@@ -330,9 +352,9 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
330352 } else {
331353 /* Decoding value of parameter */
332354 if (param != NULL ) {
333- master_to_zval (& tmp , param -> encode , val );
355+ master_to_zval_with_doc_cleanup (& tmp , param -> encode , val , response );
334356 } else {
335- master_to_zval (& tmp , NULL , val );
357+ master_to_zval_with_doc_cleanup (& tmp , NULL , val , response );
336358 }
337359 }
338360 add_assoc_zval (return_value , param -> paramName , & tmp );
@@ -353,7 +375,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
353375 zval tmp ;
354376 zval * arr ;
355377
356- master_to_zval (& tmp , NULL , val );
378+ master_to_zval_with_doc_cleanup (& tmp , NULL , val , response );
357379 if (val -> name ) {
358380 if ((arr = zend_hash_str_find (Z_ARRVAL_P (return_value ), (char * )val -> name , strlen ((char * )val -> name ))) != NULL ) {
359381 add_next_index_zval (arr , & tmp );
@@ -418,7 +440,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio
418440 }
419441 smart_str_free (& key );
420442 }
421- master_to_zval (& val , enc , trav );
443+ master_to_zval_with_doc_cleanup (& val , enc , trav , response );
422444 add_assoc_zval (soap_headers , (char * )trav -> name , & val );
423445 }
424446 trav = trav -> next ;
0 commit comments