Upstream nikic/FastRoute state of the touched files before e76ad24228
This commit is contained in:
1 parent
7ac8857878
commit
5861a25d71
6 files changed
+9
-62
No files matched your search
@@ -7,6 +7,7 @@ use FastRoute\Dispatcher\Result\Matched;
|
|||||||
|
|
||||||
use function assert;
|
use function assert;
|
||||||
use function end;
|
use function end;
|
||||||
|
use function preg_match;
|
||||||
|
|
||||||
/** @final */
|
/** @final */
|
||||||
class CharCountBased extends RegexBasedAbstract
|
class CharCountBased extends RegexBasedAbstract
|
||||||
@@ -17,7 +18,7 @@ class CharCountBased extends RegexBasedAbstract
|
|||||||
foreach ($routeData as $data) {
|
foreach ($routeData as $data) {
|
||||||
assert(isset($data['suffix']));
|
assert(isset($data['suffix']));
|
||||||
|
|
||||||
if ($this->matchRoute($data['regex'], $uri . $data['suffix'], $matches) !== 1) {
|
if (preg_match($data['regex'], $uri . $data['suffix'], $matches) !== 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace FastRoute\Dispatcher;
|
|||||||
use FastRoute\Dispatcher\Result\Matched;
|
use FastRoute\Dispatcher\Result\Matched;
|
||||||
|
|
||||||
use function count;
|
use function count;
|
||||||
|
use function preg_match;
|
||||||
|
|
||||||
/** @final */
|
/** @final */
|
||||||
class GroupCountBased extends RegexBasedAbstract
|
class GroupCountBased extends RegexBasedAbstract
|
||||||
@@ -14,7 +15,7 @@ class GroupCountBased extends RegexBasedAbstract
|
|||||||
protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched
|
protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched
|
||||||
{
|
{
|
||||||
foreach ($routeData as $data) {
|
foreach ($routeData as $data) {
|
||||||
if ($this->matchRoute($data['regex'], $uri, $matches) !== 1) {
|
if (preg_match($data['regex'], $uri, $matches) !== 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace FastRoute\Dispatcher;
|
|||||||
use FastRoute\Dispatcher\Result\Matched;
|
use FastRoute\Dispatcher\Result\Matched;
|
||||||
|
|
||||||
use function assert;
|
use function assert;
|
||||||
|
use function preg_match;
|
||||||
|
|
||||||
/** @final */
|
/** @final */
|
||||||
class GroupPosBased extends RegexBasedAbstract
|
class GroupPosBased extends RegexBasedAbstract
|
||||||
@@ -14,7 +15,7 @@ class GroupPosBased extends RegexBasedAbstract
|
|||||||
protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched
|
protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched
|
||||||
{
|
{
|
||||||
foreach ($routeData as $data) {
|
foreach ($routeData as $data) {
|
||||||
if ($this->matchRoute($data['regex'], $uri, $matches) !== 1) {
|
if (preg_match($data['regex'], $uri, $matches) !== 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ namespace FastRoute\Dispatcher;
|
|||||||
|
|
||||||
use FastRoute\Dispatcher\Result\Matched;
|
use FastRoute\Dispatcher\Result\Matched;
|
||||||
|
|
||||||
|
use function preg_match;
|
||||||
|
|
||||||
/** @final */
|
/** @final */
|
||||||
class MarkBased extends RegexBasedAbstract
|
class MarkBased extends RegexBasedAbstract
|
||||||
{
|
{
|
||||||
@@ -12,7 +14,7 @@ class MarkBased extends RegexBasedAbstract
|
|||||||
protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched
|
protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched
|
||||||
{
|
{
|
||||||
foreach ($routeData as $data) {
|
foreach ($routeData as $data) {
|
||||||
if ($this->matchRoute($data['regex'], $uri, $matches) !== 1) {
|
if (preg_match($data['regex'], $uri, $matches) !== 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ use FastRoute\Dispatcher;
|
|||||||
use FastRoute\Dispatcher\Result\Matched;
|
use FastRoute\Dispatcher\Result\Matched;
|
||||||
use FastRoute\Dispatcher\Result\MethodNotAllowed;
|
use FastRoute\Dispatcher\Result\MethodNotAllowed;
|
||||||
use FastRoute\Dispatcher\Result\NotMatched;
|
use FastRoute\Dispatcher\Result\NotMatched;
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
use function preg_last_error_msg;
|
|
||||||
use function preg_match;
|
|
||||||
use function sprintf;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@@ -40,26 +35,6 @@ abstract class RegexBasedAbstract implements Dispatcher
|
|||||||
/** @param DynamicRouteChunks $routeData */
|
/** @param DynamicRouteChunks $routeData */
|
||||||
abstract protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched;
|
abstract protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched;
|
||||||
|
|
||||||
/**
|
|
||||||
* Matches a route regex, distinguishing a genuine "no match" (preg_match()
|
|
||||||
* returns 0) from a PCRE engine failure such as PREG_BACKTRACK_LIMIT_ERROR
|
|
||||||
* (returns false), which would otherwise fail unrelated routes sharing the
|
|
||||||
* same combined regex chunk.
|
|
||||||
*
|
|
||||||
* @param array<int|string, mixed>|null $matches
|
|
||||||
*/
|
|
||||||
protected function matchRoute(string $regex, string $subject, ?array &$matches = null): int
|
|
||||||
{
|
|
||||||
$result = preg_match($regex, $subject, $matches);
|
|
||||||
if ($result === false) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
sprintf('Regex matching failed for "%s": %s', $regex, preg_last_error_msg()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dispatch(string $httpMethod, string $uri): Matched|NotMatched|MethodNotAllowed
|
public function dispatch(string $httpMethod, string $uri): Matched|NotMatched|MethodNotAllowed
|
||||||
{
|
{
|
||||||
if (isset($this->staticRouteMap[$httpMethod][$uri])) {
|
if (isset($this->staticRouteMap[$httpMethod][$uri])) {
|
||||||
|
|||||||
@@ -13,11 +13,8 @@ use FastRoute\Dispatcher\Result\MethodNotAllowed;
|
|||||||
use FastRoute\Dispatcher\Result\NotMatched;
|
use FastRoute\Dispatcher\Result\NotMatched;
|
||||||
use PHPUnit\Framework\Attributes as PHPUnit;
|
use PHPUnit\Framework\Attributes as PHPUnit;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
use function FastRoute\simpleDispatcher;
|
use function FastRoute\simpleDispatcher;
|
||||||
use function ini_set;
|
|
||||||
use function str_repeat;
|
|
||||||
|
|
||||||
/** @phpstan-import-type ExtraParameters from DataGenerator */
|
/** @phpstan-import-type ExtraParameters from DataGenerator */
|
||||||
abstract class DispatcherTestCase extends TestCase
|
abstract class DispatcherTestCase extends TestCase
|
||||||
@@ -180,36 +177,6 @@ abstract class DispatcherTestCase extends TestCase
|
|||||||
}, $this->generateDispatcherOptions());
|
}, $this->generateDispatcherOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A PCRE engine failure must surface instead of being reported as
|
|
||||||
* NOT_FOUND for an unrelated route in the same combined regex chunk.
|
|
||||||
*
|
|
||||||
* @see https://github.com/nikic/FastRoute/issues/167
|
|
||||||
*/
|
|
||||||
#[PHPUnit\Test]
|
|
||||||
public function regexEngineFailureIsNotSilentlyTreatedAsNotFound(): void
|
|
||||||
{
|
|
||||||
$previousLimit = ini_set('pcre.backtrack_limit', '1000');
|
|
||||||
self::assertNotFalse($previousLimit, 'Unable to lower pcre.backtrack_limit for this test');
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->expectException(RuntimeException::class);
|
|
||||||
$this->expectExceptionMessageMatches('/Backtrack limit exhausted/');
|
|
||||||
|
|
||||||
$dispatcher = simpleDispatcher(static function (ConfigureRoutes $r): void {
|
|
||||||
// Catastrophically backtracking pattern.
|
|
||||||
$r->addRoute('GET', '/{p:(?:a?a?)*}/complicated', 'complicated_pattern');
|
|
||||||
// Cheap route in the same chunk: it would match on its own, but the
|
|
||||||
// chunk's preg_match() call fails.
|
|
||||||
$r->addRoute('GET', '/{p:a+}', 'cheap_route');
|
|
||||||
}, $this->generateDispatcherOptions());
|
|
||||||
|
|
||||||
$dispatcher->dispatch('GET', '/' . str_repeat('a', 30));
|
|
||||||
} finally {
|
|
||||||
ini_set('pcre.backtrack_limit', $previousLimit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return iterable<string, array{0: string, 1: string, 2: Closure(ConfigureRoutes):void, 3: string, 4?: array<string, string>}> */
|
/** @return iterable<string, array{0: string, 1: string, 2: Closure(ConfigureRoutes):void, 3: string, 4?: array<string, string>}> */
|
||||||
public static function provideFoundDispatchCases(): iterable
|
public static function provideFoundDispatchCases(): iterable
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user