From 88ecdbeb4f982b0c1513268cc2131c222172ded9 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 13:38:37 +0100 Subject: [PATCH 01/16] ext/soap/php_http.c: fetch deflate/gzip internal functions directly --- ext/soap/php_http.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 2d6ed207efbdd..096986ee5bbae 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -386,31 +386,41 @@ int make_http_soap_request(zval *this_ptr, smart_str_append_const(&soap_headers_z,"Accept-Encoding: gzip, deflate\r\n"); } if (level > 0) { - zval func; + zend_function *fn; zval retval; zval params[3]; - int n; + uint32_t param_num; ZVAL_STR_COPY(¶ms[0], buf); ZVAL_LONG(¶ms[1], level); if (kind == SOAP_COMPRESSION_DEFLATE) { - n = 2; - ZVAL_STRING(&func, "gzcompress"); + param_num = 2; + fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("gzcompress")); + if (UNEXPECTED(fn == NULL)) { + zend_throw_error(NULL, "Function gzcompress() has been disabled"); + smart_str_free(&soap_headers_z); + return FALSE; + } + smart_str_append_const(&soap_headers_z,"Content-Encoding: deflate\r\n"); } else { - n = 3; - ZVAL_STRING(&func, "gzencode"); + param_num = 3; + fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("gzencode")); + if (UNEXPECTED(fn == NULL)) { + zend_throw_error(NULL, "Function gzencode() has been disabled"); + smart_str_free(&soap_headers_z); + return FALSE; + } + smart_str_append_const(&soap_headers_z,"Content-Encoding: gzip\r\n"); ZVAL_LONG(¶ms[2], 0x1f); } - if (call_user_function(CG(function_table), (zval*)NULL, &func, &retval, n, params) == SUCCESS && - Z_TYPE(retval) == IS_STRING) { - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(&func); + + zend_call_known_function(fn, NULL, NULL, &retval, param_num, params, NULL); + zval_ptr_dtor(¶ms[0]); + if (Z_TYPE(retval) == IS_STRING) { request = Z_STR(retval); } else { - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(&func); zval_ptr_dtor(&retval); if (request != buf) { zend_string_release_ex(request, 0); From 45c0e6b3c3e26a8037d3ba0856bd1b6974b5e749 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 13:42:19 +0100 Subject: [PATCH 02/16] ext/soap/php_http.c: Fix some indentation and code style issues --- ext/soap/php_http.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 096986ee5bbae..bad264e3a21e9 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -380,12 +380,15 @@ int make_http_soap_request(zval *this_ptr, int level = Z_LVAL_P(tmp) & 0x0f; int kind = Z_LVAL_P(tmp) & SOAP_COMPRESSION_DEFLATE; - if (level > 9) {level = 9;} + if (level > 9) { + level = 9; + } - if ((Z_LVAL_P(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) { + if ((Z_LVAL_P(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) { smart_str_append_const(&soap_headers_z,"Accept-Encoding: gzip, deflate\r\n"); - } - if (level > 0) { + } + + if (level > 0) { zend_function *fn; zval retval; zval params[3]; @@ -416,7 +419,7 @@ int make_http_soap_request(zval *this_ptr, ZVAL_LONG(¶ms[2], 0x1f); } - zend_call_known_function(fn, NULL, NULL, &retval, param_num, params, NULL); + zend_call_known_function(fn, NULL, NULL, &retval, param_num, params, NULL); zval_ptr_dtor(¶ms[0]); if (Z_TYPE(retval) == IS_STRING) { request = Z_STR(retval); @@ -428,7 +431,7 @@ int make_http_soap_request(zval *this_ptr, smart_str_free(&soap_headers_z); return FALSE; } - } + } } tmp = Z_CLIENT_HTTPSOCKET_P(this_ptr); @@ -461,7 +464,9 @@ int make_http_soap_request(zval *this_ptr, try_again: if (phpurl == NULL || phpurl->host == NULL) { - if (phpurl != NULL) {php_url_free(phpurl);} + if (phpurl != NULL) { + php_url_free(phpurl); + } if (request != buf) { zend_string_release_ex(request, 0); } @@ -1052,7 +1057,7 @@ int make_http_soap_request(zval *this_ptr, if (sempos != NULL) { options = sempos+1; } else { - break; + break; } } } @@ -1509,7 +1514,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) if (len_read <= 0) { /* Error or EOF */ done = TRUE; - break; + break; } len_size += len_read; http_buf_size += len_read; From 1ee7821d3ba8da14243a47acd7e1e012023938d9 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 13:45:53 +0100 Subject: [PATCH 03/16] ext/soap/php_http.c: Use more appropriate smart_str API --- ext/soap/php_http.c | 46 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index bad264e3a21e9..4cc05324117d4 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -253,12 +253,12 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph } smart_str_append_const(&soap_headers, "CONNECT "); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); + smart_str_append(&soap_headers, phpurl->host); smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, phpurl->port); smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"); smart_str_append_const(&soap_headers, "Host: "); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); + smart_str_append(&soap_headers, phpurl->host); if (phpurl->port != 80) { smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, phpurl->port); @@ -584,24 +584,24 @@ int make_http_soap_request(zval *this_ptr, smart_str_append_const(&soap_headers, "POST "); if (use_proxy && !use_ssl) { - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->scheme)); + smart_str_append(&soap_headers, phpurl->scheme); smart_str_append_const(&soap_headers, "://"); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); + smart_str_append(&soap_headers, phpurl->host); smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, phpurl->port); } if (phpurl->path) { - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->path)); + smart_str_append(&soap_headers, phpurl->path); } else { smart_str_appendc(&soap_headers, '/'); } if (phpurl->query) { smart_str_appendc(&soap_headers, '?'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->query)); + smart_str_append(&soap_headers, phpurl->query); } if (phpurl->fragment) { smart_str_appendc(&soap_headers, '#'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->fragment)); + smart_str_append(&soap_headers, phpurl->fragment); } if (http_1_1) { smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"); @@ -609,7 +609,7 @@ int make_http_soap_request(zval *this_ptr, smart_str_append_const(&soap_headers, " HTTP/1.0\r\n"); } smart_str_append_const(&soap_headers, "Host: "); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); + smart_str_append(&soap_headers, phpurl->host); if (phpurl->port != (use_ssl?443:80)) { smart_str_appendc(&soap_headers, ':'); smart_str_append_unsigned(&soap_headers, phpurl->port); @@ -625,7 +625,7 @@ int make_http_soap_request(zval *this_ptr, if (Z_TYPE_P(tmp) == IS_STRING) { if (Z_STRLEN_P(tmp) > 0) { smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); smart_str_append_const(&soap_headers, "\r\n"); } } else if (context && @@ -633,7 +633,7 @@ int make_http_soap_request(zval *this_ptr, Z_TYPE_P(tmp) == IS_STRING) { if (Z_STRLEN_P(tmp) > 0) { smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); smart_str_append_const(&soap_headers, "\r\n"); } } else if (FG(user_agent)) { @@ -653,7 +653,7 @@ int make_http_soap_request(zval *this_ptr, Z_STRLEN_P(tmp) > 0 ) { smart_str_append_const(&soap_headers, "Content-Type: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } else { smart_str_append_const(&soap_headers, "Content-Type: application/soap+xml; charset=utf-8"); } @@ -670,7 +670,7 @@ int make_http_soap_request(zval *this_ptr, Z_STRLEN_P(tmp) > 0 ) { smart_str_append_const(&soap_headers, "Content-Type: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); smart_str_append_const(&soap_headers, "\r\n"); } else { smart_str_append_const(&soap_headers, "Content-Type: text/xml; charset=utf-8\r\n"); @@ -682,7 +682,7 @@ int make_http_soap_request(zval *this_ptr, } } smart_str_append_const(&soap_headers,"Content-Length: "); - smart_str_append_long(&soap_headers, request->len); + smart_str_append_unsigned(&soap_headers, ZSTR_LEN(request)); smart_str_append_const(&soap_headers, "\r\n"); /* HTTP Authentication */ @@ -790,30 +790,30 @@ int make_http_soap_request(zval *this_ptr, make_digest(response, hash); smart_str_append_const(&soap_headers, "Authorization: Digest username=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(login), Z_STRLEN_P(login)); + smart_str_append(&soap_headers, Z_STR_P(login)); if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "realm", sizeof("realm")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", realm=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", nonce=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } smart_str_append_const(&soap_headers, "\", uri=\""); if (phpurl->path) { - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->path)); + smart_str_append(&soap_headers, phpurl->path); } else { smart_str_appendc(&soap_headers, '/'); } if (phpurl->query) { smart_str_appendc(&soap_headers, '?'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->query)); + smart_str_append(&soap_headers, phpurl->query); } if (phpurl->fragment) { smart_str_appendc(&soap_headers, '#'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->fragment)); + smart_str_append(&soap_headers, phpurl->fragment); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "qop", sizeof("qop")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { @@ -829,12 +829,12 @@ int make_http_soap_request(zval *this_ptr, if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "opaque", sizeof("opaque")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", opaque=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "algorithm", sizeof("algorithm")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", algorithm=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } smart_str_append_const(&soap_headers, "\"\r\n"); } else { @@ -886,7 +886,7 @@ int make_http_soap_request(zval *this_ptr, in_domain(phpurl->host, Z_STR_P(tmp))) && (use_ssl || (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 3)) == NULL)) { if (!first_cookie) { - smart_str_appends(&soap_headers, "; "); + smart_str_append_const(&soap_headers, "; "); } first_cookie = false; smart_str_append(&soap_headers, key); @@ -909,7 +909,7 @@ int make_http_soap_request(zval *this_ptr, ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr), ZSTR_VAL(soap_headers.s), ZSTR_LEN(soap_headers.s)); } - smart_str_appendl(&soap_headers, request->val, request->len); + smart_str_append(&soap_headers, request); smart_str_0(&soap_headers); err = php_stream_write(stream, ZSTR_VAL(soap_headers.s), ZSTR_LEN(soap_headers.s)); From bf869a50b8d866c52afe85819457090361f58f93 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 15:01:11 +0100 Subject: [PATCH 04/16] ext/soap/php_http.c: Refactor proxy_authentication() --- ext/soap/php_http.c | 10 +++++----- ext/soap/php_http.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 4cc05324117d4..86a2ac73add33 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -28,15 +28,15 @@ static zend_string *get_http_headers(php_stream *socketd); smart_str_appendl(str,const,sizeof(const)-1) /* Proxy HTTP Authentication */ -int proxy_authentication(zval* this_ptr, smart_str* soap_headers) +bool proxy_authentication(const zval* this_ptr, smart_str* soap_headers) { - zval *login = Z_CLIENT_PROXY_LOGIN_P(this_ptr); + const zval *login = Z_CLIENT_PROXY_LOGIN_P(this_ptr); if (Z_TYPE_P(login) == IS_STRING) { smart_str auth = {0}; smart_str_append(&auth, Z_STR_P(login)); smart_str_appendc(&auth, ':'); - zval *password = Z_CLIENT_PROXY_PASSWORD_P(this_ptr); + const zval *password = Z_CLIENT_PROXY_PASSWORD_P(this_ptr); if (Z_TYPE_P(password) == IS_STRING) { smart_str_append(&auth, Z_STR_P(password)); } @@ -47,9 +47,9 @@ int proxy_authentication(zval* this_ptr, smart_str* soap_headers) smart_str_append_const(soap_headers, "\r\n"); zend_string_release_ex(buf, 0); smart_str_free(&auth); - return 1; + return true; } - return 0; + return false; } /* HTTP Authentication */ diff --git a/ext/soap/php_http.h b/ext/soap/php_http.h index df24c0d26fa84..7fd05380f82d1 100644 --- a/ext/soap/php_http.h +++ b/ext/soap/php_http.h @@ -26,7 +26,7 @@ int make_http_soap_request(zval *this_ptr, int soap_version, zval *response); -int proxy_authentication(zval* this_ptr, smart_str* soap_headers); +bool proxy_authentication(const zval* this_ptr, smart_str* soap_headers); int basic_authentication(zval* this_ptr, smart_str* soap_headers); void http_context_headers(php_stream_context* context, bool has_authorization, From 1af4b35ffc1a7e10e859edabd7928ab84ae3f9b4 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 13:48:34 +0100 Subject: [PATCH 05/16] ext/soap/php_http.c: Refactor basic_authentication() --- ext/soap/php_http.c | 16 ++++++++-------- ext/soap/php_http.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 86a2ac73add33..f6d30260097d0 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -53,29 +53,29 @@ bool proxy_authentication(const zval* this_ptr, smart_str* soap_headers) } /* HTTP Authentication */ -int basic_authentication(zval* this_ptr, smart_str* soap_headers) +bool basic_authentication(const zval* this_ptr, smart_str* soap_headers) { - zval *login = Z_CLIENT_LOGIN_P(this_ptr); - zval *use_digest = Z_CLIENT_USE_DIGEST_P(this_ptr); + const zval *login = Z_CLIENT_LOGIN_P(this_ptr); + const zval *use_digest = Z_CLIENT_USE_DIGEST_P(this_ptr); if (Z_TYPE_P(login) == IS_STRING && Z_TYPE_P(use_digest) != IS_TRUE) { smart_str auth = {0}; smart_str_append(&auth, Z_STR_P(login)); smart_str_appendc(&auth, ':'); - zval *password = Z_CLIENT_PASSWORD_P(this_ptr); + const zval *password = Z_CLIENT_PASSWORD_P(this_ptr); if (Z_TYPE_P(password) == IS_STRING) { smart_str_append(&auth, Z_STR_P(password)); } smart_str_0(&auth); - zend_string *buf = php_base64_encode((unsigned char*)ZSTR_VAL(auth.s), ZSTR_LEN(auth.s)); + zend_string *buf = php_base64_encode_str(auth.s); smart_str_append_const(soap_headers, "Authorization: Basic "); smart_str_append(soap_headers, buf); smart_str_append_const(soap_headers, "\r\n"); - zend_string_release_ex(buf, 0); + zend_string_release_ex(buf, false); smart_str_free(&auth); - return 1; + return true; } - return 0; + return false; } static void http_context_add_header(const char *s, diff --git a/ext/soap/php_http.h b/ext/soap/php_http.h index 7fd05380f82d1..17ce6d77d26b5 100644 --- a/ext/soap/php_http.h +++ b/ext/soap/php_http.h @@ -27,7 +27,7 @@ int make_http_soap_request(zval *this_ptr, zval *response); bool proxy_authentication(const zval* this_ptr, smart_str* soap_headers); -int basic_authentication(zval* this_ptr, smart_str* soap_headers); +bool basic_authentication(const zval* this_ptr, smart_str* soap_headers); void http_context_headers(php_stream_context* context, bool has_authorization, bool has_proxy_authorization, From 2f0643dbc571c3d740c4ca080010ea9b5560e558 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 13:51:43 +0100 Subject: [PATCH 06/16] ext/soap/php_http.c: Refactor in_domain() --- ext/soap/php_http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index f6d30260097d0..1183c8ff37e3e 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -326,9 +326,9 @@ static bool in_domain(const zend_string *host, const zend_string *domain) { if (ZSTR_VAL(domain)[0] == '.') { if (ZSTR_LEN(host) > ZSTR_LEN(domain)) { - return strcmp(ZSTR_VAL(host)+ZSTR_LEN(host)-ZSTR_LEN(domain), ZSTR_VAL(domain)) == 0; + return zend_string_equals_cstr(domain, ZSTR_VAL(host)+ZSTR_LEN(host)-ZSTR_LEN(domain), ZSTR_LEN(domain)); } else { - return 0; + return false; } } else { return zend_string_equals(host,domain); From 3351e415d3877230c0cc642b89ab2c54dc00e080 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 14:08:14 +0100 Subject: [PATCH 07/16] ext/soap/php_http.c: Refactor make_http_soap_request() - Use zend_string* to prevent unnecessary strlen computations - Use bool instead of int - Reduce scope of variables --- ext/soap/php_http.c | 129 ++++++++++++++++++++++---------------------- ext/soap/php_http.h | 13 ++--- ext/soap/soap.c | 10 ++-- 3 files changed, 76 insertions(+), 76 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 1183c8ff37e3e..99ecdcea96629 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -335,13 +335,14 @@ static bool in_domain(const zend_string *host, const zend_string *domain) } } -int make_http_soap_request(zval *this_ptr, - zend_string *buf, - char *location, - char *soapaction, - int soap_version, - zval *return_value) -{ +bool make_http_soap_request( + zval *this_ptr, + zend_string *buf, + zend_string *location, + zend_string *soapaction, + zend_long soap_version, + zval *return_value +) { zend_string *request; smart_str soap_headers = {0}; smart_str soap_headers_z = {0}; @@ -354,23 +355,20 @@ int make_http_soap_request(zval *this_ptr, zend_string *http_body; char *content_type, *http_version, *cookie_itt; size_t cookie_len; - int http_close; + bool http_close; zend_string *http_headers; char *connection; - int http_1_1; + bool http_1_1; int http_status; - int content_type_xml = 0; + bool content_type_xml = false; zend_long redirect_max = 20; char *content_encoding; char *http_msg = NULL; bool old_allow_url_fopen; php_stream_context *context = NULL; - bool has_authorization = 0; - bool has_proxy_authorization = 0; - bool has_cookies = 0; if (this_ptr == NULL || Z_TYPE_P(this_ptr) != IS_OBJECT) { - return FALSE; + return false; } request = buf; @@ -402,7 +400,7 @@ int make_http_soap_request(zval *this_ptr, if (UNEXPECTED(fn == NULL)) { zend_throw_error(NULL, "Function gzcompress() has been disabled"); smart_str_free(&soap_headers_z); - return FALSE; + return false; } smart_str_append_const(&soap_headers_z,"Content-Encoding: deflate\r\n"); @@ -412,7 +410,7 @@ int make_http_soap_request(zval *this_ptr, if (UNEXPECTED(fn == NULL)) { zend_throw_error(NULL, "Function gzencode() has been disabled"); smart_str_free(&soap_headers_z); - return FALSE; + return false; } smart_str_append_const(&soap_headers_z,"Content-Encoding: gzip\r\n"); @@ -429,7 +427,7 @@ int make_http_soap_request(zval *this_ptr, zend_string_release_ex(request, 0); } smart_str_free(&soap_headers_z); - return FALSE; + return false; } } } @@ -445,8 +443,8 @@ int make_http_soap_request(zval *this_ptr, stream = NULL; } - if (location != NULL && location[0] != '\000') { - phpurl = php_url_parse(location); + if (ZSTR_LEN(location) != 0) { + phpurl = php_url_parse_ex(ZSTR_VAL(location), ZSTR_LEN(location)); } tmp = Z_CLIENT_STREAM_CONTEXT_P(this_ptr); @@ -473,7 +471,7 @@ int make_http_soap_request(zval *this_ptr, add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } use_ssl = 0; @@ -487,7 +485,7 @@ int make_http_soap_request(zval *this_ptr, add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } old_allow_url_fopen = PG(allow_url_fopen); @@ -501,7 +499,7 @@ int make_http_soap_request(zval *this_ptr, PG(allow_url_fopen) = old_allow_url_fopen; smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } if (phpurl->port == 0) { @@ -554,7 +552,7 @@ int make_http_soap_request(zval *this_ptr, PG(allow_url_fopen) = old_allow_url_fopen; smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } } PG(allow_url_fopen) = old_allow_url_fopen; @@ -562,7 +560,7 @@ int make_http_soap_request(zval *this_ptr, bool client_trace = Z_TYPE_P(Z_CLIENT_TRACE_P(this_ptr)) == IS_TRUE; if (stream) { - zval *cookies, *login, *password; + zval *cookies, *login; zval *url_zval = Z_CLIENT_HTTPURL_P(this_ptr); if (Z_TYPE_P(url_zval) == IS_OBJECT) { @@ -577,9 +575,9 @@ int make_http_soap_request(zval *this_ptr, (tmp = php_stream_context_get_option(context, "http", "protocol_version")) != NULL && Z_TYPE_P(tmp) == IS_DOUBLE && Z_DVAL_P(tmp) == 1.0) { - http_1_1 = 0; + http_1_1 = false; } else { - http_1_1 = 1; + http_1_1 = true; } smart_str_append_const(&soap_headers, "POST "); @@ -657,11 +655,10 @@ int make_http_soap_request(zval *this_ptr, } else { smart_str_append_const(&soap_headers, "Content-Type: application/soap+xml; charset=utf-8"); } - if (soapaction) { - smart_str_append_const(&soap_headers,"; action=\""); - smart_str_appends(&soap_headers, soapaction); - smart_str_append_const(&soap_headers,"\""); - } + + smart_str_append_const(&soap_headers,"; action=\""); + smart_str_append(&soap_headers, soapaction); + smart_str_append_const(&soap_headers,"\""); smart_str_append_const(&soap_headers,"\r\n"); } else { if (context && @@ -675,22 +672,22 @@ int make_http_soap_request(zval *this_ptr, } else { smart_str_append_const(&soap_headers, "Content-Type: text/xml; charset=utf-8\r\n"); } - if (soapaction) { - smart_str_append_const(&soap_headers, "SOAPAction: \""); - smart_str_appends(&soap_headers, soapaction); - smart_str_append_const(&soap_headers, "\"\r\n"); - } + + smart_str_append_const(&soap_headers, "SOAPAction: \""); + smart_str_append(&soap_headers, soapaction); + smart_str_append_const(&soap_headers, "\"\r\n"); } smart_str_append_const(&soap_headers,"Content-Length: "); smart_str_append_unsigned(&soap_headers, ZSTR_LEN(request)); smart_str_append_const(&soap_headers, "\r\n"); /* HTTP Authentication */ + bool has_authorization = false; login = Z_CLIENT_LOGIN_P(this_ptr); if (Z_TYPE_P(login) == IS_STRING) { zval *digest = Z_CLIENT_DIGEST_P(this_ptr); - has_authorization = 1; + has_authorization = true; if (Z_TYPE_P(digest) == IS_ARRAY) { char HA1[33], HA2[33], response[33], cnonce[33], nc[9]; unsigned char nonce[16]; @@ -706,7 +703,7 @@ int make_http_soap_request(zval *this_ptr, smart_str_free(&soap_headers_z); smart_str_free(&soap_headers); efree(http_msg); - return FALSE; + return false; } php_hash_bin2hex(cnonce, nonce, sizeof(nonce)); @@ -729,7 +726,7 @@ int make_http_soap_request(zval *this_ptr, PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); } PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); - password = Z_CLIENT_PASSWORD_P(this_ptr); + zval *password = Z_CLIENT_PASSWORD_P(this_ptr); if (Z_TYPE_P(password) == IS_STRING) { PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(password), Z_STRLEN_P(password)); } @@ -843,7 +840,7 @@ int make_http_soap_request(zval *this_ptr, smart_str auth = {0}; smart_str_append(&auth, Z_STR_P(login)); smart_str_appendc(&auth, ':'); - password = Z_CLIENT_PASSWORD_P(this_ptr); + zval *password = Z_CLIENT_PASSWORD_P(this_ptr); if (Z_TYPE_P(password) == IS_STRING) { smart_str_append(&auth, Z_STR_P(password)); } @@ -858,17 +855,19 @@ int make_http_soap_request(zval *this_ptr, } /* Proxy HTTP Authentication */ + bool has_proxy_authorization = false; if (use_proxy && !use_ssl) { has_proxy_authorization = proxy_authentication(this_ptr, &soap_headers); } /* Send cookies along with request */ + bool has_cookies = false; cookies = Z_CLIENT_COOKIES_P(this_ptr); ZEND_ASSERT(Z_TYPE_P(cookies) == IS_ARRAY); if (zend_hash_num_elements(Z_ARRVAL_P(cookies)) != 0 && !HT_IS_PACKED(Z_ARRVAL_P(cookies))) { zval *data; zend_string *key; - has_cookies = 1; + has_cookies = true; bool first_cookie = true; smart_str_append_const(&soap_headers, "Cookie: "); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(cookies), key, data) { @@ -924,14 +923,14 @@ int make_http_soap_request(zval *this_ptr, add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } smart_str_free(&soap_headers); } else { add_soap_fault(this_ptr, "HTTP", "Failed to create stream??", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } http_headers = NULL; @@ -948,7 +947,7 @@ int make_http_soap_request(zval *this_ptr, add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } if (client_trace) { @@ -957,14 +956,14 @@ int make_http_soap_request(zval *this_ptr, } /* Check to see what HTTP status was sent */ - http_1_1 = 0; + http_1_1 = false; http_status = 0; http_version = get_http_header_value(ZSTR_VAL(http_headers), "HTTP/"); if (http_version) { char *tmp; if (!strncmp(http_version,"1.1", 3)) { - http_1_1 = 1; + http_1_1 = true; } tmp = strstr(http_version," "); @@ -1083,41 +1082,41 @@ int make_http_soap_request(zval *this_ptr, /* See if the server requested a close */ if (http_1_1) { - http_close = FALSE; + http_close = false; if (use_proxy && !use_ssl) { connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { - http_close = TRUE; + http_close = true; } efree(connection); } } - if (http_close == FALSE) { + if (!http_close) { connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { - http_close = TRUE; + http_close = true; } efree(connection); } } } else { - http_close = TRUE; + http_close = true; if (use_proxy && !use_ssl) { connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { - http_close = FALSE; + http_close = false; } efree(connection); } } - if (http_close == TRUE) { + if (http_close) { connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { - http_close = FALSE; + http_close = false; } efree(connection); } @@ -1139,7 +1138,7 @@ int make_http_soap_request(zval *this_ptr, efree(http_msg); } smart_str_free(&soap_headers_z); - return FALSE; + return false; } if (request != buf) { @@ -1196,7 +1195,7 @@ int make_http_soap_request(zval *this_ptr, add_soap_fault(this_ptr, "HTTP", "Redirection limit reached, aborting", NULL, NULL, SOAP_GLOBAL(lang_en)); smart_str_free(&soap_headers_z); efree(http_msg); - return FALSE; + return false; } goto try_again; @@ -1289,7 +1288,7 @@ int make_http_soap_request(zval *this_ptr, } if (strncmp(content_type, "text/xml", cmplen) == 0 || strncmp(content_type, "application/soap+xml", cmplen) == 0) { - content_type_xml = 1; + content_type_xml = true; /* if (strncmp(http_body, "= 400) { - int error = 0; + bool error = false; if (Z_STRLEN_P(return_value) == 0) { - error = 1; + error = true; } else if (Z_STRLEN_P(return_value) > 0) { if (!content_type_xml) { char *s = Z_STRVAL_P(return_value); @@ -1367,7 +1366,7 @@ int make_http_soap_request(zval *this_ptr, s++; } if (strncmp(s, " Date: Mon, 7 Jul 2025 14:29:49 +0100 Subject: [PATCH 08/16] ext/soap/php_http.c: Refactor get_http_body() - Use zend_string* to prevent unnecessary strlen computations in the futrue - Use bool instead of int - Reduce scope of variables --- ext/soap/php_http.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 99ecdcea96629..818b9ceb99e14 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -21,7 +21,7 @@ static char *get_http_header_value_nodup(char *headers, char *type, size_t *len); static char *get_http_header_value(char *headers, char *type); -static zend_string *get_http_body(php_stream *socketd, int close, char *headers); +static zend_string *get_http_body(php_stream *stream, bool close, zend_string *headers); static zend_string *get_http_headers(php_stream *socketd); #define smart_str_append_const(str, const) \ @@ -1124,7 +1124,7 @@ bool make_http_soap_request( } - http_body = get_http_body(stream, http_close, ZSTR_VAL(http_headers)); + http_body = get_http_body(stream, http_close, http_headers); if (!http_body) { if (request != buf) { zend_string_release_ex(request, 0); @@ -1454,25 +1454,32 @@ static char *get_http_header_value(char *headers, char *type) return NULL; } -static zend_string* get_http_body(php_stream *stream, int close, char *headers) +static zend_string* get_http_body(php_stream *stream, bool close, zend_string *headers) { zend_string *http_buf = NULL; char *header; - int header_close = close, header_chunked = 0, header_length = 0, http_buf_size = 0; + bool header_close = close; + bool header_chunked = false; + int header_length = 0; + size_t http_buf_size = 0; if (!close) { - header = get_http_header_value(headers, "Connection:"); + header = get_http_header_value(ZSTR_VAL(headers), "Connection:"); if (header) { - if(!strncasecmp(header, "close", sizeof("close")-1)) header_close = 1; + if (!strncasecmp(header, "close", sizeof("close")-1)) { + header_close = true; + } efree(header); } } - header = get_http_header_value(headers, "Transfer-Encoding:"); + header = get_http_header_value(ZSTR_VAL(headers), "Transfer-Encoding:"); if (header) { - if(!strncasecmp(header, "chunked", sizeof("chunked")-1)) header_chunked = 1; + if (!strncasecmp(header, "chunked", sizeof("chunked")-1)) { + header_chunked = true; + } efree(header); } - header = get_http_header_value(headers, "Content-Length:"); + header = get_http_header_value(ZSTR_VAL(headers), "Content-Length:"); if (header) { header_length = atoi(header); efree(header); @@ -1483,9 +1490,8 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) } if (header_chunked) { - char ch, done, headerbuf[8192]; - - done = FALSE; + char headerbuf[8192]; + bool done = false; while (!done) { int buf_size = 0; @@ -1495,13 +1501,6 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) if (buf_size > 0) { size_t len_size = 0; - if (http_buf_size + buf_size + 1 < 0) { - if (http_buf) { - zend_string_release_ex(http_buf, 0); - } - return NULL; - } - if (http_buf) { http_buf = zend_string_realloc(http_buf, http_buf_size + buf_size, 0); } else { @@ -1512,7 +1511,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) ssize_t len_read = php_stream_read(stream, http_buf->val + http_buf_size, buf_size - len_size); if (len_read <= 0) { /* Error or EOF */ - done = TRUE; + done = true; break; } len_size += len_read; @@ -1520,7 +1519,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) } /* Eat up '\r' '\n' */ - ch = php_stream_getc(stream); + char ch = php_stream_getc(stream); if (ch == '\r') { ch = php_stream_getc(stream); } @@ -1540,7 +1539,7 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) return NULL; } if (buf_size == 0) { - done = TRUE; + done = true; } } From 9159c5a4c526a62f4e0920f73b05ecf912bc1483 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 15:07:25 +0100 Subject: [PATCH 09/16] ext/soap/php_http.c: Refactor get_http_headers() --- ext/soap/php_http.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 818b9ceb99e14..ea3d715848b36 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -22,7 +22,7 @@ static char *get_http_header_value_nodup(char *headers, char *type, size_t *len); static char *get_http_header_value(char *headers, char *type); static zend_string *get_http_body(php_stream *stream, bool close, zend_string *headers); -static zend_string *get_http_headers(php_stream *socketd); +static zend_string *get_http_headers(php_stream *stream); #define smart_str_append_const(str, const) \ smart_str_appendl(str,const,sizeof(const)-1) @@ -1603,8 +1603,7 @@ static zend_string *get_http_headers(php_stream *stream) if ((headerbuf[0] == '\r' && headerbuf[1] == '\n') || (headerbuf[0] == '\n')) { /* empty line marks end of headers */ - smart_str_0(&tmp_response); - return tmp_response.s; + return smart_str_extract(&tmp_response); } /* add header to collection */ From 2951aeabc98b1d6688caea98b9b5ec47521bb4a5 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 14:32:53 +0100 Subject: [PATCH 10/16] ext/soap/php_http.c: Refactor get_http_header_value() - Use zend_string* to prevent unnecessary strlen computations in the futrue --- ext/soap/php_http.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index ea3d715848b36..312b6c6f7ddb9 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -20,7 +20,7 @@ #include "ext/hash/php_hash.h" /* For php_hash_bin2hex() */ static char *get_http_header_value_nodup(char *headers, char *type, size_t *len); -static char *get_http_header_value(char *headers, char *type); +static char *get_http_header_value(zend_string *headers, char *type); static zend_string *get_http_body(php_stream *stream, bool close, zend_string *headers); static zend_string *get_http_headers(php_stream *stream); @@ -958,7 +958,7 @@ bool make_http_soap_request( /* Check to see what HTTP status was sent */ http_1_1 = false; http_status = 0; - http_version = get_http_header_value(ZSTR_VAL(http_headers), "HTTP/"); + http_version = get_http_header_value(http_headers, "HTTP/"); if (http_version) { char *tmp; @@ -1084,7 +1084,7 @@ bool make_http_soap_request( if (http_1_1) { http_close = false; if (use_proxy && !use_ssl) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); + connection = get_http_header_value(http_headers, "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { http_close = true; @@ -1093,7 +1093,7 @@ bool make_http_soap_request( } } if (!http_close) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); + connection = get_http_header_value(http_headers, "Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { http_close = true; @@ -1104,7 +1104,7 @@ bool make_http_soap_request( } else { http_close = true; if (use_proxy && !use_ssl) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); + connection = get_http_header_value(http_headers, "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { http_close = false; @@ -1113,7 +1113,7 @@ bool make_http_soap_request( } } if (http_close) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); + connection = get_http_header_value(http_headers, "Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { http_close = false; @@ -1156,7 +1156,7 @@ bool make_http_soap_request( if (http_status >= 300 && http_status < 400) { char *loc; - if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location:")) != NULL) { + if ((loc = get_http_header_value(http_headers, "Location:")) != NULL) { php_url *new_url = php_url_parse(loc); if (new_url != NULL) { @@ -1206,7 +1206,7 @@ bool make_http_soap_request( zval *digest = Z_CLIENT_DIGEST_P(this_ptr); zval *login = Z_CLIENT_LOGIN_P(this_ptr); zval *password = Z_CLIENT_PASSWORD_P(this_ptr); - char *auth = get_http_header_value(ZSTR_VAL(http_headers), "WWW-Authenticate:"); + char *auth = get_http_header_value(http_headers, "WWW-Authenticate:"); if (auth && strstr(auth, "Digest") == auth && Z_TYPE_P(digest) != IS_ARRAY && Z_TYPE_P(login) == IS_STRING && Z_TYPE_P(password) == IS_STRING) { char *s; @@ -1276,7 +1276,7 @@ bool make_http_soap_request( smart_str_free(&soap_headers_z); /* Check and see if the server even sent a xml document */ - content_type = get_http_header_value(ZSTR_VAL(http_headers), "Content-Type:"); + content_type = get_http_header_value(http_headers, "Content-Type:"); if (content_type) { char *pos = NULL; int cmplen; @@ -1306,7 +1306,7 @@ bool make_http_soap_request( } /* Decompress response */ - content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding:"); + content_encoding = get_http_header_value(http_headers, "Content-Encoding:"); if (content_encoding) { zval retval; zval params[1]; @@ -1440,12 +1440,12 @@ static char *get_http_header_value_nodup(char *headers, char *type, size_t *len) return NULL; } -static char *get_http_header_value(char *headers, char *type) +static char *get_http_header_value(zend_string *headers, char *type) { size_t len; char *value; - value = get_http_header_value_nodup(headers, type, &len); + value = get_http_header_value_nodup(ZSTR_VAL(headers), type, &len); if (value) { return estrndup(value, len); @@ -1464,7 +1464,7 @@ static zend_string* get_http_body(php_stream *stream, bool close, zend_string *h size_t http_buf_size = 0; if (!close) { - header = get_http_header_value(ZSTR_VAL(headers), "Connection:"); + header = get_http_header_value(headers, "Connection:"); if (header) { if (!strncasecmp(header, "close", sizeof("close")-1)) { header_close = true; @@ -1472,14 +1472,14 @@ static zend_string* get_http_body(php_stream *stream, bool close, zend_string *h efree(header); } } - header = get_http_header_value(ZSTR_VAL(headers), "Transfer-Encoding:"); + header = get_http_header_value(headers, "Transfer-Encoding:"); if (header) { if (!strncasecmp(header, "chunked", sizeof("chunked")-1)) { header_chunked = true; } efree(header); } - header = get_http_header_value(ZSTR_VAL(headers), "Content-Length:"); + header = get_http_header_value(headers, "Content-Length:"); if (header) { header_length = atoi(header); efree(header); From 1e4db484c33f064cc1a59cbeb980f1180ea26a6a Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 14:46:25 +0100 Subject: [PATCH 11/16] ext/soap/php_http.c: Refactor get_http_header_value_nodup() - Pass lengths to prevent strlen() for known lengths --- ext/soap/php_http.c | 46 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 312b6c6f7ddb9..060a6f52dbd0a 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -19,7 +19,7 @@ #include "php_soap.h" #include "ext/hash/php_hash.h" /* For php_hash_bin2hex() */ -static char *get_http_header_value_nodup(char *headers, char *type, size_t *len); +static const char *get_http_header_value_nodup(const char *headers, size_t headers_len, const char *type, size_t type_len, size_t *len); static char *get_http_header_value(zend_string *headers, char *type); static zend_string *get_http_body(php_stream *stream, bool close, zend_string *headers); static zend_string *get_http_headers(php_stream *stream); @@ -353,8 +353,7 @@ bool make_http_soap_request( int use_proxy = 0; int use_ssl; zend_string *http_body; - char *content_type, *http_version, *cookie_itt; - size_t cookie_len; + char *content_type, *http_version; bool http_close; zend_string *http_headers; char *connection; @@ -1013,34 +1012,36 @@ bool make_http_soap_request( we shouldn't be changing urls so path doesn't matter too much */ - cookie_itt = ZSTR_VAL(http_headers); + const char *cookie_itt = ZSTR_VAL(http_headers); + size_t cookie_len = ZSTR_LEN(http_headers); + size_t parsed_cookie_len; - while ((cookie_itt = get_http_header_value_nodup(cookie_itt, "Set-Cookie:", &cookie_len))) { + while ((cookie_itt = get_http_header_value_nodup(cookie_itt, cookie_len, ZEND_STRL("Set-Cookie:"), &parsed_cookie_len))) { zval *cookies = Z_CLIENT_COOKIES_P(this_ptr); SEPARATE_ARRAY(cookies); - char *cookie = estrndup(cookie_itt, cookie_len); + char *cookie = estrndup(cookie_itt, parsed_cookie_len); char *eqpos = strstr(cookie, "="); char *sempos = strstr(cookie, ";"); if (eqpos != NULL && (sempos == NULL || sempos > eqpos)) { smart_str name = {0}; - int cookie_len; + size_t current_cookie_len; zval zcookie; if (sempos != NULL) { - cookie_len = sempos-(eqpos+1); + current_cookie_len = sempos-(eqpos+1); } else { - cookie_len = strlen(cookie)-(eqpos-cookie)-1; + current_cookie_len = parsed_cookie_len-(eqpos-cookie)-1; } smart_str_appendl(&name, cookie, eqpos - cookie); smart_str_0(&name); array_init(&zcookie); - add_index_stringl(&zcookie, 0, eqpos + 1, cookie_len); + add_index_stringl(&zcookie, 0, eqpos + 1, current_cookie_len); if (sempos != NULL) { - char *options = cookie + cookie_len+1; + char *options = cookie + current_cookie_len+1; while (*options) { while (*options == ' ') {options++;} sempos = strstr(options, ";"); @@ -1076,7 +1077,8 @@ bool make_http_soap_request( smart_str_free(&name); } - cookie_itt = cookie_itt + cookie_len; + cookie_itt = cookie_itt + parsed_cookie_len; + cookie_len -= parsed_cookie_len; efree(cookie); } @@ -1387,24 +1389,22 @@ bool make_http_soap_request( return true; } -static char *get_http_header_value_nodup(char *headers, char *type, size_t *len) +static const char *get_http_header_value_nodup(const char *headers, size_t headers_len, const char *type, size_t type_len, size_t *len) { - char *pos, *tmp = NULL; - int typelen, headerslen; + const char *pos; + const char *tmp = NULL; - typelen = strlen(type); - headerslen = strlen(headers); /* header `titles' can be lower case, or any case combination, according * to the various RFC's. */ pos = headers; do { /* start of buffer or start of line */ - if (strncasecmp(pos, type, typelen) == 0) { - char *eol; + if (strncasecmp(pos, type, type_len) == 0) { + const char *eol; /* match */ - tmp = pos + typelen; + tmp = pos + type_len; /* strip leading whitespace */ while (*tmp == ' ' || *tmp == '\t') { @@ -1413,7 +1413,7 @@ static char *get_http_header_value_nodup(char *headers, char *type, size_t *len) eol = strchr(tmp, '\n'); if (eol == NULL) { - eol = headers + headerslen; + eol = headers + headers_len; } else if (eol > tmp) { if (*(eol-1) == '\r') { eol--; @@ -1443,9 +1443,7 @@ static char *get_http_header_value_nodup(char *headers, char *type, size_t *len) static char *get_http_header_value(zend_string *headers, char *type) { size_t len; - char *value; - - value = get_http_header_value_nodup(ZSTR_VAL(headers), type, &len); + const char *value = get_http_header_value_nodup(ZSTR_VAL(headers), ZSTR_LEN(headers), type, strlen(type), &len); if (value) { return estrndup(value, len); From ca16a225113f2159b2d99dc84bc75692e9bcfafc Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 14:58:47 +0100 Subject: [PATCH 12/16] ext/soap/php_http.c: Fix memory leak of header value --- ext/soap/php_http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 060a6f52dbd0a..e2ecdcfbabd7e 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1160,11 +1160,11 @@ bool make_http_soap_request( if ((loc = get_http_header_value(http_headers, "Location:")) != NULL) { php_url *new_url = php_url_parse(loc); + efree(loc); if (new_url != NULL) { zend_string_release_ex(http_headers, 0); zend_string_release_ex(http_body, 0); - efree(loc); if (new_url->scheme == NULL && new_url->path != NULL) { new_url->scheme = phpurl->scheme ? zend_string_copy(phpurl->scheme) : NULL; new_url->host = phpurl->host ? zend_string_copy(phpurl->host) : NULL; From 239ebf2001c205af634d98df83dfe2dc12f84e62 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 15:13:57 +0100 Subject: [PATCH 13/16] ext/soap/php_http.c: Refactor cookies loop in make_http_soap_request() --- ext/soap/php_http.c | 51 ++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index e2ecdcfbabd7e..ba05837a4cef6 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -870,28 +870,37 @@ bool make_http_soap_request( bool first_cookie = true; smart_str_append_const(&soap_headers, "Cookie: "); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(cookies), key, data) { - if (key && Z_TYPE_P(data) == IS_ARRAY) { - zval *value; - - if ((value = zend_hash_index_find(Z_ARRVAL_P(data), 0)) != NULL && - Z_TYPE_P(value) == IS_STRING) { - zval *tmp; - if (((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 1)) == NULL || - Z_TYPE_P(tmp) != IS_STRING || - strncmp(phpurl->path?ZSTR_VAL(phpurl->path):"/",Z_STRVAL_P(tmp),Z_STRLEN_P(tmp)) == 0) && - ((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 2)) == NULL || - Z_TYPE_P(tmp) != IS_STRING || - in_domain(phpurl->host, Z_STR_P(tmp))) && - (use_ssl || (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 3)) == NULL)) { - if (!first_cookie) { - smart_str_append_const(&soap_headers, "; "); - } - first_cookie = false; - smart_str_append(&soap_headers, key); - smart_str_appendc(&soap_headers, '='); - smart_str_append(&soap_headers, Z_STR_P(value)); - } + if (key == NULL || Z_TYPE_P(data) != IS_ARRAY) { + continue; + } + + zval *value = zend_hash_index_find(Z_ARRVAL_P(data), 0); + if (value == NULL || Z_TYPE_P(value) != IS_STRING) { + continue; + } + + zval *tmp; + if ( + ( + (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 1)) == NULL + || Z_TYPE_P(tmp) != IS_STRING + || strncmp(phpurl->path?ZSTR_VAL(phpurl->path):"/",Z_STRVAL_P(tmp),Z_STRLEN_P(tmp)) == 0 + ) && ( + (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 2)) == NULL + || Z_TYPE_P(tmp) != IS_STRING + || in_domain(phpurl->host, Z_STR_P(tmp)) + ) && ( + use_ssl + || (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 3)) == NULL + ) + ) { + if (!first_cookie) { + smart_str_append_const(&soap_headers, "; "); } + first_cookie = false; + smart_str_append(&soap_headers, key); + smart_str_appendc(&soap_headers, '='); + smart_str_append(&soap_headers, Z_STR_P(value)); } } ZEND_HASH_FOREACH_END(); smart_str_append_const(&soap_headers, "\r\n"); From a99a0eac92e852a327b66b91e38641dfc5046903 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 7 Jul 2025 15:26:16 +0100 Subject: [PATCH 14/16] ext/soap/php_http.c: Reduce repeated HT fetch for identical keys --- ext/soap/php_http.c | 49 +++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index ba05837a4cef6..cf32b67ad0370 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -708,6 +708,14 @@ bool make_http_soap_request( php_hash_bin2hex(cnonce, nonce, sizeof(nonce)); cnonce[32] = 0; + zval *digest_realm = zend_hash_str_find(Z_ARRVAL_P(digest), ZEND_STRL("realm")); + const zend_string *realm = digest_realm && Z_TYPE_P(digest_realm) == IS_STRING ? Z_STR_P(digest_realm) : NULL; + zval *digest_nonce = zend_hash_str_find(Z_ARRVAL_P(digest), ZEND_STRL("nonce")); + const zend_string *nonce_zstr = digest_nonce && Z_TYPE_P(digest_nonce) == IS_STRING ? Z_STR_P(digest_nonce) : NULL; + zval *digest_algorithm = zend_hash_str_find(Z_ARRVAL_P(digest), ZEND_STRL("algorithm")); + const zend_string *algorithm = digest_algorithm && Z_TYPE_P(digest_algorithm) == IS_STRING ? Z_STR_P(digest_algorithm) : NULL; + bool has_qop = zend_hash_str_exists(Z_ARRVAL_P(digest), ZEND_STRL("qop")); + if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nc", sizeof("nc")-1)) != NULL && Z_TYPE_P(tmp) == IS_LONG) { Z_LVAL_P(tmp)++; @@ -720,9 +728,8 @@ bool make_http_soap_request( PHP_MD5Init(&md5ctx); PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(login), Z_STRLEN_P(login)); PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "realm", sizeof("realm")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { - PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + if (realm) { + PHP_MD5Update(&md5ctx, (unsigned char*)ZSTR_VAL(realm), ZSTR_LEN(realm)); } PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); zval *password = Z_CLIENT_PASSWORD_P(this_ptr); @@ -731,16 +738,12 @@ bool make_http_soap_request( } PHP_MD5Final(hash, &md5ctx); make_digest(HA1, hash); - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "algorithm", sizeof("algorithm")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING && - Z_STRLEN_P(tmp) == sizeof("md5-sess")-1 && - stricmp(Z_STRVAL_P(tmp), "md5-sess") == 0) { + if (algorithm && zend_string_equals_literal_ci(algorithm, "md5-sess")) { PHP_MD5Init(&md5ctx); PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32); PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { - PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + if (nonce_zstr) { + PHP_MD5Update(&md5ctx, (unsigned char*)ZSTR_VAL(nonce_zstr), ZSTR_LEN(nonce_zstr)); } PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8); @@ -766,13 +769,11 @@ bool make_http_soap_request( PHP_MD5Init(&md5ctx); PHP_MD5Update(&md5ctx, (unsigned char*)HA1, 32); PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { - PHP_MD5Update(&md5ctx, (unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + if (nonce_zstr) { + PHP_MD5Update(&md5ctx, (unsigned char*)ZSTR_VAL(nonce_zstr), ZSTR_LEN(nonce_zstr)); } PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "qop", sizeof("qop")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { + if (has_qop) { PHP_MD5Update(&md5ctx, (unsigned char*)nc, 8); PHP_MD5Update(&md5ctx, (unsigned char*)":", 1); PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, 8); @@ -787,15 +788,13 @@ bool make_http_soap_request( smart_str_append_const(&soap_headers, "Authorization: Digest username=\""); smart_str_append(&soap_headers, Z_STR_P(login)); - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "realm", sizeof("realm")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { + if (realm) { smart_str_append_const(&soap_headers, "\", realm=\""); - smart_str_append(&soap_headers, Z_STR_P(tmp)); + smart_str_append(&soap_headers, realm); } - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { + if (nonce_zstr) { smart_str_append_const(&soap_headers, "\", nonce=\""); - smart_str_append(&soap_headers, Z_STR_P(tmp)); + smart_str_append(&soap_headers, nonce_zstr); } smart_str_append_const(&soap_headers, "\", uri=\""); if (phpurl->path) { @@ -811,8 +810,7 @@ bool make_http_soap_request( smart_str_appendc(&soap_headers, '#'); smart_str_append(&soap_headers, phpurl->fragment); } - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "qop", sizeof("qop")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { + if (has_qop) { /* TODO: Support for qop=auth-int */ smart_str_append_const(&soap_headers, "\", qop=auth"); smart_str_append_const(&soap_headers, ", nc="); @@ -827,10 +825,9 @@ bool make_http_soap_request( smart_str_append_const(&soap_headers, "\", opaque=\""); smart_str_append(&soap_headers, Z_STR_P(tmp)); } - if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "algorithm", sizeof("algorithm")-1)) != NULL && - Z_TYPE_P(tmp) == IS_STRING) { + if (algorithm) { smart_str_append_const(&soap_headers, "\", algorithm=\""); - smart_str_append(&soap_headers, Z_STR_P(tmp)); + smart_str_append(&soap_headers, algorithm); } smart_str_append_const(&soap_headers, "\"\r\n"); } else { From bd6b61dac273d7c5ff03e2b4a62b68f604a4dd1c Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Tue, 8 Jul 2025 12:39:13 +0100 Subject: [PATCH 15/16] ext/soap/php_http.c: add is_cstr_equals_literal_ci() macro --- ext/soap/php_http.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index cf32b67ad0370..4ae33c430ffe1 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -27,6 +27,9 @@ static zend_string *get_http_headers(php_stream *stream); #define smart_str_append_const(str, const) \ smart_str_appendl(str,const,sizeof(const)-1) +#define is_cstr_equals_literal_ci(str, len, literal) \ + ((len) == sizeof(literal)-1 && strncasecmp((str), "" literal, sizeof(literal)-1) == 0) + /* Proxy HTTP Authentication */ bool proxy_authentication(const zval* this_ptr, smart_str* soap_headers) { @@ -112,25 +115,16 @@ static void http_context_add_header(const char *s, p++; } /* skip some predefined headers */ - if ((name_len != sizeof("host")-1 || - strncasecmp(s, "host", sizeof("host")-1) != 0) && - (name_len != sizeof("connection")-1 || - strncasecmp(s, "connection", sizeof("connection")-1) != 0) && - (name_len != sizeof("user-agent")-1 || - strncasecmp(s, "user-agent", sizeof("user-agent")-1) != 0) && - (name_len != sizeof("content-length")-1 || - strncasecmp(s, "content-length", sizeof("content-length")-1) != 0) && - (name_len != sizeof("content-type")-1 || - strncasecmp(s, "content-type", sizeof("content-type")-1) != 0) && - (!has_cookies || - name_len != sizeof("cookie")-1 || - strncasecmp(s, "cookie", sizeof("cookie")-1) != 0) && - (!has_authorization || - name_len != sizeof("authorization")-1 || - strncasecmp(s, "authorization", sizeof("authorization")-1) != 0) && - (!has_proxy_authorization || - name_len != sizeof("proxy-authorization")-1 || - strncasecmp(s, "proxy-authorization", sizeof("proxy-authorization")-1) != 0)) { + if ( + !is_cstr_equals_literal_ci(s, name_len, "host") + && !is_cstr_equals_literal_ci(s, name_len, "connection") + && !is_cstr_equals_literal_ci(s, name_len, "user-agent") + && !is_cstr_equals_literal_ci(s, name_len, "content-length") + && !is_cstr_equals_literal_ci(s, name_len, "content-type") + && (!has_cookies || !is_cstr_equals_literal_ci(s, name_len, "cookie")) + && (!has_authorization || !is_cstr_equals_literal_ci(s, name_len, "authorization")) + && (!has_proxy_authorization || !is_cstr_equals_literal_ci(s, name_len, "proxy-authorization")) + ) { /* add header */ smart_str_appendl(soap_headers, s, p-s); smart_str_append_const(soap_headers, "\r\n"); From e0c75d43cd7488a4719df742bcd79b59f2ce2db1 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Tue, 8 Jul 2025 12:48:05 +0100 Subject: [PATCH 16/16] ext/soap/php_http.c: Bring variable declaration closer to use site --- ext/soap/php_http.c | 54 +++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 4ae33c430ffe1..b502ec76fd5dc 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -347,15 +347,12 @@ bool make_http_soap_request( int use_proxy = 0; int use_ssl; zend_string *http_body; - char *content_type, *http_version; bool http_close; zend_string *http_headers; - char *connection; bool http_1_1; int http_status; bool content_type_xml = false; zend_long redirect_max = 20; - char *content_encoding; char *http_msg = NULL; bool old_allow_url_fopen; php_stream_context *context = NULL; @@ -957,7 +954,7 @@ bool make_http_soap_request( /* Check to see what HTTP status was sent */ http_1_1 = false; http_status = 0; - http_version = get_http_header_value(http_headers, "HTTP/"); + char *http_version = get_http_header_value(http_headers, "HTTP/"); if (http_version) { char *tmp; @@ -1086,16 +1083,16 @@ bool make_http_soap_request( if (http_1_1) { http_close = false; if (use_proxy && !use_ssl) { - connection = get_http_header_value(http_headers, "Proxy-Connection:"); - if (connection) { - if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { + char *proxy_connection = get_http_header_value(http_headers, "Proxy-Connection:"); + if (proxy_connection) { + if (strncasecmp(proxy_connection, "close", sizeof("close")-1) == 0) { http_close = true; } - efree(connection); + efree(proxy_connection); } } if (!http_close) { - connection = get_http_header_value(http_headers, "Connection:"); + char *connection = get_http_header_value(http_headers, "Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { http_close = true; @@ -1106,16 +1103,16 @@ bool make_http_soap_request( } else { http_close = true; if (use_proxy && !use_ssl) { - connection = get_http_header_value(http_headers, "Proxy-Connection:"); - if (connection) { - if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { + char *proxy_connection = get_http_header_value(http_headers, "Proxy-Connection:"); + if (proxy_connection) { + if (strncasecmp(proxy_connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { http_close = false; } - efree(connection); + efree(proxy_connection); } } if (http_close) { - connection = get_http_header_value(http_headers, "Connection:"); + char *connection = get_http_header_value(http_headers, "Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { http_close = false; @@ -1278,7 +1275,7 @@ bool make_http_soap_request( smart_str_free(&soap_headers_z); /* Check and see if the server even sent a xml document */ - content_type = get_http_header_value(http_headers, "Content-Type:"); + char *content_type = get_http_header_value(http_headers, "Content-Type:"); if (content_type) { char *pos = NULL; int cmplen; @@ -1308,7 +1305,7 @@ bool make_http_soap_request( } /* Decompress response */ - content_encoding = get_http_header_value(http_headers, "Content-Encoding:"); + char *content_encoding = get_http_header_value(http_headers, "Content-Encoding:"); if (content_encoding) { zval retval; zval params[1]; @@ -1455,32 +1452,31 @@ static char *get_http_header_value(zend_string *headers, char *type) static zend_string* get_http_body(php_stream *stream, bool close, zend_string *headers) { zend_string *http_buf = NULL; - char *header; bool header_close = close; bool header_chunked = false; int header_length = 0; size_t http_buf_size = 0; if (!close) { - header = get_http_header_value(headers, "Connection:"); - if (header) { - if (!strncasecmp(header, "close", sizeof("close")-1)) { + char *connection = get_http_header_value(headers, "Connection:"); + if (connection) { + if (!strncasecmp(connection, "close", sizeof("close")-1)) { header_close = true; } - efree(header); + efree(connection); } } - header = get_http_header_value(headers, "Transfer-Encoding:"); - if (header) { - if (!strncasecmp(header, "chunked", sizeof("chunked")-1)) { + char *transfer_encoding = get_http_header_value(headers, "Transfer-Encoding:"); + if (transfer_encoding) { + if (!strncasecmp(transfer_encoding, "chunked", sizeof("chunked")-1)) { header_chunked = true; } - efree(header); + efree(transfer_encoding); } - header = get_http_header_value(headers, "Content-Length:"); - if (header) { - header_length = atoi(header); - efree(header); + char *content_length = get_http_header_value(headers, "Content-Length:"); + if (content_length) { + header_length = atoi(content_length); + efree(content_length); if (!header_length && !header_chunked) { /* Empty response */ return ZSTR_EMPTY_ALLOC();