Skip to content

Commit

Permalink
Fix filemtime() warning because of eval'd code (#494)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
andrey-tech and derrabus authored Sep 5, 2024
1 parent b25dcbb commit 253dca4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
5 changes: 3 additions & 2 deletions lib/Doctrine/Common/Annotations/CachedReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use function array_merge;
use function assert;
use function filemtime;
use function is_file;
use function max;
use function time;

Expand Down Expand Up @@ -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()),
Expand All @@ -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())
Expand Down
5 changes: 3 additions & 2 deletions lib/Doctrine/Common/Annotations/PsrCachedReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()),
Expand All @@ -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())
Expand Down
34 changes: 34 additions & 0 deletions tests/Doctrine/Tests/Common/Annotations/CachedReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions tests/Doctrine/Tests/Common/Annotations/PsrCachedReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 253dca4

Please sign in to comment.