Commit 324b3baea5f for php.net

commit 324b3baea5ff09b18215e432ab51dad94fbf6546
Merge: 90e3132656c 403bf75d832
Author: Weilin Du <weilindu@php.net>
Date:   Tue Jun 23 23:43:37 2026 +0800

    Merge branch 'PHP-8.5'

    * PHP-8.5:
      ext/phar: Fix .phar-prefixed non-magic directory handling (#22372)

diff --cc ext/phar/phar_internal.h
index d75498f9c95,eaea68dbbe5..f175fb7b9d6
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@@ -376,22 -380,48 +376,47 @@@ static inline bool phar_validate_alias(
  }
  /* }}} */

+ static inline bool phar_path_is_magic_phar_ex(const char *path, size_t path_len) /* {{{ */
+ {
+ 	if (path_len > 0 && path[0] == '/') {
+ 		path++;
+ 		path_len--;
+ 	}
+
+ 	if (path_len < sizeof(".phar") - 1 || memcmp(path, ".phar", sizeof(".phar") - 1) != 0) {
+ 		return false;
+ 	}
+
+ 	if (path_len == sizeof(".phar") - 1) {
+ 		return true;
+ 	}
+
+ 	return path[sizeof(".phar") - 1] == '/' || path[sizeof(".phar") - 1] == '\\';
+ }
+ /* }}} */
+
+ static inline bool phar_is_magic_phar(const zend_string *path) /* {{{ */
+ {
+ 	return phar_path_is_magic_phar_ex(ZSTR_VAL(path), ZSTR_LEN(path));
+ }
+ /* }}} */
+
  static inline void phar_set_inode(phar_entry_info *entry) /* {{{ */
  {
 -	char tmp[MAXPATHLEN];
 -	size_t tmp_len;
 -	size_t len1, len2;
 -
 -	tmp_len = MIN(MAXPATHLEN, ZSTR_LEN(entry->filename) + entry->phar->fname_len);
 -
 -	len1 = MIN(entry->phar->fname_len, tmp_len);
  	if (entry->phar->fname) {
 -		memcpy(tmp, entry->phar->fname, len1);
 -	}
 +		char tmp[MAXPATHLEN];
 +		size_t tmp_len = MIN(MAXPATHLEN, ZSTR_LEN(entry->filename) + ZSTR_LEN(entry->phar->fname));

 -	len2 = MIN(tmp_len - len1, ZSTR_LEN(entry->filename));
 -	memcpy(tmp + len1, entry->filename, len2);
 +		size_t len1 = MIN(ZSTR_LEN(entry->phar->fname), tmp_len);
 +		memcpy(tmp, ZSTR_VAL(entry->phar->fname), len1);

 -	entry->inode = (unsigned short) zend_hash_func(tmp, tmp_len);
 +		size_t len2 = MIN(tmp_len - len1, ZSTR_LEN(entry->filename));
 +		memcpy(tmp + len1, entry->filename, len2);
 +
 +		entry->inode = (unsigned short) zend_hash_func(tmp, tmp_len);
 +	} else {
 +		entry->inode = (unsigned short) zend_string_hash_val(entry->filename);
 +	}
  }
  /* }}} */

diff --cc ext/phar/phar_object.c
index 46db925cfd5,8e7155bacf4..e2ba71c501e
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@@ -3401,17 -3468,17 +3401,17 @@@ PHP_METHOD(Phar, copy
  		RETURN_THROWS();
  	}

- 	if (zend_string_starts_with_literal(old_file, ".phar")) {
+ 	if (phar_is_magic_phar(old_file)) {
  		/* can't copy a meta file */
  		zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0,
 -			"file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname);
 +			"file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname));
  		RETURN_THROWS();
  	}

- 	if (zend_string_starts_with_literal(new_file, ".phar")) {
+ 	if (phar_is_magic_phar(new_file)) {
  		/* can't copy a meta file */
  		zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0,
 -			"file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname);
 +			"file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname));
  		RETURN_THROWS();
  	}