diff --git a/.travis.yml b/.travis.yml index 115fa34aa9180..feb49ef8b0637 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,8 +31,6 @@ matrix: - php: nightly services: [memcached] fast_finish: true - allow_failures: - - php: nightly cache: directories: diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 4cea086b78e73..199ed6804c3fb 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -863,17 +863,16 @@ 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 (false !== strpos($message, "@anonymous\0")) { + $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $message); } diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index cc68f596eea9f..7fa460d7d87fe 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -897,7 +897,8 @@ public function testRenderAnonymousException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new class('') extends \InvalidArgumentException { }; + throw new class('') extends \InvalidArgumentException { + }; }); $tester = new ApplicationTester($application); @@ -907,12 +908,13 @@ public function testRenderAnonymousException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { }))); + throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { + }))); }); $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() @@ -920,7 +922,8 @@ public function testRenderExceptionStackTraceContainsRootException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new class('') extends \InvalidArgumentException { }; + throw new class('') extends \InvalidArgumentException { + }; }); $tester = new ApplicationTester($application); @@ -930,12 +933,13 @@ public function testRenderExceptionStackTraceContainsRootException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { }))); + throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { + }))); }); $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..42d74977ffec4 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.15", "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..ac9545628a1ae 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,7 @@ public function getClass() */ public function setClass($class) { - $this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; return $this; } @@ -179,9 +179,9 @@ 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 (false !== strpos($message, "@anonymous\0")) { + $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $message); } diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 2ba84c171b97c..5943ff21b7704 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -325,6 +325,26 @@ public function testHandleUserError() } } + public function testHandleErrorWithAnonymousClass() + { + $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) { + } finally { + restore_error_handler(); + restore_exception_handler(); + } + + $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()); + } + 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..3dab2888e34e5 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.15" }, "conflict": { "symfony/http-kernel": "<3.4" diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php index 71f21f50fadf0..fe6227e8146ea 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 = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: '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..e02a8fc45dced 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,8 @@ 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_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $message); } } diff --git a/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php b/src/Symfony/Component/ErrorHandler/Exception/FlattenException.php index 61a3497adc9f8..e275ed1262bb4 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,7 @@ 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; + $this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class; return $this; } @@ -195,9 +195,9 @@ 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 (false !== strpos($message, "@anonymous\0")) { + $message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $message); } diff --git a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php index d34961a00b0e7..bb910b6d1a110 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php @@ -365,6 +365,26 @@ public function testHandleUserError() } } + public function testHandleErrorWithAnonymousClass() + { + $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) { + } finally { + restore_error_handler(); + restore_exception_handler(); + } + + $this->assertSame('foo stdClass@anonymous bar', $e->getMessage()); + $this->assertSame(3, $e->getSeverity()); + $this->assertSame('foo.php', $e->getFile()); + $this->assertSame(12, $e->getLine()); + } + public function testHandleDeprecation() { $logArgCheck = function ($level, $message, $context) { @@ -433,6 +453,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..a685b6b36828c 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.15", "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..438ef37f3450d 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]; @@ -474,7 +471,7 @@ 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 = false !== strpos($class, "@anonymous\0") ? get_parent_class($class).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..2ae07df88445b 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.15", "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..4d818a4952f01 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.15" }, "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..612a7ca2d9933 100644 --- a/src/Symfony/Component/VarDumper/Caster/ClassStub.php +++ b/src/Symfony/Component/VarDumper/Caster/ClassStub.php @@ -55,9 +55,9 @@ 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 (false !== strpos($identifier, "@anonymous\0")) { + $this->value = $identifier = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $identifier); } diff --git a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php index 9fe1e39ae49e0..dc9ed7e322ba5 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,9 @@ 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']) && false !== strpos($a[Caster::PREFIX_PROTECTED.'message'], "@anonymous\0")) { + $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; }, $a[Caster::PREFIX_PROTECTED.'message']); }