[php-src] master: ext/zip: ZipArchive::getNameIndex() index truncated to int.

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

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

ext/zip: ZipArchive::getNameIndex() index truncated to int.

The index was cast to int before being handed to zip_get_name(), whose
parameter is a zip_uint64_t, so any value with a non-zero upper half
wrapped and selected the wrong entry: getNameIndex(1 << 32) returned the
name of entry 0 instead of false. Cast to zip_uint64_t instead, letting
libzip reject out of range indices.

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


Diff:

diff --git a/NEWS b/NEWS
index 04adab59625e..aa7862f63bb4 100644
--- a/NEWS
+++ b/NEWS
@@ -80,6 +80,8 @@ PHP                                                                        NEWS
     garbage collected). (Weilin Du, ndossche)
   . Fixed ZipArchive::extractTo() and ZipArchive::getFrom*() reporting success
     on corrupted entries. (David Carlier)
+  . Fixed ZipArchive::getNameIndex() truncating the entry index to int.
+    (David Carlier)
 
 - SAPI:
   . Fixed fuzzer targets failing to build in isolation. (Mrmaxmeier)
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index 5e640df9a102..69b81b88753d 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -2181,7 +2181,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');
+?>
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.