Unverified Commit 4f58848a authored by Gunnar Liljas's avatar Gunnar Liljas Committed by GitHub

Fix keyspace isolation with ScriptEvaluateAsync (#1377)

Co-authored-by: 's avatarGunnar Liljas <gunnar.liljas@revide.se>
parent 659d5149
......@@ -221,7 +221,7 @@ public Task<bool> KeyExpireAsync(RedisKey key, TimeSpan? expiry, CommandFlags fl
return Inner.KeyExpireAsync(ToInner(key), expiry, flags);
}
public Task<TimeSpan?> KeyIdleTimeAsync(RedisKey key,CommandFlags flags = CommandFlags.None)
public Task<TimeSpan?> KeyIdleTimeAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{
return Inner.KeyIdleTimeAsync(ToInner(key), flags);
}
......@@ -386,12 +386,14 @@ public Task<RedisResult> ScriptEvaluateAsync(string script, RedisKey[] keys = nu
public Task<RedisResult> ScriptEvaluateAsync(LuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{
return Inner.ScriptEvaluateAsync(script, parameters, flags);
// TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those?
return script.EvaluateAsync(Inner, parameters, Prefix, flags);
}
public Task<RedisResult> ScriptEvaluateAsync(LoadedLuaScript script, object parameters = null, CommandFlags flags = CommandFlags.None)
{
return Inner.ScriptEvaluateAsync(script, parameters, flags);
// TODO: The return value could contain prefixed keys. It might make sense to 'unprefix' those?
return script.EvaluateAsync(Inner, parameters, Prefix, flags);
}
public Task<long> SetAddAsync(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None)
......@@ -908,12 +910,12 @@ protected ICollection<object> ToInner(ICollection<object> args)
{
var withPrefix = new object[args.Count];
int i = 0;
foreach(var oldArg in args)
foreach (var oldArg in args)
{
object newArg;
if (oldArg is RedisKey key)
{
newArg = ToInner(key);
newArg = ToInner(key);
}
else if (oldArg is RedisChannel channel)
{
......
......@@ -856,6 +856,32 @@ public void LuaScriptWithWrappedDatabase()
}
}
[Fact]
public async Task AsyncLuaScriptWithWrappedDatabase()
{
const string Script = "redis.call('set', @key, @value)";
using (var conn = Create(allowAdmin: true))
{
Skip.IfMissingFeature(conn, nameof(RedisFeatures.Scripting), f => f.Scripting);
var db = conn.GetDatabase();
var wrappedDb = KeyspaceIsolation.DatabaseExtensions.WithKeyPrefix(db, "prefix-");
var key = Me();
await db.KeyDeleteAsync(key, CommandFlags.FireAndForget);
var prepared = LuaScript.Prepare(Script);
await wrappedDb.ScriptEvaluateAsync(prepared, new { key = (RedisKey)key, value = 123 });
var val1 = await wrappedDb.StringGetAsync(key);
Assert.Equal(123, (int)val1);
var val2 = await db.StringGetAsync("prefix-" + key);
Assert.Equal(123, (int)val2);
var val3 = await db.StringGetAsync(key);
Assert.True(val3.IsNull);
}
}
[Fact]
public void LoadedLuaScriptWithWrappedDatabase()
{
......@@ -883,6 +909,33 @@ public void LoadedLuaScriptWithWrappedDatabase()
}
}
[Fact]
public async Task AsyncLoadedLuaScriptWithWrappedDatabase()
{
const string Script = "redis.call('set', @key, @value)";
using (var conn = Create(allowAdmin: true))
{
Skip.IfMissingFeature(conn, nameof(RedisFeatures.Scripting), f => f.Scripting);
var db = conn.GetDatabase();
var wrappedDb = KeyspaceIsolation.DatabaseExtensions.WithKeyPrefix(db, "prefix2-");
var key = Me();
await db.KeyDeleteAsync(key, CommandFlags.FireAndForget);
var server = conn.GetServer(conn.GetEndPoints()[0]);
var prepared = await LuaScript.Prepare(Script).LoadAsync(server);
await wrappedDb.ScriptEvaluateAsync(prepared, new { key = (RedisKey)key, value = 123 }, flags: CommandFlags.FireAndForget);
var val1 = await wrappedDb.StringGetAsync(key);
Assert.Equal(123, (int)val1);
var val2 = await db.StringGetAsync("prefix2-" + key);
Assert.Equal(123, (int)val2);
var val3 = await db.StringGetAsync(key);
Assert.True(val3.IsNull);
}
}
[Fact]
public void ScriptWithKeyPrefixViaTokens()
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment