[Cache] Prevent notice on case matching metadata trick

On saving an array of one element with a int key of strlen 10
it matches the first conditions of the trick used to save metadata.

> Notice: Trying to access array offset on value of type int

Casting it to string fixes it.
This commit is contained in:
Bastien Jaillot 2020-12-09 23:09:03 +01:00 committed by Nicolas Grekas
parent 2dd4561d3f
commit a91ac74906
3 changed files with 26 additions and 2 deletions

View File

@ -51,7 +51,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
// Detect wrapped values that encode for their expiry and creation duration
// For compactness, these values are packed in the key of an array using
// magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
$item->value = $v[$k];
$v = unpack('Ve/Nc', substr($k, 1, -1));
$item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;

View File

@ -59,7 +59,7 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
// Detect wrapped values that encode for their expiry and creation duration
// For compactness, these values are packed in the key of an array using
// magic numbers in the form 9D-..-..-..-..-00-..-..-..-5F
if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
if (\is_array($v) && 1 === \count($v) && 10 === \strlen($k = (string) key($v)) && "\x9D" === $k[0] && "\0" === $k[5] && "\x5F" === $k[9]) {
$item->value = $v[$k];
$v = unpack('Ve/Nc', substr($k, 1, -1));
$item->metadata[CacheItem::METADATA_EXPIRY] = $v['e'] + CacheItem::METADATA_EXPIRY_OFFSET;

View File

@ -272,6 +272,30 @@ abstract class AdapterTestCase extends CachePoolTest
$this->assertFalse($cache->hasItem('foobar'));
$this->assertTrue($cache->hasItem('barfoo'));
}
public function testWeirdDataMatchingMetadataWrappedValues()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createCachePool(0, __FUNCTION__);
$cache->clear();
$item = $cache->getItem('foobar');
// it should be an array containing only one element
// with key having a strlen of 10.
$weirdDataMatchingMedatataWrappedValue = [
1234567890 => [
1,
],
];
$cache->save($item->set($weirdDataMatchingMedatataWrappedValue));
$this->assertTrue($cache->hasItem('foobar'));
}
}
class NotUnserializable