From: antirez Date: Tue, 20 Oct 2009 09:39:20 +0000 (+0200) Subject: Imporant bug leading to data corruption fixed (NOT affecting stable distribution... X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/f69f2cbafeceb03a0bc945227f08657ea1c09251 Imporant bug leading to data corruption fixed (NOT affecting stable distribution), Tcl client lib MSET/MSETNX implementation fixed, Added new tests for MSET and MSETNX in test-redis.tcl --- diff --git a/client-libraries/tcl/redis.tcl b/client-libraries/tcl/redis.tcl index deeadf2e..1a2bda5e 100644 --- a/client-libraries/tcl/redis.tcl +++ b/client-libraries/tcl/redis.tcl @@ -27,7 +27,7 @@ foreach redis_bulk_cmd { # Flag commands requiring last argument as a bulk write operation foreach redis_multibulk_cmd { - mset + mset msetnx } { set ::redis::multibulkarg($redis_multibulk_cmd) {} } @@ -53,12 +53,13 @@ proc ::redis::__dispatch__ {id method args} { append cmd [lindex $args end] ::redis::redis_writenl $fd $cmd } elseif {[info exists ::redis::multibulkarg($method)]} { - set cmd "*[expr {[llength $args]}+1]\r\n" + set cmd "*[expr {[llength $args]+1}]\r\n" append cmd "$[string length $method]\r\n$method\r\n" foreach a $args { append cmd "$[string length $a]\r\n$a\r\n" } ::redis::redis_write $fd $cmd + flush $fd } else { set cmd "$method " append cmd [join $args] diff --git a/redis.c b/redis.c index c8cb67f0..b934b40d 100644 --- a/redis.c +++ b/redis.c @@ -1936,7 +1936,7 @@ static robj *tryObjectSharing(robj *o) { * * If so, the function returns REDIS_OK and *longval is set to the value * of the number. Otherwise REDIS_ERR is returned */ -static int isStringRepresentableAsLong(char *s, long *longval) { +static int isStringRepresentableAsLong(sds s, long *longval) { char buf[32], *endptr; long value; int slen; @@ -1947,7 +1947,7 @@ static int isStringRepresentableAsLong(char *s, long *longval) { /* If the number converted back into a string is not identical * then it's not possible to encode the string as integer */ - if (strlen(buf) != (unsigned)slen || memcmp(buf,s,slen)) return REDIS_ERR; + if (sdslen(s) != (unsigned)slen || memcmp(buf,s,slen)) return REDIS_ERR; if (longval) *longval = value; return REDIS_OK; } diff --git a/test-redis.tcl b/test-redis.tcl index 68db9706..a5182670 100644 --- a/test-redis.tcl +++ b/test-redis.tcl @@ -750,19 +750,37 @@ proc main {server port} { format $err } {ERR*} + test {MSET base case} { + $r mset x 10 y "foo bar" z "x x x x x x x\n\n\r\n" + $r mget x y z + } [list 10 {foo bar} "x x x x x x x\n\n\r\n"] + + test {MSET wrong number of args} { + catch {$r mset x 10 y "foo bar" z} err + format $err + } {*wrong number*} + + test {MSETNX with already existent key} { + list [$r msetnx x1 xxx y2 yyy x 20] [$r exists x1] [$r exists y2] + } {0 0 0} + + test {MSETNX with not existing keys} { + list [$r msetnx x1 xxx y2 yyy] [$r get x1] [$r get y2] + } {1 xxx yyy} + foreach fuzztype {binary alpha compr} { test "FUZZ stresser with data model $fuzztype" { set err 0 - for {set i 0} {$i < 1000} {incr i} { + for {set i 0} {$i < 10000} {incr i} { set fuzz [randstring 0 512 $fuzztype] $r set foo $fuzz set got [$r get foo] if {$got ne $fuzz} { - incr err + set err [list $fuzz $got] break } } - format $err + set _ $err } {0} }