[php-src] PHP-8.5: Merge branch 'PHP-8.4' into PHP-8.5

Ilia Alshanetsky <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-06-25T18:22:04-04:00

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

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  Guard uninitialized SplFileObject in fputcsv() and next()

Changed paths:
  A  ext/spl/tests/gh16217.phpt
  M  NEWS
  M  ext/spl/spl_directory.c


Diff:

diff --git a/NEWS b/NEWS
index 478136540a51..4a08f3391d77 100644
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,8 @@ PHP                                                                        NEWS
     (jorgsowa)
   . Ignore leading back-slash in class_parents(), class_implements(), and
     class_uses(). (jorgsowa)
+  . Fixed bug GH-16217 (SplFileObject::fputcsv() on an uninitialized object
+    segfaults). (iliaal)
 
 - Standard:
   . Fixed bug GH-22395 (base_convert() outputs at most 64 characters).
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index a73f68c9d3b7..c0b0f6ef7c92 100644
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -2210,6 +2210,8 @@ PHP_METHOD(SplFileObject, next)
 		RETURN_THROWS();
 	}
 
+	CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern);
+
 	spl_filesystem_file_free_line(intern);
 	if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
 		spl_filesystem_file_read_line(ZEND_THIS, intern, true);
@@ -2362,6 +2364,8 @@ PHP_METHOD(SplFileObject, fputcsv)
 		RETURN_THROWS();
 	}
 
+	CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern);
+
 	if (delim) {
 		if (d_len != 1) {
 			zend_argument_value_error(2, "must be a single character");
diff --git a/ext/spl/tests/gh16217.phpt b/ext/spl/tests/gh16217.phpt
new file mode 100644
index 000000000000..71760389c8e4
--- /dev/null
+++ b/ext/spl/tests/gh16217.phpt
@@ -0,0 +1,35 @@
+--TEST--
+GH-16217 (SplFileObject methods on an uninitialized object segfault)
+--FILE--
+<?php
+function uninitialized(): SplFileObject {
+    return (new ReflectionClass(SplFileObject::class))->newInstanceWithoutConstructor();
+}
+
+try {
+    (new ReflectionMethod(SplFileObject::class, "fputcsv"))->invoke(uninitialized(), []);
+} catch (Error $e) {
+    echo "fputcsv: ", $e->getMessage(), "\n";
+}
+
+try {
+    (new ReflectionMethod(SplFileObject::class, "next"))->invoke(uninitialized());
+} catch (Error $e) {
+    echo "next: ", $e->getMessage(), "\n";
+}
+
+$obj = uninitialized();
+(new ReflectionMethod(SplFileObject::class, "setFlags"))->invoke($obj, SplFileObject::READ_AHEAD);
+try {
+    (new ReflectionMethod(SplFileObject::class, "next"))->invoke($obj);
+} catch (Error $e) {
+    echo "next (READ_AHEAD): ", $e->getMessage(), "\n";
+}
+
+echo "Done\n";
+?>
+--EXPECT--
+fputcsv: Object not initialized
+next: Object not initialized
+next (READ_AHEAD): Object not initialized
+Done
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.