[php-src] master: Merge branch 'PHP-8.5'

David Carlier <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: David Carlier (devnexen)
Date: 2026-08-30T15:27:14+01:00

Commit: https://github.com/php/php-src/commit/c09c2e98b374a78a126d1dc39057ab2ab3538e9b
Raw diff: https://github.com/php/php-src/commit/c09c2e98b374a78a126d1dc39057ab2ab3538e9b.diff

Merge branch 'PHP-8.5'

* PHP-8.5:
  ext/zip: php_zip_ops_stat() succeeds when the archive cannot be opened.
  ext/zip: ZipArchive::getNameIndex() index truncated to int.

Changed paths:
  A  ext/zip/tests/oo_getnameindex_large_index.phpt
  A  ext/zip/tests/stream_fstat_unreadable_archive.phpt
  M  ext/zip/php_zip.c
  M  ext/zip/zip_stream.c


Diff:

diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index a7a3e340ecf1..15994b60cc70 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -2197,7 +2197,7 @@ PHP_METHOD(ZipArchive, getNameIndex)
 
 	ZIP_FROM_OBJECT(intern, self);
 
-	name = zip_get_name(intern, (int) index, flags);
+	name = zip_get_name(intern, (zip_uint64_t) index, flags);
 
 	if (name) {
 		RETVAL_STRING((char *)name);
diff --git a/ext/zip/tests/oo_getnameindex_large_index.phpt b/ext/zip/tests/oo_getnameindex_large_index.phpt
new file mode 100644
index 000000000000..471dffc38d91
--- /dev/null
+++ b/ext/zip/tests/oo_getnameindex_large_index.phpt
@@ -0,0 +1,44 @@
+--TEST--
+ZipArchive::getNameIndex() with an index that does not fit in an int
+--EXTENSIONS--
+zip
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE != 8) die('skip 64-bit only');
+?>
+--FILE--
+<?php
+$file = __DIR__ . '/oo_getnameindex_large_index.zip';
+
+@unlink($file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file, ZipArchive::CREATE)) {
+    exit('failed');
+}
+
+$zip->addFromString('entry1.txt', 'entry #1');
+$zip->close();
+
+if (!$zip->open($file)) {
+    exit('failed');
+}
+
+var_dump($zip->getNameIndex(0));
+var_dump($zip->getNameIndex(1 << 32));
+var_dump($zip->getNameIndex((1 << 32) + 1));
+var_dump($zip->getNameIndex(PHP_INT_MAX));
+var_dump($zip->getNameIndex(-1));
+
+$zip->close();
+?>
+--EXPECT--
+string(10) "entry1.txt"
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+--CLEAN--
+<?php
+unlink(__DIR__ . '/oo_getnameindex_large_index.zip');
+?>
diff --git a/ext/zip/tests/stream_fstat_unreadable_archive.phpt b/ext/zip/tests/stream_fstat_unreadable_archive.phpt
new file mode 100644
index 000000000000..a81fc8fc3cfc
--- /dev/null
+++ b/ext/zip/tests/stream_fstat_unreadable_archive.phpt
@@ -0,0 +1,38 @@
+--TEST--
+fstat() on a zip:// stream whose archive can no longer be opened
+--EXTENSIONS--
+zip
+--SKIPIF--
+<?php
+if (PHP_OS_FAMILY === 'Windows') die('skip the archive cannot be rewritten while it is open');
+?>
+--FILE--
+<?php
+$file = __DIR__ . '/stream_fstat_unreadable_archive.zip';
+
+@unlink($file);
+
+$zip = new ZipArchive;
+if (!$zip->open($file, ZipArchive::CREATE)) {
+    exit('failed');
+}
+
+$zip->addFromString('entry.txt', 'entry');
+$zip->close();
+
+$fp = fopen('zip://' . $file . '#entry.txt', 'rb');
+var_dump($fp !== false);
+
+file_put_contents($file, 'this is not a zip archive');
+
+var_dump(fstat($fp));
+
+fclose($fp);
+?>
+--EXPECT--
+bool(true)
+bool(false)
+--CLEAN--
+<?php
+unlink(__DIR__ . '/stream_fstat_unreadable_archive.zip');
+?>
diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c
index a6665630e350..429342b36e3d 100644
--- a/ext/zip/zip_stream.c
+++ b/ext/zip/zip_stream.c
@@ -192,6 +192,9 @@ static int php_zip_ops_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{
 		ssb->sb.st_blocks = -1;
 #endif
 		ssb->sb.st_ino = -1;
+	} else {
+		zend_string_release_ex(file_basename, 0);
+		return -1;
 	}
 	zend_string_release_ex(file_basename, false);
 	return 0;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.