Description
Symfony version(s) affected
7.2.6
Description
In symfony/cache/Adapter/PhpFilesAdapter.php
, at line 141, in doFetch()
method,
a segmentation fault occurs when the cache file is missing with:
- PHP 8.4.7,
- PHPUnit 10.5.46,
The fault code is:
} elseif (\is_array($expiresAt = include $file)) {
$file
point to a missing file (/workspace/app/var/cache/test/pools/system/-XrFvDfXQZ/S/4/TeAQe6FJPBowgagyN1fA
).
How to reproduce
No real idea. The issue occurs in a complex context. May be trying to delete the cache before calling doFetch()
.
The issue occurs in PHPUnit integration tests, with this bootsrap:
declare(strict_types=1);
use App\Tests\SymfonyConsolerRunner;
use Symfony\Component\Dotenv\Dotenv;
require dirname(__DIR__).'/vendor/autoload.php';
if (method_exists(Dotenv::class, 'bootEnv')) { // @phpstan-ignore-line
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
}
if ('' !== ($_SERVER['APP_DEBUG'] ?? '')) {
umask(0000);
}
$symfonyConsolerRunner = new SymfonyConsolerRunner(sprintf('%s/../', __DIR__), $_ENV['APP_ENV'] ?? 'test');
$symfonyConsolerRunner->run('cache:clear', ['--no-warmup']);
$symfonyConsolerRunner->run('doctrine:database:create', ['--if-not-exists']);
$symfonyConsolerRunner->run('doctrine:migrations:migrate', ['--no-interaction']);
Adding a cache warmup to the bootstrap fix the issue:
$symfonyConsolerRunner->run('cache:warmup');
Possible Solution
Adding a file_exists() call fixes the issue.
} elseif (file_exists($file) && \is_array($expiresAt = include $file)) {
In the first loop, $expiresAt
is uninitialized, this cause a issue wih the last elseif:
} elseif ($now < $expiresAt) {
$expiresAt
should also be initialized before } elseif ($now < $expiresAt) {
. The complete code snippet is:
// Initialize the expiry time to the current time
$expiresAt = $now;
if (isset(self::$valuesCache[$file])) {
[$expiresAt, $this->values[$id]] = self::$valuesCache[$file];
} elseif (file_exists($file) && \is_array($expiresAt = include $file)) {
if ($this->appendOnly) {
self::$valuesCache[$file] = $expiresAt;
}
[$expiresAt, $this->values[$id]] = $expiresAt;
} elseif ($now < $expiresAt) {
$this->values[$id] = new LazyValue($file);
}
The code doesn't cause a segfault with these changes.
Additional Context
No response