8000 [Cache] Prevent fatal errors on php 8 when running concurrently with … · symfony/symfony@33f8496 · GitHub
[go: up one dir, main page]

Skip to content

Commit 33f8496

Browse files
sbelyshkinnicolas-grekas
authored andcommitted
[Cache] Prevent fatal errors on php 8 when running concurrently with TagAwareAdapter v6.1
1 parent f0ffa47 commit 33f8496

File tree

2 files changed

+118
-6
lines changed

2 files changed

+118
-6
lines changed

src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,11 @@ public function hasItem($key)
177177
}
178178

179179
foreach ($this->getTagVersions([$itemTags]) as $tag => $version) {
180-
if ($itemTags[$tag] !== $version && 1 !== $itemTags[$tag] - $version) {
181-
return false;
180+
if ($itemTags[$tag] === $version || \is_int($itemTags[$tag]) && \is_int($version) && 1 === $itemTags[$tag] - $version) {
181+
continue;
182182
}
183+
184+
return false;
183185
}
184186

185187
return true;
@@ -366,10 +368,11 @@ private function generateItems(iterable $items, array $tagKeys)
366368

367369
foreach ($itemTags as $key => $tags) {
368370
foreach ($tags as $tag => $version) {
369-
if ($tagVersions[$tag] !== $version && 1 !== $version - $tagVersions[$tag]) {
370-
unset($itemTags[$key]);
371-
continue 2;
371+
if ($tagVersions[$tag] === $version || \is_int($version) && \is_int($tagVersions[$tag]) && 1 === $version - $tagVersions[$tag]) {
372+
continue;
372373
}
374+
unset($itemTags[$key]);
375+
continue 2;
373376
}
374377
}
375378
$tagVersions = $tagKeys = null;
@@ -408,7 +411,7 @@ private function getTagVersions(array $tagsByKey, array &$invalidatedTags = [])
408411
$tags = [];
409412
foreach ($tagVersions as $tag => $version) {
410413
$tags[$tag.static::TAGS_PREFIX] = $tag;
411-
if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) {
414+
if ($fetchTagVersions || !isset($this->knownTagVersions[$tag]) || !\is_int($version)) {
412415
$fetchTagVersions = true;
413416
continue;
414417
}
@@ -430,6 +433,10 @@ private function getTagVersions(array $tagsByKey, array &$invalidatedTags = [])
430433
if (isset($invalidatedTags[$tag])) {
431434
$invalidatedTags[$tag] = $version->set(++$tagVersions[$tag]);
432435
}
436+
if (!\is_int($tagVersions[$tag])) {
437+
unset($this->knownTagVersions[$tag]);
438+
continue;
439+
}
433440
$this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]];
434441
}
435442

src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,109 @@ private function getNonPruneableMock(): AdapterInterface
234234
{
235235
return $this->createMock(AdapterInterface::class);
236236
}
237+
238+
/**
239+
* @doesNotPerformAssertions
240+
*/
241+
public function testToleranceForStringsAsTagVersionsCase1()
242+
{
243+
$pool = $this->createCachePool();
244+
$adapter = new FilesystemAdapter();
245+
246+
$itemKey = 'foo';
247+
$tag = $adapter->getItem('bar'.TagAwareAdapter::TAGS_PREFIX);
248+
$adapter->save($tag->set("\x00abc\xff"));
249+
$item = $pool->getItem($itemKey);
250+
$pool->save($item->tag('bar'));
251+
$pool->hasItem($itemKey);
252+
$pool->getItem($itemKey);
253+
}
254+
255+
/**
256+
* @doesNotPerformAssertions
257+
*/
258+
public function testToleranceForStringsAsTagVersionsCase2()
259+
{
260+
$pool = $this->createCachePool();
261+
$adapter = new FilesystemAdapter();
262+
263+
$itemKey = 'foo';
264+
$tag = $adapter->getItem('bar'.TagAwareAdapter::TAGS_PREFIX);
265+
$adapter->save($tag->set("\x00abc\xff"));
266+
$item = $pool->getItem($itemKey);
267+
$pool->save($item->tag('bar'));
268+
sleep(100);
269+
$pool->getItem($itemKey);
270+
$pool->hasItem($itemKey);
271+
}
272+
273+
/**
274+
* @doesNotPerformAssertions
275+
*/
276+
public function testToleranceForStringsAsTagVersionsCase3()
277+
{
278+
$pool = $this->createCachePool();
279+
$adapter = new FilesystemAdapter();
280+
281+
$itemKey = 'foo';
282+
$adapter->deleteItem('bar'.TagAwareAdapter::TAGS_PREFIX);
283+
$item = $pool->getItem($itemKey);
284+
$pool->save($item->tag('bar'));
285+
$pool->getItem($itemKey);
286+
287+
$tag = $adapter->getItem('bar'.TagAwareAdapter::TAGS_PREFIX);
288+
$adapter->save($tag->set("\x00abc\xff"));
289+
290+
$pool->hasItem($itemKey);
291+
$pool->getItem($itemKey);
292+
sleep(100);
293+
$pool->getItem($itemKey);
294+
$pool->hasItem($itemKey);
295+
}
296+
297+
/**
298+
* @doesNotPerformAssertions
299+
*/
300+
public function testToleranceForStringsAsTagVersionsCase4()
301+
{
302+
$pool = $this->createCachePool();
303+
$adapter = new FilesystemAdapter();
304+
305+
$itemKey = 'foo';
306+
$tag = $adapter->getItem('bar'.TagAwareAdapter::TAGS_PREFIX);
307+
$adapter->save($tag->set('abcABC'));
308+
309+
$item = $pool->getItem($itemKey);
310+
$pool->save($item->tag('bar'));
311+
312+
$tag = $adapter->getItem('bar'.TagAwareAdapter::TAGS_PREFIX);
313+
$adapter->save($tag->set('001122'));
314+
315+
$pool->invalidateTags(['bar']);
316+
$pool->getItem($itemKey);
317+
}
318+
319+
/**
320+
* @doesNotPerformAssertions
321+
*/
322+
public function testToleranceForStringsAsTagVersionsCase5()
323+
{
324+
$pool = $this->createCachePool();
325+
$pool2 = $this->createCachePool();
326+
$adapter = new FilesystemAdapter();
327+
328+
$itemKey1 = 'foo';
329+
$item = $pool->getItem($itemKey1);
330+
$pool->save($item->tag('bar'));
331+
332+
$tag = $adapter->getItem('bar'.TagAwareAdapter::TAGS_PREFIX);
333+
$adapter->save($tag->set('abcABC'));
334+
335+
$itemKey2 = 'baz';
336+
$item = $pool2->getItem($itemKey2);
337+
$pool2->save($item->tag('bar'));
338+
foreach ($pool->getItems([$itemKey1, $itemKey2]) as $item) {
339+
// run generator
340+
}
341+
}
237342
}

0 commit comments

Comments
 (0)
0