mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fix persistent XML memory leaks in SOAP
SOAP uses a horrible bailout based error handling approach -- avoid leaking persistent XML memory by catching bailouts in a number of places.
This commit is contained in:
parent
cfeda978df
commit
78375aa52f
3 changed files with 46 additions and 8 deletions
|
@ -1519,7 +1519,13 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z
|
||||||
text = xmlNewText(BAD_CAST(str_val));
|
text = xmlNewText(BAD_CAST(str_val));
|
||||||
xmlAddChild(dummy, text);
|
xmlAddChild(dummy, text);
|
||||||
ZVAL_NULL(&data);
|
ZVAL_NULL(&data);
|
||||||
master_to_zval(&data, attr->encode, dummy);
|
/* TODO: There are other places using dummy nodes -- generalize? */
|
||||||
|
zend_try {
|
||||||
|
master_to_zval(&data, attr->encode, dummy);
|
||||||
|
} zend_catch {
|
||||||
|
xmlFreeNode(dummy);
|
||||||
|
zend_bailout();
|
||||||
|
} zend_end_try();
|
||||||
xmlFreeNode(dummy);
|
xmlFreeNode(dummy);
|
||||||
set_zval_property(ret, attr->name, &data);
|
set_zval_property(ret, attr->name, &data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -739,7 +739,9 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
|
||||||
zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
|
zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
|
||||||
zend_hash_init(&ctx.services, 0, NULL, NULL, 0);
|
zend_hash_init(&ctx.services, 0, NULL, NULL, 0);
|
||||||
|
|
||||||
load_wsdl_ex(this_ptr, struri,&ctx, 0);
|
load_wsdl_ex(this_ptr, struri, &ctx, 0);
|
||||||
|
zend_try {
|
||||||
|
|
||||||
schema_pass2(&ctx);
|
schema_pass2(&ctx);
|
||||||
|
|
||||||
n = zend_hash_num_elements(&ctx.services);
|
n = zend_hash_num_elements(&ctx.services);
|
||||||
|
@ -1166,6 +1168,12 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
|
||||||
soap_error0(E_ERROR, "Parsing WSDL: Could not find any usable binding services in WSDL.");
|
soap_error0(E_ERROR, "Parsing WSDL: Could not find any usable binding services in WSDL.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} zend_catch {
|
||||||
|
/* Avoid persistent memory leak. */
|
||||||
|
zend_hash_destroy(&ctx.docs);
|
||||||
|
zend_bailout();
|
||||||
|
} zend_end_try();
|
||||||
|
|
||||||
zend_hash_destroy(&ctx.messages);
|
zend_hash_destroy(&ctx.messages);
|
||||||
zend_hash_destroy(&ctx.bindings);
|
zend_hash_destroy(&ctx.bindings);
|
||||||
zend_hash_destroy(&ctx.portTypes);
|
zend_hash_destroy(&ctx.portTypes);
|
||||||
|
|
|
@ -1643,7 +1643,15 @@ PHP_METHOD(SoapServer, handle)
|
||||||
old_features = SOAP_GLOBAL(features);
|
old_features = SOAP_GLOBAL(features);
|
||||||
SOAP_GLOBAL(features) = service->features;
|
SOAP_GLOBAL(features) = service->features;
|
||||||
old_soap_version = SOAP_GLOBAL(soap_version);
|
old_soap_version = SOAP_GLOBAL(soap_version);
|
||||||
function = deserialize_function_call(service->sdl, doc_request, service->actor, &function_name, &num_params, ¶ms, &soap_version, &soap_headers);
|
|
||||||
|
zend_try {
|
||||||
|
function = deserialize_function_call(service->sdl, doc_request, service->actor, &function_name, &num_params, ¶ms, &soap_version, &soap_headers);
|
||||||
|
} zend_catch {
|
||||||
|
/* Avoid leaking persistent memory */
|
||||||
|
xmlFreeDoc(doc_request);
|
||||||
|
zend_bailout();
|
||||||
|
} zend_end_try();
|
||||||
|
|
||||||
xmlFreeDoc(doc_request);
|
xmlFreeDoc(doc_request);
|
||||||
|
|
||||||
if (EG(exception)) {
|
if (EG(exception)) {
|
||||||
|
@ -3821,6 +3829,8 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
|
||||||
encode_reset_ns();
|
encode_reset_ns();
|
||||||
|
|
||||||
doc = xmlNewDoc(BAD_CAST("1.0"));
|
doc = xmlNewDoc(BAD_CAST("1.0"));
|
||||||
|
zend_try {
|
||||||
|
|
||||||
doc->charset = XML_CHAR_ENCODING_UTF8;
|
doc->charset = XML_CHAR_ENCODING_UTF8;
|
||||||
doc->encoding = xmlCharStrdup("UTF-8");
|
doc->encoding = xmlCharStrdup("UTF-8");
|
||||||
|
|
||||||
|
@ -4162,6 +4172,12 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
|
||||||
|
|
||||||
encode_finish();
|
encode_finish();
|
||||||
|
|
||||||
|
} zend_catch {
|
||||||
|
/* Avoid persistent memory leak. */
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
zend_bailout();
|
||||||
|
} zend_end_try();
|
||||||
|
|
||||||
if (function && function->responseName == NULL &&
|
if (function && function->responseName == NULL &&
|
||||||
body->children == NULL && head == NULL) {
|
body->children == NULL && head == NULL) {
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
|
@ -4183,6 +4199,8 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
|
||||||
encode_reset_ns();
|
encode_reset_ns();
|
||||||
|
|
||||||
doc = xmlNewDoc(BAD_CAST("1.0"));
|
doc = xmlNewDoc(BAD_CAST("1.0"));
|
||||||
|
zend_try {
|
||||||
|
|
||||||
doc->encoding = xmlCharStrdup("UTF-8");
|
doc->encoding = xmlCharStrdup("UTF-8");
|
||||||
doc->charset = XML_CHAR_ENCODING_UTF8;
|
doc->charset = XML_CHAR_ENCODING_UTF8;
|
||||||
if (version == SOAP_1_1) {
|
if (version == SOAP_1_1) {
|
||||||
|
@ -4222,7 +4240,7 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((zstyle = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "style", sizeof("style")-1)) != NULL &&
|
if ((zstyle = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "style", sizeof("style")-1)) != NULL &&
|
||||||
Z_TYPE_P(zstyle) == IS_LONG) {
|
Z_TYPE_P(zstyle) == IS_LONG) {
|
||||||
style = Z_LVAL_P(zstyle);
|
style = Z_LVAL_P(zstyle);
|
||||||
} else {
|
} else {
|
||||||
style = SOAP_RPC;
|
style = SOAP_RPC;
|
||||||
|
@ -4245,7 +4263,7 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((zuse = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use")-1)) != NULL &&
|
if ((zuse = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "use", sizeof("use")-1)) != NULL &&
|
||||||
Z_TYPE_P(zuse) == IS_LONG && Z_LVAL_P(zuse) == SOAP_LITERAL) {
|
Z_TYPE_P(zuse) == IS_LONG && Z_LVAL_P(zuse) == SOAP_LITERAL) {
|
||||||
use = SOAP_LITERAL;
|
use = SOAP_LITERAL;
|
||||||
} else {
|
} else {
|
||||||
use = SOAP_ENCODED;
|
use = SOAP_ENCODED;
|
||||||
|
@ -4307,9 +4325,9 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
|
||||||
|
|
||||||
ht = Z_OBJPROP_P(header);
|
ht = Z_OBJPROP_P(header);
|
||||||
if ((name = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
|
if ((name = zend_hash_str_find(ht, "name", sizeof("name")-1)) != NULL &&
|
||||||
Z_TYPE_P(name) == IS_STRING &&
|
Z_TYPE_P(name) == IS_STRING &&
|
||||||
(ns = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
|
(ns = zend_hash_str_find(ht, "namespace", sizeof("namespace")-1)) != NULL &&
|
||||||
Z_TYPE_P(ns) == IS_STRING) {
|
Z_TYPE_P(ns) == IS_STRING) {
|
||||||
xmlNodePtr h;
|
xmlNodePtr h;
|
||||||
xmlNsPtr nsptr;
|
xmlNsPtr nsptr;
|
||||||
int hdr_use = SOAP_LITERAL;
|
int hdr_use = SOAP_LITERAL;
|
||||||
|
@ -4362,6 +4380,12 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
|
||||||
|
|
||||||
encode_finish();
|
encode_finish();
|
||||||
|
|
||||||
|
} zend_catch {
|
||||||
|
/* Avoid persistent memory leak. */
|
||||||
|
xmlFreeDoc(doc);
|
||||||
|
zend_bailout();
|
||||||
|
} zend_end_try();
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue