Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions src/Illuminate/Cache/RedisTaggedCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,44 @@ public function forever($key, $value)
*/
public function flush()
{
$this->flushValues();
$this->tags->flush();
/** @var \Illuminate\Cache\RedisStore $redis_store */
$redis_store = $this->store;

$redis_connection = $redis_store->connection();
$redis_prefix = match ($redis_connection::class) {
\Illuminate\Redis\Connections\PhpRedisConnection::class => $redis_connection->client()->getOption(\Redis::OPT_PREFIX),
\Illuminate\Redis\Connections\PredisConnection::class => $redis_connection->client()->getOptions()->prefix,
};

/** @var \Illuminate\Cache\RedisTagSet $redis_tag_set */
$redis_tag_set = $this->tags;
$entries = $redis_tag_set->entries();

$cache_tags = [];
$need_deleted_keys = [];

$cache_prefix = $redis_prefix.$redis_store->getPrefix();

foreach ($this->tags->getNames() as $name) {
$cache_tags[] = $cache_prefix.$this->tags->tagId($name);
}

foreach ($entries as $entry) {
$need_deleted_keys[] = $redis_store->getPrefix().$entry;
}

$lua_script = <<<'LUA'
local prefix = table.remove(ARGV, 1)
for i, key in ipairs(KEYS) do
redis.call('DEL', key)
for j, arg in ipairs(ARGV) do
local zkey = string.gsub(key, prefix, "")
redis.call('ZREM', arg, zkey)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this line violates:

Important: to ensure the correct execution of scripts, both in standalone and clustered deployments, all names of keys that a script accesses must be explicitly provided as input key arguments. The script should only access keys whose names are given as input arguments. Scripts should never access keys with programmatically-generated names or based on the contents of data structures stored in the database.

Because the key name is taken from ARGV instead of KEYS.

Copy link
Author

@zengbo zengbo Aug 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KEYS and ARGV are not the same.
KEYS represent cache entries within the cache tag, while ARGV stands for cache tag keys.
I utilize key for KEYS and zkey for ARGV.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The arg parameter is the key that ZREM operates on and it is taken from ARGV.

end
end
LUA;

$redis_connection->eval($lua_script, count($need_deleted_keys), ...$need_deleted_keys, ...[$cache_prefix, ...$cache_tags]);

return true;
}
Expand Down