Skip to content

Commit

Permalink
Imporant bug leading to data corruption fixed (NOT affecting stable d…
Browse files Browse the repository at this point in the history
…istribution), Tcl client lib MSET/MSETNX implementation fixed, Added new tests for MSET and MSETNX in test-redis.tcl
  • Loading branch information
antirez committed Oct 20, 2009
1 parent 8165a5f commit f69f2cb
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
5 changes: 3 additions & 2 deletions client-libraries/tcl/redis.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
}
Expand All @@ -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]
Expand Down
4 changes: 2 additions & 2 deletions redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
24 changes: 21 additions & 3 deletions test-redis.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -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}
}

Expand Down

0 comments on commit f69f2cb

Please sign in to comment.