diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index e23a3eabc2a..0d992a6dd7f 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -3529,6 +3529,10 @@ PHP_METHOD(Phar, offsetExists) } RETURN_TRUE; } else { + /* If the info class is not based on PharFileInfo, directories are not directly instantiable */ + if (UNEXPECTED(!instanceof_function(phar_obj->spl.info_class, phar_ce_entry))) { + RETURN_FALSE; + } RETURN_BOOL(zend_hash_exists(&phar_obj->archive->virtual_dirs, file_name)); } } diff --git a/ext/phar/tests/phar_oo_011.phpt b/ext/phar/tests/phar_oo_011.phpt index 85c7575bcc0..98b4c34bd15 100644 --- a/ext/phar/tests/phar_oo_011.phpt +++ b/ext/phar/tests/phar_oo_011.phpt @@ -13,10 +13,22 @@ $pharconfig = 0; require_once 'files/phar_oo_test.inc'; $phar = new Phar($fname); -$phar->setInfoClass('SplFileObject'); $phar['hi/f.php'] = 'hi'; var_dump(isset($phar['hi'])); +var_dump($phar['hi']); +var_dump(isset($phar['hi/f.php'])); +echo $phar['hi/f.php']; +echo "\n"; + +$phar->setInfoClass('SplFileObject'); +$phar['hi/f.php'] = 'hi'; +var_dump(isset($phar['hi'])); +try { + var_dump($phar['hi']); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} var_dump(isset($phar['hi/f.php'])); echo $phar['hi/f.php']; echo "\n"; @@ -27,7 +39,17 @@ echo "\n"; unlink(__DIR__ . '/files/phar_oo_011.phar.php'); __halt_compiler(); ?> ---EXPECT-- +--EXPECTF-- bool(true) +object(PharFileInfo)#%d (2) { + ["pathName":"SplFileInfo":private]=> + string(%d) "phar://%s/phar_oo_011.phar.php/hi" + ["fileName":"SplFileInfo":private]=> + string(2) "hi" +} +bool(true) +phar://%s/phar_oo_011.phar.php/hi/f.php +bool(false) +LogicException: Cannot use SplFileObject with directories bool(true) hi