Ignore invalid routes cache file
If the `libraries/cache/routes.cache.php` file is invalid (usually from 5.1), ignores it and try to write a new one instead of failing. Fixes https://github.com/phpmyadmin/phpmyadmin/issues/17522. Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
parent
4590194c71
commit
680e59eb5f
@ -9,9 +9,9 @@ use FastRoute\Dispatcher;
|
||||
use FastRoute\Dispatcher\GroupCountBased as DispatcherGroupCountBased;
|
||||
use FastRoute\RouteCollector;
|
||||
use FastRoute\RouteParser\Std as RouteParserStd;
|
||||
use PhpMyAdmin\Controllers\HomeController;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use RuntimeException;
|
||||
|
||||
use function __;
|
||||
use function file_exists;
|
||||
@ -28,6 +28,7 @@ use function var_export;
|
||||
|
||||
use const CACHE_DIR;
|
||||
use const E_USER_WARNING;
|
||||
use const ROOT_PATH;
|
||||
|
||||
/**
|
||||
* Class used to warm up the routing cache and manage routing.
|
||||
@ -73,13 +74,11 @@ class Routing
|
||||
// If skip cache is enabled, do not try to read the file
|
||||
// If no cache skipping then read it and use it
|
||||
if (! $skipCache && file_exists(self::ROUTES_CACHE_FILE)) {
|
||||
/** @psalm-suppress MissingFile, UnresolvableInclude */
|
||||
/** @psalm-suppress MissingFile, UnresolvableInclude, MixedAssignment */
|
||||
$dispatchData = require self::ROUTES_CACHE_FILE;
|
||||
if (! is_array($dispatchData)) {
|
||||
throw new RuntimeException('Invalid cache file "' . self::ROUTES_CACHE_FILE . '"');
|
||||
if (self::isRoutesCacheFileValid($dispatchData)) {
|
||||
return new DispatcherGroupCountBased($dispatchData);
|
||||
}
|
||||
|
||||
return new DispatcherGroupCountBased($dispatchData);
|
||||
}
|
||||
|
||||
$routeCollector = new RouteCollector(
|
||||
@ -191,4 +190,19 @@ class Routing
|
||||
$controller = $container->get($controllerName);
|
||||
$controller($request, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $dispatchData
|
||||
*
|
||||
* @psalm-assert-if-true array[] $dispatchData
|
||||
*/
|
||||
private static function isRoutesCacheFileValid($dispatchData): bool
|
||||
{
|
||||
return is_array($dispatchData)
|
||||
&& isset($dispatchData[0], $dispatchData[1])
|
||||
&& is_array($dispatchData[0]) && is_array($dispatchData[1])
|
||||
&& isset($dispatchData[0]['GET']) && is_array($dispatchData[0]['GET'])
|
||||
&& isset($dispatchData[0]['GET']['/']) && is_string($dispatchData[0]['GET']['/'])
|
||||
&& $dispatchData[0]['GET']['/'] === HomeController::class;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,11 @@ use FastRoute\Dispatcher;
|
||||
use PhpMyAdmin\Controllers\HomeController;
|
||||
use PhpMyAdmin\Routing;
|
||||
|
||||
use function copy;
|
||||
|
||||
use const CACHE_DIR;
|
||||
use const ROOT_PATH;
|
||||
|
||||
/**
|
||||
* @covers \PhpMyAdmin\Routing
|
||||
*/
|
||||
@ -26,6 +31,52 @@ class RoutingTest extends AbstractTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDispatcherWithValidCacheFile(): void
|
||||
{
|
||||
$GLOBALS['cfg']['environment'] = null;
|
||||
|
||||
$this->assertDirectoryIsWritable(CACHE_DIR);
|
||||
$this->assertTrue(copy(
|
||||
ROOT_PATH . 'test/test_data/routes/routes-valid.cache.txt',
|
||||
CACHE_DIR . 'routes.cache.php'
|
||||
));
|
||||
|
||||
$dispatcher = Routing::getDispatcher();
|
||||
$this->assertInstanceOf(Dispatcher::class, $dispatcher);
|
||||
$this->assertSame(
|
||||
[Dispatcher::FOUND, HomeController::class, []],
|
||||
$dispatcher->dispatch('GET', '/')
|
||||
);
|
||||
|
||||
$this->assertFileEquals(
|
||||
CACHE_DIR . 'routes.cache.php',
|
||||
ROOT_PATH . 'test/test_data/routes/routes-valid.cache.txt'
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDispatcherWithInvalidCacheFile(): void
|
||||
{
|
||||
$GLOBALS['cfg']['environment'] = null;
|
||||
|
||||
$this->assertDirectoryIsWritable(CACHE_DIR);
|
||||
$this->assertTrue(copy(
|
||||
ROOT_PATH . 'test/test_data/routes/routes-invalid.cache.txt',
|
||||
CACHE_DIR . 'routes.cache.php'
|
||||
));
|
||||
|
||||
$dispatcher = Routing::getDispatcher();
|
||||
$this->assertInstanceOf(Dispatcher::class, $dispatcher);
|
||||
$this->assertSame(
|
||||
[Dispatcher::FOUND, HomeController::class, []],
|
||||
$dispatcher->dispatch('GET', '/')
|
||||
);
|
||||
|
||||
$this->assertFileNotEquals(
|
||||
CACHE_DIR . 'routes.cache.php',
|
||||
ROOT_PATH . 'test/test_data/routes/routes-invalid.cache.txt'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for Routing::getCurrentRoute
|
||||
*/
|
||||
|
||||
34
test/test_data/routes/routes-invalid.cache.txt
Normal file
34
test/test_data/routes/routes-invalid.cache.txt
Normal file
@ -0,0 +1,34 @@
|
||||
<?php return array (
|
||||
0 =>
|
||||
array (
|
||||
'GET' =>
|
||||
array (
|
||||
'' =>
|
||||
array (
|
||||
0 => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
1 => 'index',
|
||||
),
|
||||
'/' =>
|
||||
array (
|
||||
0 => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
1 => 'index',
|
||||
),
|
||||
),
|
||||
'POST' =>
|
||||
array (
|
||||
'' =>
|
||||
array (
|
||||
0 => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
1 => 'index',
|
||||
),
|
||||
'/' =>
|
||||
array (
|
||||
0 => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
1 => 'index',
|
||||
),
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
18
test/test_data/routes/routes-valid.cache.txt
Normal file
18
test/test_data/routes/routes-valid.cache.txt
Normal file
@ -0,0 +1,18 @@
|
||||
<?php return array (
|
||||
0 =>
|
||||
array (
|
||||
'GET' =>
|
||||
array (
|
||||
'' => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
'/' => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
),
|
||||
'POST' =>
|
||||
array (
|
||||
'' => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
'/' => 'PhpMyAdmin\\Controllers\\HomeController',
|
||||
),
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
),
|
||||
);
|
||||
Loading…
Reference in New Issue
Block a user