This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new 98857f25 fix(script): disable exclusive commands to be executed in 
scripting (#2732)
98857f25 is described below

commit 98857f2550bfc1e2450b4341f09f9805b6350eed
Author: Twice <[email protected]>
AuthorDate: Sat Jan 25 14:03:44 2025 +0800

    fix(script): disable exclusive commands to be executed in scripting (#2732)
---
 src/commands/cmd_function.cc |  2 +-
 src/commands/cmd_script.cc   |  4 ++--
 src/commands/cmd_server.cc   | 10 +++++++++-
 src/commands/commander.h     |  8 ++------
 src/storage/scripting.cc     |  8 +++++++-
 5 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/src/commands/cmd_function.cc b/src/commands/cmd_function.cc
index 3854b2b0..82773e5f 100644
--- a/src/commands/cmd_function.cc
+++ b/src/commands/cmd_function.cc
@@ -102,7 +102,7 @@ struct CommandFCall : Commander {
 CommandKeyRange GetScriptEvalKeyRange(const std::vector<std::string> &args);
 
 uint64_t GenerateFunctionFlags(uint64_t flags, const std::vector<std::string> 
&args) {
-  if (util::EqualICase(args[1], "load") || util::EqualICase(args[1], 
"delete")) {
+  if (args.size() >= 2 && (util::EqualICase(args[1], "load") || 
util::EqualICase(args[1], "delete"))) {
     return flags | kCmdWrite;
   }
 
diff --git a/src/commands/cmd_script.cc b/src/commands/cmd_script.cc
index 3030a81e..1b3f287d 100644
--- a/src/commands/cmd_script.cc
+++ b/src/commands/cmd_script.cc
@@ -118,7 +118,7 @@ CommandKeyRange GetScriptEvalKeyRange(const 
std::vector<std::string> &args) {
 }
 
 uint64_t GenerateScriptFlags(uint64_t flags, const std::vector<std::string> 
&args) {
-  if (util::EqualICase(args[1], "load") || util::EqualICase(args[1], "flush")) 
{
+  if (args.size() >= 2 && (util::EqualICase(args[1], "load") || 
util::EqualICase(args[1], "flush"))) {
     return flags | kCmdWrite;
   }
 
@@ -129,6 +129,6 @@ REDIS_REGISTER_COMMANDS(Script, 
MakeCmdAttr<CommandEval>("eval", -3, "write no-s
                         MakeCmdAttr<CommandEvalSHA>("evalsha", -3, "write 
no-script", GetScriptEvalKeyRange),
                         MakeCmdAttr<CommandEvalRO>("eval_ro", -3, "read-only 
no-script", GetScriptEvalKeyRange),
                         MakeCmdAttr<CommandEvalSHARO>("evalsha_ro", -3, 
"read-only no-script", GetScriptEvalKeyRange),
-                        MakeCmdAttr<CommandScript>("script", -2, "exclusive 
no-script", NO_KEY), )
+                        MakeCmdAttr<CommandScript>("script", -2, "exclusive 
no-script", NO_KEY, GenerateScriptFlags), )
 
 }  // namespace redis
diff --git a/src/commands/cmd_server.cc b/src/commands/cmd_server.cc
index de21a8b5..25447c62 100644
--- a/src/commands/cmd_server.cc
+++ b/src/commands/cmd_server.cc
@@ -646,6 +646,14 @@ class CommandDebug : public Commander {
     return Status::OK();
   }
 
+  static uint64_t FlagGen(uint64_t flags, const std::vector<std::string> 
&args) {
+    if (args.size() >= 2 && util::EqualICase(args[1], "protocol")) {
+      return flags & ~kCmdExclusive;
+    }
+
+    return flags;
+  }
+
  private:
   std::string subcommand_;
   std::string protocol_type_;
@@ -1348,7 +1356,7 @@ REDIS_REGISTER_COMMANDS(Server, 
MakeCmdAttr<CommandAuth>("auth", 2, "read-only o
                         MakeCmdAttr<CommandQuit>("quit", 1, "read-only", 
NO_KEY),
                         MakeCmdAttr<CommandScan>("scan", -2, "read-only", 
NO_KEY),
                         MakeCmdAttr<CommandRandomKey>("randomkey", 1, 
"read-only", NO_KEY),
-                        MakeCmdAttr<CommandDebug>("debug", -2, "read-only 
exclusive", NO_KEY),
+                        MakeCmdAttr<CommandDebug>("debug", -2, "read-only 
exclusive", NO_KEY, CommandDebug::FlagGen),
                         MakeCmdAttr<CommandCommand>("command", -1, 
"read-only", NO_KEY),
                         MakeCmdAttr<CommandEcho>("echo", 2, "read-only", 
NO_KEY),
                         MakeCmdAttr<CommandTime>("time", 1, "read-only 
ok-loading", NO_KEY),
diff --git a/src/commands/commander.h b/src/commands/commander.h
index f0589c92..a91a44f0 100644
--- a/src/commands/commander.h
+++ b/src/commands/commander.h
@@ -333,13 +333,9 @@ inline uint64_t ParseCommandFlags(const std::string 
&description, const std::str
       flags |= kCmdSlow;
     else if (flag == "auth")
       flags |= kCmdAuth;
-    else if (flag == "blocking") {
+    else if (flag == "blocking")
       flags |= kCmdBlocking;
-
-      // blocking commands should always be no-script
-      // TODO: we can relax this restriction if scripting becomes non-exclusive
-      flags |= kCmdNoScript;
-    } else {
+    else {
       std::cout << fmt::format("Encountered non-existent flag '{}' in command 
{} in command attribute parsing", flag,
                                cmd_name)
                 << std::endl;
diff --git a/src/storage/scripting.cc b/src/storage/scripting.cc
index 5d9c8860..19b13854 100644
--- a/src/storage/scripting.cc
+++ b/src/storage/scripting.cc
@@ -767,7 +767,13 @@ int RedisGenericCommand(lua_State *lua, int raise_error) {
     return raise_error ? RaiseError(lua) : 1;
   }
 
-  if (cmd_flags & redis::kCmdNoScript) {
+  if ((cmd_flags & redis::kCmdNoScript) || (cmd_flags & redis::kCmdExclusive)) 
{
+    PushError(lua, "This Redis command is not allowed from scripts");
+    return raise_error ? RaiseError(lua) : 1;
+  }
+
+  // TODO: fix blocking commands to make them work in scripting
+  if (cmd_flags & redis::kCmdBlocking) {
     PushError(lua, "This Redis command is not allowed from scripts");
     return raise_error ? RaiseError(lua) : 1;
   }

Reply via email to