diff options
author | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-09-03 11:52:15 +0200 |
---|---|---|
committer | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-09-03 11:53:53 +0200 |
commit | 47ae4b6a17f0423ea4bf6984cc5879f1506b71e9 (patch) | |
tree | c5d5b3cc8a1de5b876f5c8903816c264dfab3182 | |
parent | 4212dd540255ef13e5358fc3de9a658b7c2dfc24 (diff) | |
download | redis-47ae4b6a17f0423ea4bf6984cc5879f1506b71e9.tar.gz |
Verify that the blocking pop timeout value is a non-negative integer
Backport of 94364d5 to 2.0.0.
-rw-r--r-- | redis.c | 13 | ||||
-rw-r--r-- | tests/unit/type/list.tcl | 22 |
2 files changed, 34 insertions, 1 deletions
@@ -7710,9 +7710,20 @@ static int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) { /* Blocking RPOP/LPOP */ static void blockingPopGenericCommand(redisClient *c, int where) { robj *o; + long long lltimeout; time_t timeout; int j; + /* Make sure timeout is an integer value */ + if (getLongLongFromObjectOrReply(c,c->argv[c->argc-1],&lltimeout, + "timeout is not an integer") != REDIS_OK) return; + + /* Make sure the timeout is not negative */ + if (lltimeout < 0) { + addReplySds(c,sdsnew("-ERR timeout is negative\r\n")); + return; + } + for (j = 1; j < c->argc-1; j++) { o = lookupKeyWrite(c->db,c->argv[j]); if (o != NULL) { @@ -7761,7 +7772,7 @@ static void blockingPopGenericCommand(redisClient *c, int where) { } /* If the list is empty or the key does not exists we must block */ - timeout = strtol(c->argv[c->argc-1]->ptr,NULL,10); + timeout = lltimeout; if (timeout > 0) timeout += time(NULL); blockForKeys(c,c->argv+1,c->argc-2,timeout); } diff --git a/tests/unit/type/list.tcl b/tests/unit/type/list.tcl index 8c1b0b417..e0089bf36 100644 --- a/tests/unit/type/list.tcl +++ b/tests/unit/type/list.tcl @@ -83,6 +83,28 @@ start_server {tags {"list"}} { assert_equal 0 [r exists blist1] } + test "$pop: with negative timeout" { + set rd [redis_deferring_client] + $rd $pop blist1 -1 + assert_error "ERR*is negative*" {$rd read} + } + + test "$pop: with non-integer timeout" { + set rd [redis_deferring_client] + $rd $pop blist1 1.1 + assert_error "ERR*not an integer*" {$rd read} + } + + test "$pop: with zero timeout should block indefinitely" { + # To test this, use a timeout of 0 and wait a second. + # The blocking pop should still be waiting for a push. + set rd [redis_deferring_client] + $rd $pop blist1 0 + after 1000 + r rpush blist1 foo + assert_equal {blist1 foo} [$rd read] + } + test "$pop: second argument is not a list" { set rd [redis_deferring_client] r del blist1 blist2 |