diff --git a/src/server.c b/src/server.c index c707699e6..91cd5980d 100644 --- a/src/server.c +++ b/src/server.c @@ -4037,6 +4037,12 @@ int processCommand(client *c) { return C_OK; } + /* Not allow several UNSUBSCRIBE commands executed under non-pubsub mode */ + if (!c->flag.pubsub && (c->cmd->proc == unsubscribeCommand || c->cmd->proc == sunsubscribeCommand || + c->cmd->proc == punsubscribeCommand)) { + rejectCommandFormat(c, "-NOSUB '%s' command executed not in subscribed mode", c->cmd->fullname); + return C_OK; + } /* Only allow commands with flag "t", such as INFO, REPLICAOF and so on, * when replica-serve-stale-data is no and we are a replica with a broken * link with primary. */ diff --git a/tests/unit/info.tcl b/tests/unit/info.tcl index 278a1d8e3..61d1acd1f 100644 --- a/tests/unit/info.tcl +++ b/tests/unit/info.tcl @@ -424,7 +424,8 @@ start_server {tags {"info" "external:skip"}} { set info [r info clients] assert_equal [getInfoProperty $info pubsub_clients] {1} # non-pubsub clients should not be involved - assert_equal {0} [unsubscribe $rd2 {non-exist-chan}] + catch {unsubscribe $rd2 {non-exist-chan}} e + assert_match {*NOSUB*} $e set info [r info clients] assert_equal [getInfoProperty $info pubsub_clients] {1} # close all clients diff --git a/tests/unit/pubsub.tcl b/tests/unit/pubsub.tcl index 72d0498ce..68dc79a4a 100644 --- a/tests/unit/pubsub.tcl +++ b/tests/unit/pubsub.tcl @@ -109,10 +109,12 @@ start_server {tags {"pubsub network"}} { $rd1 close } - test "UNSUBSCRIBE from non-subscribed channels" { + test "UNSUBSCRIBE and PUNSUBSCRIBE from non-subscribed channels" { set rd1 [valkey_deferring_client] - assert_equal {0 0 0} [unsubscribe $rd1 {foo bar quux}] - + foreach command {unsubscribe punsubscribe} { + catch {$command $rd1 {foo bar quux}} e + assert_match {*NOSUB*} $e + } # clean up clients $rd1 close } @@ -202,14 +204,6 @@ start_server {tags {"pubsub network"}} { $rd close } {0} {resp3} - test "PUNSUBSCRIBE from non-subscribed channels" { - set rd1 [valkey_deferring_client] - assert_equal {0 0 0} [punsubscribe $rd1 {foo.* bar.* quux.*}] - - # clean up clients - $rd1 close - } - test "NUMSUB returns numbers, not strings (#1561)" { r pubsub numsub abc def } {abc 0 def 0} @@ -247,16 +241,6 @@ start_server {tags {"pubsub network"}} { $rd1 close } - test "PUNSUBSCRIBE and UNSUBSCRIBE should always reply" { - # Make sure we are not subscribed to any channel at all. - r punsubscribe - r unsubscribe - # Now check if the commands still reply correctly. - set reply1 [r punsubscribe] - set reply2 [r unsubscribe] - concat $reply1 $reply2 - } {punsubscribe {} 0 unsubscribe {} 0} - ### Keyspace events notification tests test "Keyspace notifications: we receive keyspace notifications" { diff --git a/tests/unit/pubsubshard.tcl b/tests/unit/pubsubshard.tcl index e19db211f..d62a41570 100644 --- a/tests/unit/pubsubshard.tcl +++ b/tests/unit/pubsubshard.tcl @@ -74,9 +74,8 @@ start_server {tags {"pubsubshard external:skip"}} { test "SUNSUBSCRIBE from non-subscribed channels" { set rd1 [valkey_deferring_client] - assert_equal {0} [sunsubscribe $rd1 {foo}] - assert_equal {0} [sunsubscribe $rd1 {bar}] - assert_equal {0} [sunsubscribe $rd1 {quux}] + catch {sunsubscribe $rd1 {foo}} e + assert_match {*NOSUB*} $e # clean up clients $rd1 close @@ -169,4 +168,4 @@ start_server {tags {"pubsubshard external:skip"}} { assert_equal {smessage chan1 world} [$rd1 read] } } -} \ No newline at end of file +}