diff --git a/core/lib/Drupal/Core/Flood/MemoryBackend.php b/core/lib/Drupal/Core/Flood/MemoryBackend.php index 9899e35e7ee1ac012b163b8f50f7850ea1dc16d2..062471b3db8f6e70af5796a3407158c143a7569a 100644 --- a/core/lib/Drupal/Core/Flood/MemoryBackend.php +++ b/core/lib/Drupal/Core/Flood/MemoryBackend.php @@ -41,7 +41,7 @@ public function register($name, $window = 3600, $identifier = NULL) { // We can't use REQUEST_TIME here, because that would not guarantee // uniqueness. $time = microtime(TRUE); - $this->events[$name][$identifier][$time + $window] = $time; + $this->events[$name][$identifier][] = ['expire' => $time + $window, 'time' => $time]; } /** @@ -65,8 +65,8 @@ public function isAllowed($name, $threshold, $window = 3600, $identifier = NULL) return $threshold > 0; } $limit = microtime(TRUE) - $window; - $number = count(array_filter($this->events[$name][$identifier], function ($timestamp) use ($limit) { - return $timestamp > $limit; + $number = count(array_filter($this->events[$name][$identifier], function ($entry) use ($limit) { + return $entry['time'] > $limit; })); return ($number < $threshold); } @@ -76,12 +76,10 @@ public function isAllowed($name, $threshold, $window = 3600, $identifier = NULL) */ public function garbageCollection() { foreach ($this->events as $name => $identifiers) { - foreach ($this->events[$name] as $identifier => $timestamps) { - // Filter by key (expiration) but preserve key => value associations. - $this->events[$name][$identifier] = array_filter($timestamps, function () use (&$timestamps) { - $expiration = key($timestamps); - next($timestamps); - return $expiration > microtime(TRUE); + foreach ($this->events[$name] as $identifier => $entries) { + // Remove expired entries. + $this->events[$name][$identifier] = array_filter($entries, function ($entry) { + return $entry['expire'] > microtime(TRUE); }); } } diff --git a/core/modules/system/tests/src/Kernel/System/FloodTest.php b/core/modules/system/tests/src/Kernel/System/FloodTest.php index cf32fd9fed7608543657a0a75fd4af53ad9c9c1a..97b78aa974e644f9aa5a111e880890fdeeb94c98 100644 --- a/core/modules/system/tests/src/Kernel/System/FloodTest.php +++ b/core/modules/system/tests/src/Kernel/System/FloodTest.php @@ -74,6 +74,18 @@ public function testMemoryBackend() { $this->assertFalse($flood->isAllowed($name, $threshold)); } + /** + * Tests memory backend records events to the nearest microsecond. + */ + public function testMemoryBackendThreshold() { + $request_stack = \Drupal::service('request_stack'); + $flood = new MemoryBackend($request_stack); + $flood->register('new event'); + $this->assertTrue($flood->isAllowed('new event', '2')); + $flood->register('new event'); + $this->assertFalse($flood->isAllowed('new event', '2')); + } + /** * Tests flood control database backend. */