From 253dca476f70808a5aeed3a47cc2cc88c5cab915 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 5 Sep 2024 13:15:52 +0300 Subject: [PATCH] Fix filemtime() warning because of eval'd code (#494) * Check is_file before filemtime * Fix PHPStan class not found error * Fix PHPStan error "class not found" * Add check for filename is false * Change class name in two eval'ed snippets * Use an array cache instead of a mock --------- Co-authored-by: Alexander M. Turek --- .../Common/Annotations/CachedReader.php | 5 +-- .../Common/Annotations/PsrCachedReader.php | 5 +-- .../Common/Annotations/CachedReaderTest.php | 34 +++++++++++++++++++ .../Annotations/PsrCachedReaderTest.php | 22 ++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/Common/Annotations/CachedReader.php b/lib/Doctrine/Common/Annotations/CachedReader.php index 85dbefab5..6bd6be3a9 100644 --- a/lib/Doctrine/Common/Annotations/CachedReader.php +++ b/lib/Doctrine/Common/Annotations/CachedReader.php @@ -11,6 +11,7 @@ use function array_merge; use function assert; use function filemtime; +use function is_file; use function max; use function time; @@ -229,7 +230,7 @@ private function getLastModification(ReflectionClass $class): int $parent = $class->getParentClass(); $lastModification = max(array_merge( - [$filename ? filemtime($filename) : 0], + [$filename !== false && is_file($filename) ? filemtime($filename) : 0], array_map(function (ReflectionClass $reflectionTrait): int { return $this->getTraitLastModificationTime($reflectionTrait); }, $class->getTraits()), @@ -253,7 +254,7 @@ private function getTraitLastModificationTime(ReflectionClass $reflectionTrait): } $lastModificationTime = max(array_merge( - [$fileName ? filemtime($fileName) : 0], + [$fileName !== false && is_file($fileName) ? filemtime($fileName) : 0], array_map(function (ReflectionClass $reflectionTrait): int { return $this->getTraitLastModificationTime($reflectionTrait); }, $reflectionTrait->getTraits()) diff --git a/lib/Doctrine/Common/Annotations/PsrCachedReader.php b/lib/Doctrine/Common/Annotations/PsrCachedReader.php index a7099d579..b42da39a7 100644 --- a/lib/Doctrine/Common/Annotations/PsrCachedReader.php +++ b/lib/Doctrine/Common/Annotations/PsrCachedReader.php @@ -12,6 +12,7 @@ use function array_merge; use function assert; use function filemtime; +use function is_file; use function max; use function rawurlencode; use function time; @@ -195,7 +196,7 @@ private function getLastModification(ReflectionClass $class): int $parent = $class->getParentClass(); $lastModification = max(array_merge( - [$filename ? filemtime($filename) : 0], + [$filename !== false && is_file($filename) ? filemtime($filename) : 0], array_map(function (ReflectionClass $reflectionTrait): int { return $this->getTraitLastModificationTime($reflectionTrait); }, $class->getTraits()), @@ -219,7 +220,7 @@ private function getTraitLastModificationTime(ReflectionClass $reflectionTrait): } $lastModificationTime = max(array_merge( - [$fileName ? filemtime($fileName) : 0], + [$fileName !== false && is_file($fileName) ? filemtime($fileName) : 0], array_map(function (ReflectionClass $reflectionTrait): int { return $this->getTraitLastModificationTime($reflectionTrait); }, $reflectionTrait->getTraits()) diff --git a/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php b/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php index 63537e0d4..536b468ff 100644 --- a/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php +++ b/tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php @@ -7,11 +7,13 @@ use Doctrine\Common\Annotations\Reader; use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\Cache; +use Doctrine\Common\Cache\Psr6\DoctrineProvider; use Doctrine\Tests\Common\Annotations\Fixtures\Annotation\Route; use Doctrine\Tests\Common\Annotations\Fixtures\ClassThatUsesTraitThatUsesAnotherTraitWithMethods; use PHPUnit\Framework\MockObject\MockObject; use ReflectionClass; use ReflectionMethod; +use Symfony\Component\Cache\Adapter\ArrayAdapter; use function assert; use function class_exists; @@ -225,6 +227,38 @@ public function testAvoidCallingFilemtimeTooMuch(): void $this->assertEquals([$route2], $reader->getMethodAnnotations(new ReflectionMethod($className, 'method2'))); } + /** + * @group 62 + */ + public function testReaderDoesNotCacheIfFileDoesNotExistSoLastModificationCannotBeDetermined(): void + { + $code = <<<'EOS' +namespace Doctrine\Tests\Common\Annotations; + +/** + * @\Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass("Some data") + */ +class CachedEvalClass { + +} +EOS; + + eval($code); + + if (class_exists(ArrayCache::class)) { + $cache = new ArrayCache(); + } else { + $cache = DoctrineProvider::wrap(new ArrayAdapter()); + } + + $reader = new CachedReader(new AnnotationReader(), $cache, true); + // @phpstan-ignore class.notFound + $readAnnotations = $reader->getClassAnnotations(new ReflectionClass(CachedEvalClass::class)); + + self::assertIsArray($readAnnotations); + self::assertCount(1, $readAnnotations); + } + protected function doTestCacheStale(string $className, int $lastCacheModification): CachedReader { $cacheKey = $className; diff --git a/tests/Doctrine/Tests/Common/Annotations/PsrCachedReaderTest.php b/tests/Doctrine/Tests/Common/Annotations/PsrCachedReaderTest.php index 5d3809fce..ca9a259e2 100644 --- a/tests/Doctrine/Tests/Common/Annotations/PsrCachedReaderTest.php +++ b/tests/Doctrine/Tests/Common/Annotations/PsrCachedReaderTest.php @@ -220,6 +220,28 @@ public function testReaderIsNotHitIfCacheIsFresh(): void ); } + public function testReaderDoesNotCacheIfFileDoesNotExistSoLastModificationCannotBeDetermined(): void + { + $code = <<<'EOS' +namespace Doctrine\Tests\Common\Annotations; + +/** + * @\Doctrine\Tests\Common\Annotations\Fixtures\AnnotationTargetClass("Some data") + */ +class PsrCachedEvalClass { + +} +EOS; + + eval($code); + + $reader = new PsrCachedReader(new AnnotationReader(), new ArrayAdapter(), true); + // @phpstan-ignore class.notFound + $readAnnotations = $reader->getClassAnnotations(new ReflectionClass(PsrCachedEvalClass::class)); + + self::assertCount(1, $readAnnotations); + } + protected function doTestCacheStale(string $className, int $lastCacheModification): PsrCachedReader { $cacheKey = rawurlencode($className);