Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6d02565

Browse filesBrowse files
bug #36914 Parse and render anonymous classes correctly on php 8 (derrabus)
This PR was merged into the 4.4 branch. Discussion ---------- Parse and render anonymous classes correctly on php 8 | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | #36872 | License | MIT | Doc PR | N/A The format of the value that `get_class()` returns for anonymous classes has changed in php 8. This PR attempts to detect both formats, with the help of the PHP80 polyfill where possible. Commits ------- 9d702fd Parse and render anonymous classes correctly on php 8
2 parents 7224c1d + 9d702fd commit 6d02565
Copy full SHA for 6d02565
Expand file treeCollapse file tree

24 files changed

+135
-56
lines changed

‎.travis.yml

Copy file name to clipboardExpand all lines: .travis.yml
-2Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ matrix:
3131
- php: nightly
3232
services: [memcached]
3333
fast_finish: true
34-
allow_failures:
35-
- php: nightly
3634

3735
cache:
3836
directories:

‎src/Symfony/Component/Console/Application.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Application.php
+4-5Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -863,17 +863,16 @@ private function doActuallyRenderThrowable(\Throwable $e, OutputInterface $outpu
863863
do {
864864
$message = trim($e->getMessage());
865865
if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
866-
$class = \get_class($e);
867-
$class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
866+
$class = get_debug_type($e);
868867
$title = sprintf(' [%s%s] ', $class, 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : '');
869868
$len = Helper::strlen($title);
870869
} else {
871870
$len = 0;
872871
}
873872

874-
if (false !== strpos($message, "class@anonymous\0")) {
875-
$message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
876-
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
873+
if (false !== strpos($message, "@anonymous\0")) {
874+
$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) {
875+
return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
877876
}, $message);
878877
}
879878

‎src/Symfony/Component/Console/Tests/ApplicationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/ApplicationTest.php
+10-6Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,8 @@ public function testRenderAnonymousException()
897897
$application = new Application();
898898
$application->setAutoExit(false);
899899
$application->register('foo')->setCode(function () {
900-
throw new class('') extends \InvalidArgumentException { };
900+
throw new class('') extends \InvalidArgumentException {
901+
};
901902
});
902903
$tester = new ApplicationTester($application);
903904

@@ -907,20 +908,22 @@ public function testRenderAnonymousException()
907908
$application = new Application();
908909
$application->setAutoExit(false);
909910
$application->register('foo')->setCode(function () {
910-
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { })));
911+
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() {
912+
})));
911913
});
912914
$tester = new ApplicationTester($application);
913915

914916
$tester->run(['command' => 'foo'], ['decorated' => false]);
915-
$this->assertStringContainsString('Dummy type "@anonymous" is invalid.', $tester->getDisplay(true));
917+
$this->assertStringContainsString('Dummy type "class@anonymous" is invalid.', $tester->getDisplay(true));
916918
}
917919

918920
public function testRenderExceptionStackTraceContainsRootException()
919921
{
920922
$application = new Application();
921923
$application->setAutoExit(false);
922924
$application->register('foo')->setCode(function () {
923-
throw new class('') extends \InvalidArgumentException { };
925+
throw new class('') extends \InvalidArgumentException {
926+
};
924927
});
925928
$tester = new ApplicationTester($application);
926929

@@ -930,12 +933,13 @@ public function testRenderExceptionStackTraceContainsRootException()
930933
$application = new Application();
931934
$application->setAutoExit(false);
932935
$application->register('foo')->setCode(function () {
933-
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { })));
936+
throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() {
937+
})));
934938
});
935939
$tester = new ApplicationTester($application);
936940

937941
$tester->run(['command' => 'foo'], ['decorated' => false]);
938-
$this->assertStringContainsString('Dummy type "@anonymous" is invalid.', $tester->getDisplay(true));
942+
$this->assertStringContainsString('Dummy type "class@anonymous" is invalid.', $tester->getDisplay(true));
939943
}
940944

941945
public function testRun()

‎src/Symfony/Component/Console/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/composer.json
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"php": ">=7.1.3",
2020
"symfony/polyfill-mbstring": "~1.0",
2121
"symfony/polyfill-php73": "^1.8",
22+
"symfony/polyfill-php80": "^1.15",
2223
"symfony/service-contracts": "^1.1|^2"
2324
},
2425
"require-dev": {

‎src/Symfony/Component/Debug/ErrorHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Debug/ErrorHandler.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ public function handleError($type, $message, $file, $line)
415415
$context = $e;
416416
}
417417

418-
if (false !== strpos($message, "class@anonymous\0")) {
418+
if (false !== strpos($message, "@anonymous\0")) {
419419
$logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage();
420420
} else {
421421
$logMessage = $this->levels[$type].': '.$message;
@@ -540,7 +540,7 @@ public function handleException($exception, array $error = null)
540540
$handlerException = null;
541541

542542
if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
543-
if (false !== strpos($message = $exception->getMessage(), "class@anonymous\0")) {
543+
if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) {
544544
$message = (new FlattenException())->setMessage($message)->getMessage();
545545
}
546546
if ($exception instanceof FatalErrorException) {

‎src/Symfony/Component/Debug/Exception/FatalThrowableError.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Debug/Exception/FatalThrowableError.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class FatalThrowableError extends FatalErrorException
2626

2727
public function __construct(\Throwable $e)
2828
{
29-
$this->originalClassName = \get_class($e);
29+
$this->originalClassName = get_debug_type($e);
3030

3131
if ($e instanceof \ParseError) {
3232
$severity = E_PARSE;

‎src/Symfony/Component/Debug/Exception/FlattenException.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Debug/Exception/FlattenException.php
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod
6767
$e->setStatusCode($statusCode);
6868
$e->setHeaders($headers);
6969
$e->setTraceFromThrowable($exception);
70-
$e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception));
70+
$e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : get_debug_type($exception));
7171
$e->setFile($exception->getFile());
7272
$e->setLine($exception->getLine());
7373

@@ -134,7 +134,7 @@ public function getClass()
134134
*/
135135
public function setClass($class)
136136
{
137-
$this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
137+
$this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class;
138138

139139
return $this;
140140
}
@@ -179,9 +179,9 @@ public function getMessage()
179179
*/
180180
public function setMessage($message)
181181
{
182-
if (false !== strpos($message, "class@anonymous\0")) {
183-
$message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
184-
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
182+
if (false !== strpos($message, "@anonymous\0")) {
183+
$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) {
184+
return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
185185
}, $message);
186186
}
187187

‎src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,26 @@ public function testHandleUserError()
325325
}
326326
}
327327

328+
public function testHandleErrorWithAnonymousClass()
329+
{
330+
$handler = ErrorHandler::register();
331+
$handler->throwAt(E_USER_WARNING, true);
332+
try {
333+
$handler->handleError(E_USER_WARNING, 'foo '.\get_class(new class() extends \stdClass {
334+
}).' bar', 'foo.php', 12);
335+
$this->fail('Exception expected.');
336+
} catch (\ErrorException $e) {
337+
} finally {
338+
restore_error_handler();
339+
restore_exception_handler();
340+
}
341+
342+
$this->assertSame('User Warning: foo stdClass@anonymous bar', $e->getMessage());
343+
$this->assertSame(E_USER_WARNING, $e->getSeverity());
344+
$this->assertSame('foo.php', $e->getFile());
345+
$this->assertSame(12, $e->getLine());
346+
}
347+
328348
public function testHandleDeprecation()
329349
{
330350
$logArgCheck = function ($level, $message, $context) {

‎src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,11 @@ public function testAnonymousClass()
355355

356356
$this->assertSame('RuntimeException@anonymous', $flattened->getClass());
357357

358+
$flattened->setClass(\get_class(new class('Oops') extends NotFoundHttpException {
359+
}));
360+
361+
$this->assertSame('Symfony\Component\HttpKernel\Exception\NotFoundHttpException@anonymous', $flattened->getClass());
362+
358363
$flattened = FlattenException::create(new \Exception(sprintf('Class "%s" blah.', \get_class(new class() extends \RuntimeException {
359364
}))));
360365

‎src/Symfony/Component/Debug/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Component/Debug/composer.json
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
],
1818
"require": {
1919
"php": ">=7.1.3",
20-
"psr/log": "~1.0"
20+
"psr/log": "~1.0",
21+
"symfony/polyfill-php80": "^1.15"
2122
},
2223
"conflict": {
2324
"symfony/http-kernel": "<3.4"

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.