From 91e01793cb7c248db19b4add75b64efc823d8a5f Mon Sep 17 00:00:00 2001
From: catch <6915-catch@users.noreply.drupalcode.org>
Date: Mon, 23 Dec 2024 11:11:24 +0000
Subject: [PATCH] Issue #3395212 by nicxvan, deborahblessy, murilohp,
 smustgrave, fabianx, kristiaanvandeneynde: Ensure invalid items are not
 written to FastBackend in ChainedFast

(cherry picked from commit e6b0b85ee8071c490af0d9ea6dfb1a5c84029218)
---
 .../Drupal/Core/Cache/ChainedFastBackend.php  |  4 +-
 .../Core/Cache/ChainedFastBackendTest.php     | 42 +++++++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/core/lib/Drupal/Core/Cache/ChainedFastBackend.php b/core/lib/Drupal/Core/Cache/ChainedFastBackend.php
index 7426aba15133..21e8ce360936 100644
--- a/core/lib/Drupal/Core/Cache/ChainedFastBackend.php
+++ b/core/lib/Drupal/Core/Cache/ChainedFastBackend.php
@@ -166,7 +166,9 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) {
     if ($cids) {
       foreach ($this->consistentBackend->getMultiple($cids, $allow_invalid) as $item) {
         $cache[$item->cid] = $item;
-        $this->fastBackend->set($item->cid, $item->data, $item->expire, $item->tags);
+        if (!$allow_invalid || $item->valid) {
+          $this->fastBackend->set($item->cid, $item->data, $item->expire, $item->tags);
+        }
       }
     }
 
diff --git a/core/tests/Drupal/Tests/Core/Cache/ChainedFastBackendTest.php b/core/tests/Drupal/Tests/Core/Cache/ChainedFastBackendTest.php
index 653f5d7b552d..836e26d01400 100644
--- a/core/tests/Drupal/Tests/Core/Cache/ChainedFastBackendTest.php
+++ b/core/tests/Drupal/Tests/Core/Cache/ChainedFastBackendTest.php
@@ -5,6 +5,7 @@
 namespace Drupal\Tests\Core\Cache;
 
 use Drupal\Component\Datetime\Time;
+use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\ChainedFastBackend;
 use Drupal\Core\Cache\MemoryBackend;
 use Drupal\Tests\UnitTestCase;
@@ -61,6 +62,47 @@ public function testGetDoesNotHitConsistentBackend(): void {
     $this->assertEquals('baz', $chained_fast_backend->get('foo')->data);
   }
 
+  /**
+   * Tests a get() on consistent backend without saving on fast backend.
+   */
+  public function testSetInvalidDataFastBackend(): void {
+    $cid = $this->randomString();
+    $item = (object) [
+      'cid' => $cid,
+      'data' => serialize($this->randomObject()),
+      'created' => ChainedFastBackend::LAST_WRITE_TIMESTAMP_PREFIX . 'cache_foo',
+      'expire' => Cache::PERMANENT,
+      'tags' => [],
+      'valid' => FALSE,
+    ];
+
+    $consistent_cache = $this->createMock('Drupal\Core\Cache\CacheBackendInterface');
+
+    $consistent_cache->expects($this->once())
+      ->method('get')
+      ->withAnyParameters()
+      ->willReturn(FALSE);
+    $consistent_cache->expects($this->once())
+      ->method('getMultiple')
+      ->withAnyParameters()
+      ->willReturn([$item]);
+
+    $fast_cache = new MemoryBackend(new Time());
+
+    $chained_fast_backend = new ChainedFastBackend(
+      $consistent_cache,
+      $fast_cache,
+      'foo'
+    );
+
+    // Perform a get using the allowing invalid data parameter.
+    $this->assertEquals($item, $chained_fast_backend->get($cid, TRUE));
+
+    // Perform a get directly on the fast cache to guarantee the invalid data
+    // were not saved there.
+    $this->assertEquals(NULL, $fast_cache->get($cid), 'Invalid data was not saved on the fast cache.');
+  }
+
   /**
    * Tests a fast cache miss gets data from the consistent cache backend.
    */
-- 
GitLab