Commit 600e4a84458 for php.net

commit 600e4a84458dde1cf7a508697c87af9fb15d669d
Author: Weilin Du <weilindu@php.net>
Date:   Fri Aug 14 17:01:16 2026 +0800

    tree-wide: Refactor with `zend_string_ends_with*` (#23216)

diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index 4d3081a3b07..468055732e1 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.c
@@ -1015,7 +1015,7 @@ PHP_FUNCTION(odbc_execute)

 			if (ZSTR_LEN(tmpstr) > 2 &&
 				ZSTR_VAL(tmpstr)[0] == '\'' &&
-				ZSTR_VAL(tmpstr)[ZSTR_LEN(tmpstr) - 1] == '\'') {
+				zend_string_ends_with_literal(tmpstr, "'")) {

 				if (UNEXPECTED(zend_str_has_nul_byte(tmpstr))) {
 					odbc_release_params(result, params);
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index cf62765d9e1..96bf83a3552 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -1519,8 +1519,8 @@ static void zend_accel_add_key(zend_string *key, zend_accel_hash_entry *bucket)

 static zend_always_inline bool is_phar_file(const zend_string *filename)
 {
-	return filename && ZSTR_LEN(filename) >= sizeof(".phar") &&
-		!memcmp(ZSTR_VAL(filename) + ZSTR_LEN(filename) - (sizeof(".phar")-1), ".phar", sizeof(".phar")-1) &&
+	return filename &&
+		zend_string_ends_with_literal(filename, ".phar") &&
 		!strstr(ZSTR_VAL(filename), "://");
 }

diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index 3a1b4a04caf..9f0ca2c1a5e 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -3427,13 +3427,13 @@ static zend_result pgsql_copy_from_query(PGconn *pgsql, PGresult *pgsql_result,
 	}

 	int result;
-	if (ZSTR_LEN(tmp) > 0 && ZSTR_VAL(tmp)[ZSTR_LEN(tmp) - 1] != '\n') {
+	if (ZSTR_LEN(tmp) == 0 || zend_string_ends_with_literal(tmp, "\n")) {
+		result = PQputCopyData(pgsql, ZSTR_VAL(tmp), ZSTR_LEN(tmp));
+	} else {
 		char *zquery = zend_cstr_append_char(
 			ZSTR_VAL(tmp), ZSTR_LEN(tmp), '\n');
 		result = PQputCopyData(pgsql, zquery, ZSTR_LEN(tmp) + 1);
 		efree(zquery);
-	} else {
-		result = PQputCopyData(pgsql, ZSTR_VAL(tmp), ZSTR_LEN(tmp));
 	}

 	zend_tmp_string_release(tmp_tmp);
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 8a330a954b8..2fc17e7b9ce 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -4251,7 +4251,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 3, 5) static int extract_helper(const phar_archiv
 			if (FAILURE == phar_extract_file(overwrite, entry, path_to, error)) return -1;
 			extracted++;
 		} ZEND_HASH_FOREACH_END();
-	} else if (ZSTR_LEN(search) > 0 && '/' == ZSTR_VAL(search)[ZSTR_LEN(search) - 1]) {
+	} else if (zend_string_ends_with_literal(search, "/")) {
 		/* ends in "/" -- extract all entries having that prefix */
 		ZEND_HASH_MAP_FOREACH_PTR(&archive->manifest, entry) {
 			if (!zend_string_starts_with(entry->filename, search)) continue;
diff --git a/ext/session/session.c b/ext/session/session.c
index cb951c6d60e..452a3446fc1 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -876,7 +876,7 @@ static PHP_INI_MH(OnUpdateRfc1867Freq)
 		return FAILURE;
 	}

-	if (ZSTR_LEN(new_value) > 0 && ZSTR_VAL(new_value)[ZSTR_LEN(new_value) - 1] == '%') {
+	if (zend_string_ends_with_literal(new_value, "%")) {
 		if (new_freq > 100) {
 			php_error_docref(NULL, E_WARNING, "session.upload_progress.freq must be less than or equal to 100%%");
 			return FAILURE;
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index b49acd947b3..5df9506102a 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -341,13 +341,9 @@ static php_stream* http_connect(zval* this_ptr, php_uri *uri, bool use_ssl, php_
 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 zend_string_equals_cstr(domain, ZSTR_VAL(host) + ZSTR_LEN(host) - ZSTR_LEN(domain), ZSTR_LEN(domain));
-		} else {
-			return false;
-		}
+		return zend_string_ends_with(host, domain);
 	} else {
-		return zend_string_equals(host,domain);
+		return zend_string_equals(host, domain);
 	}
 }