Fix GH-8861: correctly handle string lengths in SplFileinfo methods (#8869)

* Fix GH-8861: correctly handle string lengths in \SplFileinfo::getBasename

Co-authored-by: M. Vondano <m-vo@users.noreply.github.com>
This commit is contained in:
George Peter Banyard 2022-06-28 15:42:59 +01:00 committed by GitHub
parent 63c7418b91
commit 9bae9ab3a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 263 additions and 6 deletions

View file

@ -651,14 +651,17 @@ static inline HashTable *spl_filesystem_object_get_debug_info(zend_object *objec
pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "fileName", sizeof("fileName")-1);
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)) {
/* +1 to skip the trailing / of the path in the file name */
ZVAL_STRINGL(&tmp, ZSTR_VAL(intern->file_name) + ZSTR_LEN(path) + 1, ZSTR_LEN(intern->file_name) - (ZSTR_LEN(path) + 1));
} else {
ZVAL_STR_COPY(&tmp, intern->file_name);
}
zend_symtable_update(rv, pnstr, &tmp);
zend_string_release_ex(pnstr, /* persistent */ false);
zend_string_release_ex(path, /* persistent */ false);
if (path) {
zend_string_release_ex(path, /* persistent */ false);
}
}
if (intern->type == SPL_FS_DIR) {
#ifdef HAVE_GLOB
@ -920,9 +923,11 @@ PHP_METHOD(SplFileInfo, getFilename)
path = spl_filesystem_object_get_path(intern);
if (path && ZSTR_LEN(path) < ZSTR_LEN(intern->file_name)) {
size_t path_len = ZSTR_LEN(path);
RETVAL_STRINGL(ZSTR_VAL(intern->file_name) + path_len + 1, ZSTR_LEN(intern->file_name) - (path_len + 1));
ZEND_ASSERT(path);
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 */
size_t path_len = ZSTR_LEN(path) + 1;
RETVAL_STRINGL(ZSTR_VAL(intern->file_name) + path_len, ZSTR_LEN(intern->file_name) - path_len);
} else {
RETVAL_STR_COPY(intern->file_name);
}
@ -1037,7 +1042,8 @@ PHP_METHOD(SplFileInfo, getBasename)
path = spl_filesystem_object_get_path(intern);
if (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 */
fname = ZSTR_VAL(intern->file_name) + ZSTR_LEN(path) + 1;
flen = ZSTR_LEN(intern->file_name) - (ZSTR_LEN(path) + 1);
} else {

View file

@ -0,0 +1,115 @@
--TEST--
Check Glob iterator is okay with SplFileInfo getPath method calls
--FILE--
<?php
$o = new GlobIterator(__DIR__.'/*.abcdefghij');
echo "Test getATime()\n";
var_dump($o->getATime());
echo "Test getBasename()\n";
var_dump($o->getBasename());
echo "Test getCTime()\n";
var_dump($o->getCTime());
echo "Test getExtension()\n";
var_dump($o->getExtension());
echo "Test getFilename()\n";
var_dump($o->getFilename());
echo "Test getGroup()\n";
var_dump($o->getGroup());
echo "Test getInode()\n";
var_dump($o->getInode());
echo "Test getMTime()\n";
var_dump($o->getMTime());
echo "Test getOwner()\n";
var_dump($o->getOwner());
echo "Test getPath()\n";
var_dump($o->getPath());
echo "Test getPathInfo()\n";
var_dump($o->getPathInfo());
echo "Test getPathname()\n";
var_dump($o->getPathname());
echo "Test getPerms()\n";
var_dump($o->getPerms());
echo "Test getRealPath()\n";
var_dump($o->getRealPath());
echo "Test getSize()\n";
var_dump($o->getSize());
echo "Test getType()\n";
var_dump($o->getType());
echo "Test isDir()\n";
var_dump($o->isDir());
echo "Test isExecutable()\n";
var_dump($o->isExecutable());
echo "Test isFile()\n";
var_dump($o->isFile());
echo "Test isLink()\n";
var_dump($o->isLink());
echo "Test isReadable()\n";
var_dump($o->isReadable());
echo "Test isWritable()\n";
var_dump($o->isWritable());
echo "Test __toString()\n";
var_dump($o->__toString());
echo "Test __debugInfo()\n";
var_dump($o);
?>
--EXPECTF--
Test getATime()
bool(false)
Test getBasename()
string(0) ""
Test getCTime()
bool(false)
Test getExtension()
string(0) ""
Test getFilename()
string(0) ""
Test getGroup()
bool(false)
Test getInode()
bool(false)
Test getMTime()
bool(false)
Test getOwner()
bool(false)
Test getPath()
string(0) ""
Test getPathInfo()
NULL
Test getPathname()
string(0) ""
Test getPerms()
bool(false)
Test getRealPath()
string(%d) "%s"
Test getSize()
bool(false)
Test getType()
bool(false)
Test isDir()
bool(false)
Test isExecutable()
bool(false)
Test isFile()
bool(false)
Test isLink()
bool(false)
Test isReadable()
bool(false)
Test isWritable()
bool(false)
Test __toString()
string(0) ""
Test __debugInfo()
object(GlobIterator)#1 (4) {
["pathName":"SplFileInfo":private]=>
string(0) ""
["fileName":"SplFileInfo":private]=>
string(0) ""
["glob":"DirectoryIterator":private]=>
string(%d) "glob://%s"
["subPathName":"RecursiveDirectoryIterator":private]=>
string(0) ""
}

View file

@ -0,0 +1,86 @@
--TEST--
SPL: SplFileInfo::_debugInfo() basic test
--FILE--
<?php
// without $suffix
var_dump(new \SplFileInfo('/path/to/a.txt'));
var_dump(new \SplFileInfo('path/to/b'));
var_dump(new \SplFileInfo('c.txt'));
var_dump(new \SplFileInfo('d'));
var_dump(new \SplFileInfo('~/path/to//e'));
// with $suffix
var_dump(new \SplFileInfo('path/to/a.txt'));
var_dump(new \SplFileInfo('path/to/bbb.txt'));
var_dump(new \SplFileInfo('path/to/ccc.txt'));
var_dump(new \SplFileInfo('d.txt'));
var_dump(new \SplFileInfo('e.txt'));
var_dump(new \SplFileInfo('f'));
?>
--EXPECT--
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(14) "/path/to/a.txt"
["fileName":"SplFileInfo":private]=>
string(5) "a.txt"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(9) "path/to/b"
["fileName":"SplFileInfo":private]=>
string(1) "b"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(5) "c.txt"
["fileName":"SplFileInfo":private]=>
string(5) "c.txt"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(1) "d"
["fileName":"SplFileInfo":private]=>
string(1) "d"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(12) "~/path/to//e"
["fileName":"SplFileInfo":private]=>
string(1) "e"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(13) "path/to/a.txt"
["fileName":"SplFileInfo":private]=>
string(5) "a.txt"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(15) "path/to/bbb.txt"
["fileName":"SplFileInfo":private]=>
string(7) "bbb.txt"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(15) "path/to/ccc.txt"
["fileName":"SplFileInfo":private]=>
string(7) "ccc.txt"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(5) "d.txt"
["fileName":"SplFileInfo":private]=>
string(5) "d.txt"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(5) "e.txt"
["fileName":"SplFileInfo":private]=>
string(5) "e.txt"
}
object(SplFileInfo)#1 (2) {
["pathName":"SplFileInfo":private]=>
string(1) "f"
["fileName":"SplFileInfo":private]=>
string(1) "f"
}

View file

@ -0,0 +1,32 @@
--TEST--
SPL: SplFileInfo::getBasename() basic test
--FILE--
<?php
// without $suffix
echo (new \SplFileInfo('/path/to/a.txt'))->getBasename() . PHP_EOL;
echo (new \SplFileInfo('path/to/b'))->getBasename() . PHP_EOL;
echo (new \SplFileInfo('c.txt'))->getBasename() . PHP_EOL;
echo (new \SplFileInfo('d'))->getBasename() . PHP_EOL;
echo (new \SplFileInfo('~/path/to//e'))->getBasename() . PHP_EOL . PHP_EOL;
// with $suffix
echo (new \SplFileInfo('path/to/a.txt'))->getBasename('.txt') . PHP_EOL;
echo (new \SplFileInfo('path/to/bbb.txt'))->getBasename('b.txt') . PHP_EOL;
echo (new \SplFileInfo('path/to/ccc.txt'))->getBasename('to/ccc.txt') . PHP_EOL;
echo (new \SplFileInfo('d.txt'))->getBasename('txt') . PHP_EOL;
echo (new \SplFileInfo('e.txt'))->getBasename('e.txt') . PHP_EOL;
echo (new \SplFileInfo('f'))->getBasename('.txt');
?>
--EXPECT--
a.txt
b
c.txt
d
e
a
bb
ccc.txt
d.
e.txt
f

View file

@ -0,0 +1,18 @@
--TEST--
SPL: SplFileInfo::getFilename() basic test
--FILE--
<?php
echo (new \SplFileInfo('/path/to/a.txt'))->getFilename() . PHP_EOL;
echo (new \SplFileInfo('path/to/b'))->getFilename() . PHP_EOL;
echo (new \SplFileInfo('c.txt'))->getFilename() . PHP_EOL;
echo (new \SplFileInfo('d'))->getFilename() . PHP_EOL;
echo (new \SplFileInfo('~/path/to//e'))->getFilename() . PHP_EOL . PHP_EOL;
?>
--EXPECT--
a.txt
b
c.txt
d
e