Commit 80b13459a4e for php

commit 80b13459a4e2fad667841676685fd045f898ddb1
Merge: eefe4db40ed ac1a9c18137
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Fri Oct 9 07:15:39 2026 -0400

    Merge branch 'PHP-8.5' into PHP-8.6

    * PHP-8.5:
      ext/standard: Validate the bcrypt cost before reading it

diff --cc NEWS
index 618ecace1ae,8561f853ec9..44176bcb54f
--- a/NEWS
+++ b/NEWS
@@@ -19,13 -19,9 +19,15 @@@ PH
    . Fix too wide type inference for ASSIGN_DIM_OP. (ndossche)
    . Fix OSS-Fuzz #568005340 (FETCH_DIM_FUNC_ARG partial conversion). (ndossche)

 +- Phar:
 +  . Fixed GH-24166 (Double-free in Phar::webPhar() in CGI without PATH_INFO).
 +    (RigelYoung, Jakub Zelenka)
 +
  - Standard:
 +  . Fixed chown() and lchown() failing to resolve user names in ZTS builds
 +    when getpwnam_r() needs a larger buffer. (Ilia Alshanetsky)
+   . Fixed password_get_info() and password_needs_rehash() accepting malformed
+     bcrypt costs. (Ilia Alshanetsky)

  - Zip:
    . Fixed use-after-free when re-entering ZipArchive during destruction or
diff --cc ext/standard/password.c
index a28ceb7e0ce,9dcd8070b76..21e483bc344
--- a/ext/standard/password.c
+++ b/ext/standard/password.c
@@@ -133,15 -147,13 +145,13 @@@ static int php_password_bcrypt_get_info

  static bool php_password_bcrypt_needs_rehash(const zend_string *hash, zend_array *options) {
  	zval *znew_cost;
- 	zend_long old_cost = PHP_PASSWORD_BCRYPT_COST;
+ 	zend_long old_cost;
  	zend_long new_cost = PHP_PASSWORD_BCRYPT_COST;

- 	if (!php_password_bcrypt_valid(hash)) {
+ 	if (!php_password_bcrypt_get_cost(hash, &old_cost)) {
  		/* Should never get called this way. */
 -		return 1;
 +		return true;
  	}
-
- 	sscanf(ZSTR_VAL(hash), "$2y$" ZEND_LONG_FMT "$", &old_cost);
  	if (options && (znew_cost = zend_hash_str_find(options, "cost", sizeof("cost")-1)) != NULL) {
  		new_cost = zval_get_long(znew_cost);
  	}