Skip to content

Commit 88673ab

Browse files
Merge branch '10.5' into 11.3
2 parents d92ac4f + 7888430 commit 88673ab

File tree

7 files changed

+68
-0
lines changed

7 files changed

+68
-0
lines changed

ChangeLog-11.3.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ All notable changes of the PHPUnit 11.3 release series are documented in this fi
77
### Fixed
88

99
* [#5950](https://github.com/sebastianbergmann/phpunit/pull/5950): TestDox text should not be `trim()`med when it contains `$` character
10+
* The attribute parser will no longer try to instantiate attribute classes that do not exist
1011

1112
## [11.3.5] - 2024-09-13
1213

src/Metadata/Parser/AnnotationParser.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use function array_merge;
1313
use function assert;
14+
use function class_exists;
1415
use function count;
1516
use function explode;
1617
use function method_exists;
@@ -60,6 +61,8 @@ final class AnnotationParser implements Parser
6061
*/
6162
public function forClass(string $className): MetadataCollection
6263
{
64+
assert(class_exists($className));
65+
6366
$result = [];
6467

6568
foreach (AnnotationRegistry::getInstance()->forClassName($className)->symbolAnnotations() as $annotation => $values) {
@@ -206,6 +209,9 @@ public function forClass(string $className): MetadataCollection
206209
*/
207210
public function forMethod(string $className, string $methodName): MetadataCollection
208211
{
212+
assert(class_exists($className));
213+
assert(method_exists($className, $methodName));
214+
209215
$result = [];
210216

211217
foreach (AnnotationRegistry::getInstance()->forMethod($className, $methodName)->symbolAnnotations() as $annotation => $values) {

src/Metadata/Parser/AttributeParser.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
use const JSON_THROW_ON_ERROR;
1313
use function assert;
14+
use function class_exists;
1415
use function json_decode;
16+
use function method_exists;
1517
use function sprintf;
1618
use function str_starts_with;
1719
use function strtolower;
@@ -91,13 +93,19 @@
9193
*/
9294
public function forClass(string $className): MetadataCollection
9395
{
96+
assert(class_exists($className));
97+
9498
$result = [];
9599

96100
foreach ((new ReflectionClass($className))->getAttributes() as $attribute) {
97101
if (!str_starts_with($attribute->getName(), 'PHPUnit\\Framework\\Attributes\\')) {
98102
continue;
99103
}
100104

105+
if (!class_exists($attribute->getName())) {
106+
continue;
107+
}
108+
101109
$attributeInstance = $attribute->newInstance();
102110

103111
switch ($attribute->getName()) {
@@ -369,13 +377,20 @@ public function forClass(string $className): MetadataCollection
369377
*/
370378
public function forMethod(string $className, string $methodName): MetadataCollection
371379
{
380+
assert(class_exists($className));
381+
assert(method_exists($className, $methodName));
382+
372383
$result = [];
373384

374385
foreach ((new ReflectionMethod($className, $methodName))->getAttributes() as $attribute) {
375386
if (!str_starts_with($attribute->getName(), 'PHPUnit\\Framework\\Attributes\\')) {
376387
continue;
377388
}
378389

390+
if (!class_exists($attribute->getName())) {
391+
continue;
392+
}
393+
379394
$attributeInstance = $attribute->newInstance();
380395

381396
switch ($attribute->getName()) {

src/Metadata/Parser/CachingParser.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
*/
1010
namespace PHPUnit\Metadata\Parser;
1111

12+
use function assert;
13+
use function class_exists;
14+
use function method_exists;
1215
use PHPUnit\Metadata\MetadataCollection;
1316

1417
/**
@@ -45,6 +48,8 @@ public function __construct(Parser $reader)
4548
*/
4649
public function forClass(string $className): MetadataCollection
4750
{
51+
assert(class_exists($className));
52+
4853
if (isset($this->classCache[$className])) {
4954
return $this->classCache[$className];
5055
}
@@ -60,6 +65,9 @@ public function forClass(string $className): MetadataCollection
6065
*/
6166
public function forMethod(string $className, string $methodName): MetadataCollection
6267
{
68+
assert(class_exists($className));
69+
assert(method_exists($className, $methodName));
70+
6371
$key = $className . '::' . $methodName;
6472

6573
if (isset($this->methodCache[$key])) {

src/Metadata/Parser/ParserChain.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
*/
1010
namespace PHPUnit\Metadata\Parser;
1111

12+
use function assert;
13+
use function class_exists;
14+
use function method_exists;
1215
use PHPUnit\Metadata\MetadataCollection;
1316

1417
/**
@@ -32,6 +35,8 @@ public function __construct(Parser $attributeReader, Parser $annotationReader)
3235
*/
3336
public function forClass(string $className): MetadataCollection
3437
{
38+
assert(class_exists($className));
39+
3540
$metadata = $this->attributeReader->forClass($className);
3641

3742
if (!$metadata->isEmpty()) {
@@ -47,6 +52,9 @@ public function forClass(string $className): MetadataCollection
4752
*/
4853
public function forMethod(string $className, string $methodName): MetadataCollection
4954
{
55+
assert(class_exists($className));
56+
assert(method_exists($className, $methodName));
57+
5058
$metadata = $this->attributeReader->forMethod($className, $methodName);
5159

5260
if (!$metadata->isEmpty()) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TestFixture\Metadata\Attribute;
11+
12+
use PHPUnit\Framework\Attributes\PhpunitAttributeThatDoesNotExist;
13+
use PHPUnit\Framework\TestCase;
14+
15+
#[PhpunitAttributeThatDoesNotExist]
16+
final class PhpunitAttributeThatDoesNotExistTest extends TestCase
17+
{
18+
#[PhpunitAttributeThatDoesNotExist]
19+
public function testOne(): void
20+
{
21+
}
22+
}

tests/unit/Metadata/Parser/AttributeParserTestCase.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
use PHPUnit\TestFixture\Metadata\Attribute\LargeTest;
3838
use PHPUnit\TestFixture\Metadata\Attribute\MediumTest;
3939
use PHPUnit\TestFixture\Metadata\Attribute\NonPhpunitAttributeTest;
40+
use PHPUnit\TestFixture\Metadata\Attribute\PhpunitAttributeThatDoesNotExistTest;
4041
use PHPUnit\TestFixture\Metadata\Attribute\PreserveGlobalStateTest;
4142
use PHPUnit\TestFixture\Metadata\Attribute\ProcessIsolationTest;
4243
use PHPUnit\TestFixture\Metadata\Attribute\RequiresFunctionTest;
@@ -995,5 +996,12 @@ public function test_ignores_attributes_not_owned_by_PHPUnit(): void
995996
$this->assertTrue($metadata->isEmpty());
996997
}
997998

999+
public function test_ignores_attributes_in_PHPUnit_namespace_that_do_not_exist(): void
1000+
{
1001+
$metadata = $this->parser()->forClassAndMethod(PhpunitAttributeThatDoesNotExistTest::class, 'testOne');
1002+
1003+
$this->assertTrue($metadata->isEmpty());
1004+
}
1005+
9981006
abstract protected function parser(): Parser;
9991007
}

0 commit comments

Comments
 (0)