Skip to content

Commit c2a5991

Browse files
[Config] ConfigCache::isFresh() should return false on __PHP_Incomplete_Class
1 parent 777cdfc commit c2a5991

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/Symfony/Component/Config/ConfigCache.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class ConfigCache implements ConfigCacheInterface
2828
private $debug;
2929
private $file;
3030

31+
private static $unserializeSignalingException;
32+
3133
/**
3234
* @param string $file The absolute cache path
3335
* @param bool $debug Whether debugging is enabled or not
@@ -85,8 +87,33 @@ public function isFresh()
8587
return false;
8688
}
8789

90+
$e = null;
91+
$meta = false;
8892
$time = filemtime($this->file);
89-
$meta = unserialize(file_get_contents($metadata));
93+
$signalingException = new \UnexpectedValueException();
94+
$prevUnserializeHandler = ini_set('unserialize_callback_func', '');
95+
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context) use (&$prevErrorHandler, $signalingException) {
96+
if (E_WARNING === $type && 'Class __PHP_Incomplete_Class has no unserializer' === $msg) {
97+
throw $signalingException;
98+
}
99+
100+
return $prevErrorHandler && $prevErrorHandler($type, $msg, $file, $line, $context);
101+
});
102+
103+
try {
104+
$meta = unserialize(file_get_contents($metadata));
105+
} catch (\Error $e) {
106+
} catch (\Exception $e) {
107+
}
108+
restore_error_handler();
109+
ini_set('unserialize_callback_func', $prevUnserializeHandler);
110+
if (null !== $e && $e !== $signalingException) {
111+
throw $e;
112+
}
113+
if (false === $meta) {
114+
return false;
115+
}
116+
90117
foreach ($meta as $resource) {
91118
if (!$resource->isFresh($time)) {
92119
return false;

src/Symfony/Component/Config/Tests/ConfigCacheTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ public function testCacheIsNotFreshIfOneOfTheResourcesIsNotFresh()
9393
$this->assertFalse($cache->isFresh());
9494
}
9595

96+
public function testCacheIsNotFreshWhenUnserializeFails()
97+
{
98+
file_put_contents($this->metaFile, str_replace('FileResource', 'ClassNotHere', file_get_contents($this->metaFile)));
99+
100+
$cache = new ConfigCache($this->cacheFile, true);
101+
102+
$this->assertFalse($cache->isFresh());
103+
}
104+
96105
public function testWriteDumpsFile()
97106
{
98107
unlink($this->cacheFile);

0 commit comments

Comments
 (0)