Fix GH-12721: SplFileInfo::getFilename() segfault in combination with GlobIterator and no directory separator

This broke in 7cd8879 and 9bae9ab. NULL is a perfectly valid return
value that should be handled.

Closes GH-12722.
This commit is contained in:
Niels Dossche 2023-11-18 23:50:53 +01:00
parent f90b40416f
commit 4d41dffb4f
3 changed files with 65 additions and 5 deletions

4
NEWS
View file

@ -22,6 +22,10 @@ PHP NEWS
- PHPDBG: - PHPDBG:
. Fixed bug GH-12675 (MEMORY_LEAK in phpdbg_prompt.c). (nielsdos) . Fixed bug GH-12675 (MEMORY_LEAK in phpdbg_prompt.c). (nielsdos)
- SPL:
. Fixed bug GH-12721 (SplFileInfo::getFilename() segfault in combination
with GlobIterator and no directory separator). (nielsdos)
- SQLite3: - SQLite3:
. Fixed bug GH-12633 (sqlite3_defensive.phpt fails with sqlite 3.44.0). . Fixed bug GH-12633 (sqlite3_defensive.phpt fails with sqlite 3.44.0).
(SakiTakamachi) (SakiTakamachi)

View file

@ -925,7 +925,6 @@ PHP_METHOD(SplFileInfo, getFilename)
path = spl_filesystem_object_get_path(intern); path = spl_filesystem_object_get_path(intern);
ZEND_ASSERT(path);
if (path && ZSTR_LEN(path) && ZSTR_LEN(path) < ZSTR_LEN(intern->file_name)) { if (path && ZSTR_LEN(path) && ZSTR_LEN(path) < ZSTR_LEN(intern->file_name)) {
/* +1 to skip the trailing / of the path in the file name */ /* +1 to skip the trailing / of the path in the file name */
size_t path_len = ZSTR_LEN(path) + 1; size_t path_len = ZSTR_LEN(path) + 1;
@ -933,7 +932,9 @@ PHP_METHOD(SplFileInfo, getFilename)
} else { } else {
RETVAL_STR_COPY(intern->file_name); RETVAL_STR_COPY(intern->file_name);
} }
zend_string_release_ex(path, /* persistent */ false); if (path) {
zend_string_release_ex(path, /* persistent */ false);
}
} }
/* }}} */ /* }}} */
@ -973,14 +974,16 @@ PHP_METHOD(SplFileInfo, getExtension)
path = spl_filesystem_object_get_path(intern); path = spl_filesystem_object_get_path(intern);
if (ZSTR_LEN(path) && ZSTR_LEN(path) < ZSTR_LEN(intern->file_name)) { if (path && ZSTR_LEN(path) && ZSTR_LEN(path) < ZSTR_LEN(intern->file_name)) {
fname = ZSTR_VAL(intern->file_name) + ZSTR_LEN(path) + 1; fname = ZSTR_VAL(intern->file_name) + ZSTR_LEN(path) + 1;
flen = ZSTR_LEN(intern->file_name) - (ZSTR_LEN(path) + 1); flen = ZSTR_LEN(intern->file_name) - (ZSTR_LEN(path) + 1);
} else { } else {
fname = ZSTR_VAL(intern->file_name); fname = ZSTR_VAL(intern->file_name);
flen = ZSTR_LEN(intern->file_name); flen = ZSTR_LEN(intern->file_name);
} }
zend_string_release_ex(path, /* persistent */ false); if (path) {
zend_string_release_ex(path, /* persistent */ false);
}
ret = php_basename(fname, flen, NULL, 0); ret = php_basename(fname, flen, NULL, 0);
@ -1052,7 +1055,9 @@ PHP_METHOD(SplFileInfo, getBasename)
fname = ZSTR_VAL(intern->file_name); fname = ZSTR_VAL(intern->file_name);
flen = ZSTR_LEN(intern->file_name); flen = ZSTR_LEN(intern->file_name);
} }
zend_string_release_ex(path, /* persistent */ false); if (path) {
zend_string_release_ex(path, /* persistent */ false);
}
RETURN_STR(php_basename(fname, flen, suffix, slen)); RETURN_STR(php_basename(fname, flen, suffix, slen));
} }

View file

@ -0,0 +1,51 @@
--TEST--
GH-12721 (SplFileInfo::getFilename() segfault in combination with GlobIterator and no directory separator)
--FILE--
<?php
file_put_contents('file1.gh12721', 'hello');
echo "--- No slash ---\n";
foreach (new GlobIterator('*.gh12721') as $fileInfo) {
echo $fileInfo->getFilename(), "\n";
echo $fileInfo->getExtension(), "\n";
echo $fileInfo->getBasename(), "\n";
var_dump($fileInfo->getFileInfo());
}
echo "--- With slash ---\n";
foreach (new GlobIterator('./*.gh12721') as $fileInfo) {
echo $fileInfo->getFilename(), "\n";
echo $fileInfo->getExtension(), "\n";
echo $fileInfo->getBasename(), "\n";
var_dump($fileInfo->getFileInfo());
}
?>
--CLEAN--
<?php
@unlink('file1.gh12721');
?>
--EXPECTF--
--- No slash ---
file1.gh12721
gh12721
file1.gh12721
object(SplFileInfo)#4 (2) {
["pathName":"SplFileInfo":private]=>
string(13) "file1.gh12721"
["fileName":"SplFileInfo":private]=>
string(13) "file1.gh12721"
}
--- With slash ---
file1.gh12721
gh12721
file1.gh12721
object(SplFileInfo)#3 (2) {
["pathName":"SplFileInfo":private]=>
string(15) "%sfile1.gh12721"
["fileName":"SplFileInfo":private]=>
string(13) "file1.gh12721"
}