diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 4cea086b78e73..796ce5e4ed609 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -863,17 +863,20 @@ private function doActuallyRenderThrowable(\Throwable $e, OutputInterface $outpu do { $message = trim($e->getMessage()); if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { - $class = \get_class($e); - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $class = get_debug_type($e); $title = sprintf(' [%s%s] ', $class, 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : ''); $len = Helper::strlen($title); } else { $len = 0; } - if (false !== strpos($message, "class@anonymous\0")) { - $message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + if (str_contains($message, "@anonymous\0")) { + $message = preg_replace_callback('/([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { + if ('class' === $m[1]) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: 'class').'@anonymous' : $m[0]; + } + + return $m[1].'@anonymous'; }, $message); } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index cc68f596eea9f..58c0aa8b0808f 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -912,7 +912,7 @@ public function testRenderAnonymousException() $tester = new ApplicationTester($application); $tester->run(['command' => 'foo'], ['decorated' => false]); - $this->assertStringContainsString('Dummy type "@anonymous" is invalid.', $tester->getDisplay(true)); + $this->assertStringContainsString('Dummy type "class@anonymous" is invalid.', $tester->getDisplay(true)); } public function testRenderExceptionStackTraceContainsRootException() @@ -935,7 +935,7 @@ public function testRenderExceptionStackTraceContainsRootException() $tester = new ApplicationTester($application); $tester->run(['command' => 'foo'], ['decorated' => false]); - $this->assertStringContainsString('Dummy type "@anonymous" is invalid.', $tester->getDisplay(true)); + $this->assertStringContainsString('Dummy type "class@anonymous" is invalid.', $tester->getDisplay(true)); } public function testRun() diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index 1f7240d4a625d..743ee2f18b122 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -19,6 +19,7 @@ "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.17", "symfony/service-contracts": "^1.1|^2" }, "require-dev": { diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index fe84ba5dad296..0cac5208c2cff 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -415,7 +415,7 @@ public function handleError($type, $message, $file, $line) $context = $e; } - if (false !== strpos($message, "class@anonymous\0")) { + if (false !== strpos($message, "@anonymous\0")) { $logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage(); } else { $logMessage = $this->levels[$type].': '.$message; @@ -540,7 +540,7 @@ public function handleException($exception, array $error = null) $handlerException = null; if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) { - if (false !== strpos($message = $exception->getMessage(), "class@anonymous\0")) { + if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) { $message = (new FlattenException())->setMessage($message)->getMessage(); } if ($exception instanceof FatalErrorException) { diff --git a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php index e13b0172f0588..5f86fecd69576 100644 --- a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php +++ b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php @@ -26,7 +26,7 @@ class FatalThrowableError extends FatalErrorException public function __construct(\Throwable $e) { - $this->originalClassName = \get_class($e); + $this->originalClassName = get_debug_type($e); if ($e instanceof \ParseError) { $severity = E_PARSE; diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php index a4cb517cb20fb..ad405d041b6f0 100644 --- a/src/Symfony/Component/Debug/Exception/FlattenException.php +++ b/src/Symfony/Component/Debug/Exception/FlattenException.php @@ -67,7 +67,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod $e->setStatusCode($statusCode); $e->setHeaders($headers); $e->setTraceFromThrowable($exception); - $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception)); + $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : get_debug_type($exception)); $e->setFile($exception->getFile()); $e->setLine($exception->getLine()); @@ -134,7 +134,11 @@ public function getClass() */ public function setClass($class) { - $this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + if (preg_match('/^([\\\\\w]+)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', $class, $matches)) { + $this->class = ('class' === $matches[1] ? get_parent_class($matches[0]) : $matches[1]).'@anonymous'; + } else { + $this->class = $class; + } return $this; } @@ -179,9 +183,13 @@ public function getMessage() */ public function setMessage($message) { - if (false !== strpos($message, "class@anonymous\0")) { - $message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + if (str_contains($message, "@anonymous\0")) { + $message = preg_replace_callback('/([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { + if ('class' === $m[1]) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: 'class').'@anonymous' : $m[0]; + } + + return $m[1].'@anonymous'; }, $message); } diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 2ba84c171b97c..80ab0f2c79b1e 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -325,6 +325,24 @@ public function testHandleUserError() } } + public function testHandleErrorWithAnonymousClass(): void + { + $handler = ErrorHandler::register(); + $handler->throwAt(E_USER_WARNING, true); + try { + $handler->handleError(E_USER_WARNING, 'foo '.\get_class(new class() extends \stdClass { + }).' bar', 'foo.php', 12); + $this->fail('Exception expected.'); + } catch (\ErrorException $e) { + $this->assertSame('User Warning: foo stdClass@anonymous bar', $e->getMessage()); + $this->assertSame(E_USER_WARNING, $e->getSeverity()); + $this->assertSame('foo.php', $e->getFile()); + $this->assertSame(12, $e->getLine()); + } finally { + restore_error_handler(); + } + } + public function testHandleDeprecation() { $logArgCheck = function ($level, $message, $context) { diff --git a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php index a2620b2e28333..9f715a816bd28 100644 --- a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php +++ b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php @@ -355,6 +355,11 @@ public function testAnonymousClass() $this->assertSame('RuntimeException@anonymous', $flattened->getClass()); + $flattened->setClass(\get_class(new class('Oops') extends NotFoundHttpException { + })); + + $this->assertSame('Symfony\Component\HttpKernel\Exception\NotFoundHttpException@anonymous', $flattened->getClass()); + $flattened = FlattenException::create(new \Exception(sprintf('Class "%s" blah.', \get_class(new class() extends \RuntimeException { })))); diff --git a/src/Symfony/Component/Debug/composer.json b/src/Symfony/Component/Debug/composer.json index f68082db7b31f..bd85795d544eb 100644 --- a/src/Symfony/Component/Debug/composer.json +++ b/src/Symfony/Component/Debug/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=7.1.3", - "psr/log": "~1.0" + "psr/log": "~1.0", + "symfony/polyfill-php80": "~1.17" }, "conflict": { "symfony/http-kernel": "<3.4" diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php index 71f21f50fadf0..5b666871c0612 100644 --- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php +++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php @@ -407,7 +407,7 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } $deprecations = []; - $className = isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00") ? get_parent_class($class).'@anonymous' : $class; + $className = $refl->isAnonymous() ? (($parentRefl = $refl->getParentClass()) ? $parentRefl->name : 'class').'@anonymous' : $class; // Don't trigger deprecations for classes in the same vendor if ($class !== $className) { diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php index 0c8edfcd9d3b9..aff20765181be 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php +++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php @@ -435,7 +435,7 @@ public function handleError(int $type, string $message, string $file, int $line) $context = $e; } - if (false !== strpos($message, "class@anonymous\0")) { + if (false !== strpos($message, "@anonymous\0")) { $logMessage = $this->parseAnonymousClass($message); } else { $logMessage = $this->levels[$type].': '.$message; @@ -558,7 +558,7 @@ public function handleException(\Throwable $exception) } if ($this->loggedErrors & $type) { - if (false !== strpos($message = $exception->getMessage(), "class@anonymous\0")) { + if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) { $message = $this->parseAnonymousClass($message); } @@ -768,8 +768,12 @@ private function cleanTrace(array $backtrace, int $type, string $file, int $line */ private function parseAnonymousClass(string $message): string { - return preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + return preg_replace_callback('/([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { + if ('class' === $m[1]) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: 'class').'@anonymous' : $m[0]; + } + + return $m[1].'@anonymous'; }, $message); } } diff --git a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php index 61a3497adc9f8..6173a750c1910 100644 --- a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php +++ b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php @@ -71,7 +71,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod $e->setStatusCode($statusCode); $e->setHeaders($headers); $e->setTraceFromThrowable($exception); - $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception)); + $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : get_debug_type($exception)); $e->setFile($exception->getFile()); $e->setLine($exception->getLine()); @@ -138,7 +138,11 @@ public function getClass(): string */ public function setClass($class): self { - $this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + if (preg_match('/^([\\\\\w]+)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', $class, $matches)) { + $this->class = ('class' === $matches[1] ? get_parent_class($matches[0]) : $matches[1]).'@anonymous'; + } else { + $this->class = $class; + } return $this; } @@ -195,9 +199,13 @@ public function getMessage(): string */ public function setMessage($message): self { - if (false !== strpos($message, "class@anonymous\0")) { - $message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + if (str_contains($message, "@anonymous\0")) { + $message = preg_replace_callback('/([\\\\\w]+)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { + if ('class' === $m[1]) { + return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + } + + return $m[1].'@anonymous'; }, $message); } diff --git a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php index d34961a00b0e7..8d7ba4be4b9a2 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php @@ -365,6 +365,24 @@ public function testHandleUserError() } } + public function testHandleErrorWithAnonymousClass(): void + { + $handler = ErrorHandler::register(); + $handler->throwAt(3, true); + try { + $handler->handleError(3, 'foo '.\get_class(new class() extends \stdClass { + }).' bar', 'foo.php', 12); + $this->fail('Exception expected.'); + } catch (\ErrorException $e) { + $this->assertSame('foo stdClass@anonymous bar', $e->getMessage()); + $this->assertSame(3, $e->getSeverity()); + $this->assertSame('foo.php', $e->getFile()); + $this->assertSame(12, $e->getLine()); + } finally { + restore_error_handler(); + } + } + public function testHandleDeprecation() { $logArgCheck = function ($level, $message, $context) { @@ -433,6 +451,10 @@ public function handleExceptionProvider(): array { return [ ['Uncaught Exception: foo', new \Exception('foo')], + ['Uncaught Exception: foo', new class('foo') extends \RuntimeException { + }], + ['Uncaught Exception: foo stdClass@anonymous bar', new \RuntimeException('foo '.\get_class(new class() extends \stdClass { + }).' bar')], ['Uncaught Error: bar', new \Error('bar')], ['Uncaught ccc', new \ErrorException('ccc')], ]; diff --git a/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php index 437d211f71590..55fd4de29f57d 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php +++ b/src/Symfony/Component/ErrorHandler/Tests/Exception/FlattenExceptionTest.php @@ -373,6 +373,11 @@ public function testAnonymousClass() $this->assertSame('RuntimeException@anonymous', $flattened->getClass()); + $flattened->setClass(\get_class(new class('Oops') extends NotFoundHttpException { + })); + + $this->assertSame('Symfony\Component\HttpKernel\Exception\NotFoundHttpException@anonymous', $flattened->getClass()); + $flattened = FlattenException::createFromThrowable(new \Exception(sprintf('Class "%s" blah.', \get_class(new class() extends \RuntimeException { })))); diff --git a/src/Symfony/Component/ErrorHandler/composer.json b/src/Symfony/Component/ErrorHandler/composer.json index 857236e32cb6d..285db2dd55830 100644 --- a/src/Symfony/Component/ErrorHandler/composer.json +++ b/src/Symfony/Component/ErrorHandler/composer.json @@ -19,6 +19,7 @@ "php": ">=7.1.3", "psr/log": "~1.0", "symfony/debug": "^4.4.5", + "symfony/polyfill-php80": "^1.17", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 8349de676a976..6f664a5f7a80e 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -228,10 +228,7 @@ public function getBundles() public function getBundle($name) { if (!isset($this->bundles[$name])) { - $class = static::class; - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; - - throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, $class)); + throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, get_debug_type($this))); } return $this->bundles[$name]; @@ -473,8 +470,8 @@ protected function build(ContainerBuilder $container) */ protected function getContainerClass() { - $class = static::class; - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).str_replace('.', '_', ContainerBuilder::hash($class)) : $class; + $class = get_debug_type($this); + $class = str_ends_with($class, '@anonymous') ? get_parent_class($this).str_replace('.', '_', ContainerBuilder::hash($class)) : $class; $class = $this->name.str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container'; if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $class)) { diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index deac82b72d5fc..36f8ea6e66502 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -640,6 +640,27 @@ public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel() $this->assertGreaterThan($preReBoot, $kernel->getStartTime()); } + public function testAnonymousKernelGeneratesValidContainerClass(): void + { + $kernel = new class('test', true) extends Kernel { + public function registerBundles(): iterable + { + return []; + } + + public function registerContainerConfiguration(LoaderInterface $loader): void + { + } + + public function getContainerClass(): string + { + return parent::getContainerClass(); + } + }; + + $this->assertRegExp('/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*TestDebugContainer$/', $kernel->getContainerClass()); + } + /** * Returns a mock for the BundleInterface. */ diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index eca3b54b3661d..a69758cb98ebd 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -22,6 +22,7 @@ "symfony/http-foundation": "^4.4|^5.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.17", "psr/log": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php b/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php index f0400c3cb660f..bedade318fe0f 100644 --- a/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php +++ b/src/Symfony/Component/Messenger/Middleware/TraceableMiddleware.php @@ -78,8 +78,7 @@ public function next(): MiddlewareInterface if ($this->stack === $nextMiddleware = $this->stack->next()) { $this->currentEvent = 'Tail'; } else { - $class = \get_class($nextMiddleware); - $this->currentEvent = sprintf('"%s"', 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class); + $this->currentEvent = sprintf('"%s"', get_debug_type($nextMiddleware)); } $this->currentEvent .= sprintf(' on "%s"', $this->busName); diff --git a/src/Symfony/Component/Messenger/Tests/Middleware/TraceableMiddlewareTest.php b/src/Symfony/Component/Messenger/Tests/Middleware/TraceableMiddlewareTest.php index 54be577554992..3bc64675d9cf4 100644 --- a/src/Symfony/Component/Messenger/Tests/Middleware/TraceableMiddlewareTest.php +++ b/src/Symfony/Component/Messenger/Tests/Middleware/TraceableMiddlewareTest.php @@ -30,14 +30,16 @@ public function testHandle() $busId = 'command_bus'; $envelope = new Envelope(new DummyMessage('Hello')); - $middleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock(); - $middleware->expects($this->once()) - ->method('handle') - ->with($envelope, $this->anything()) - ->willReturnCallback(function ($envelope, StackInterface $stack) { + $middleware = new class() implements MiddlewareInterface { + public $calls = 0; + + public function handle(Envelope $envelope, StackInterface $stack): Envelope + { + ++$this->calls; + return $stack->next()->handle($envelope, $stack); - }) - ; + } + }; $stopwatch = $this->createMock(Stopwatch::class); $stopwatch->expects($this->once())->method('isStarted')->willReturn(true); @@ -51,7 +53,7 @@ public function testHandle() $stopwatch->expects($this->exactly(2)) ->method('stop') ->withConsecutive( - [$this->matches('"%sMiddlewareInterface%s" on "command_bus"')], + ['"Symfony\Component\Messenger\Middleware\MiddlewareInterface@anonymous" on "command_bus"'], ['Tail on "command_bus"'] ) ; @@ -59,6 +61,7 @@ public function testHandle() $traced = new TraceableMiddleware($stopwatch, $busId); $traced->handle($envelope, new StackMiddleware(new \ArrayIterator([null, $middleware]))); + $this->assertSame(1, $middleware->calls); } public function testHandleWithException() diff --git a/src/Symfony/Component/Messenger/composer.json b/src/Symfony/Component/Messenger/composer.json index dfe66f10f04ea..ad63a6c55d5ea 100644 --- a/src/Symfony/Component/Messenger/composer.json +++ b/src/Symfony/Component/Messenger/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=7.1.3", - "psr/log": "~1.0" + "psr/log": "~1.0", + "symfony/polyfill-php80": "^1.17" }, "require-dev": { "doctrine/dbal": "^2.6", diff --git a/src/Symfony/Component/VarDumper/Caster/ClassStub.php b/src/Symfony/Component/VarDumper/Caster/ClassStub.php index c998b49f2cc47..b79c862731ce3 100644 --- a/src/Symfony/Component/VarDumper/Caster/ClassStub.php +++ b/src/Symfony/Component/VarDumper/Caster/ClassStub.php @@ -55,9 +55,13 @@ public function __construct(string $identifier, $callable = null) } } - if (false !== strpos($identifier, "class@anonymous\0")) { - $this->value = $identifier = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + if (str_contains($identifier, "@anonymous\0")) { + $this->value = $identifier = preg_replace_callback('/([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { + if ('class' === $m[1]) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: 'class').'@anonymous' : $m[0]; + } + + return $m[1].'@anonymous'; }, $identifier); } diff --git a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php index 9fe1e39ae49e0..d24a349159470 100644 --- a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php @@ -73,8 +73,7 @@ public static function castThrowingCasterException(ThrowingCasterException $e, a if (isset($a[$xPrefix.'previous'], $a[$trace]) && $a[$xPrefix.'previous'] instanceof \Exception) { $b = (array) $a[$xPrefix.'previous']; - $class = \get_class($a[$xPrefix.'previous']); - $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $class = get_debug_type($a[$xPrefix.'previous']); self::traceUnshift($b[$xPrefix.'trace'], $class, $b[$prefix.'file'], $b[$prefix.'line']); $a[$trace] = new TraceStub($b[$xPrefix.'trace'], false, 0, -\count($a[$trace]->value)); } @@ -282,9 +281,13 @@ private static function filterExceptionArray(string $xClass, array $a, string $x } unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message'], $a[Caster::PREFIX_DYNAMIC.'__destructorException']); - if (isset($a[Caster::PREFIX_PROTECTED.'message']) && false !== strpos($a[Caster::PREFIX_PROTECTED.'message'], "class@anonymous\0")) { - $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { - return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + if (isset($a[Caster::PREFIX_PROTECTED.'message']) && str_contains($a[Caster::PREFIX_PROTECTED.'message'], "@anonymous\0")) { + $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { + if ('class' === $m[1]) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: 'class').'@anonymous' : $m[0]; + } + + return $m[1].'@anonymous'; }, $a[Caster::PREFIX_PROTECTED.'message']); }