From 8e9c3fe71c997bffcbae52fc6484d9336c9535fd Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 28 May 2025 19:16:09 +0200 Subject: [PATCH 1/2] Use function table directly in soap do_request The function will exist, avoid creating a temporary string and lowercasing it. --- ext/soap/soap.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 1084f9c691cf..4c945634009f 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -2209,7 +2209,6 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co bool ret = true; char *buf; int buf_size; - zval func; zval params[5]; bool _bailout = false; @@ -2228,7 +2227,6 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_P(this_ptr), buf, buf_size); } - ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1); ZVAL_STRINGL(¶ms[0], buf, buf_size); ZVAL_STRING(¶ms[1], location); if (action == NULL) { @@ -2239,10 +2237,12 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co ZVAL_LONG(¶ms[3], version); ZVAL_BOOL(¶ms[4], one_way); - if (call_user_function(NULL, this_ptr, &func, response, 5, params) != SUCCESS) { - add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() failed", NULL, NULL); - ret = false; - } else if (Z_TYPE_P(response) != IS_STRING) { + zend_function *func = zend_hash_str_find_ptr(&Z_OBJCE_P(this_ptr)->function_table, ZEND_STRL("__dorequest")); + ZEND_ASSERT(func != NULL); + + zend_call_known_instance_method(func, Z_OBJ_P(this_ptr), response, 5, params); + + if (Z_TYPE_P(response) != IS_STRING) { if (EG(exception) && instanceof_function(EG(exception)->ce, zend_ce_error)) { /* Programmer error in __doRequest() implementation, let it bubble up. */ } else if (Z_TYPE_P(Z_CLIENT_SOAP_FAULT_P(this_ptr)) != IS_OBJECT) { @@ -2256,7 +2256,6 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co } zend_catch { _bailout = true; } zend_end_try(); - zval_ptr_dtor(&func); zval_ptr_dtor(¶ms[2]); zval_ptr_dtor(¶ms[1]); zval_ptr_dtor(¶ms[0]); From 2cf41550ed24ccabadf4ab72a0b229f1c890cfab Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 28 May 2025 19:18:12 +0200 Subject: [PATCH 2/2] Avoid creating a zend_string twice in soap do_request --- ext/soap/soap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 4c945634009f..09043886b9c6 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -2221,12 +2221,6 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co } zend_try { - zval *trace = Z_CLIENT_TRACE_P(this_ptr); - if (Z_TYPE_P(trace) == IS_TRUE) { - zval_ptr_dtor(Z_CLIENT_LAST_REQUEST_P(this_ptr)); - ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_P(this_ptr), buf, buf_size); - } - ZVAL_STRINGL(¶ms[0], buf, buf_size); ZVAL_STRING(¶ms[1], location); if (action == NULL) { @@ -2237,6 +2231,12 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co ZVAL_LONG(¶ms[3], version); ZVAL_BOOL(¶ms[4], one_way); + zval *trace = Z_CLIENT_TRACE_P(this_ptr); + if (Z_TYPE_P(trace) == IS_TRUE) { + zval_ptr_dtor(Z_CLIENT_LAST_REQUEST_P(this_ptr)); + ZVAL_COPY(Z_CLIENT_LAST_REQUEST_P(this_ptr), ¶ms[0]); + } + zend_function *func = zend_hash_str_find_ptr(&Z_OBJCE_P(this_ptr)->function_table, ZEND_STRL("__dorequest")); ZEND_ASSERT(func != NULL);