diff --git a/NEWS b/NEWS index 7dd1aea4b881..39f2359152f0 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,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-22360 (convert.base64-encode corruption on diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index f83ea9f84aca..eb3fb8caef64 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -2224,6 +2224,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); @@ -2376,6 +2378,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-- +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