Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

New binary protocol error for bad stored value in incr/decr (issue48)

  • Loading branch information...
commit cce46e8f092b2c57cdb94a780f67d95b65bdd762 1 parent 223a436
Dustin Sallings dustin authored Trond Norbye committed
1  doc/protocol-binary.xml
View
@@ -210,6 +210,7 @@
<t hangText="0x0003">Value too large</t>
<t hangText="0x0004">Invalid arguments</t>
<t hangText="0x0005">Item not stored</t>
+ <t hangText="0x0006">Incr/Decr on non-numeric value.</t>
<t hangText="0x0081">Unknown command</t>
<t hangText="0x0082">Out of memory</t>
</list>
20 memcached.c
View
@@ -931,6 +931,9 @@ static void write_bin_error(conn *c, protocol_binary_response_status err, int sw
case PROTOCOL_BINARY_RESPONSE_E2BIG:
errstr = "Too large.";
break;
+ case PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL:
+ errstr = "Non-numeric server-side value for incr or decr";
+ break;
case PROTOCOL_BINARY_RESPONSE_NOT_STORED:
errstr = "Not stored.";
break;
@@ -1028,12 +1031,17 @@ static void complete_incr_bin(conn *c) {
c->binary_header.request.cas == ITEM_get_cas(it))) {
/* Weird magic in add_delta forces me to pad here */
char tmpbuf[INCR_MAX_STORAGE_LEN];
- add_delta(c, it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT,
- req->message.body.delta, tmpbuf);
- rsp->message.body.value = swap64(strtoull(tmpbuf, NULL, 10));
- c->cas = ITEM_get_cas(it);
- write_bin_response(c, &rsp->message.body, 0, 0,
- sizeof(rsp->message.body.value));
+ char *adrv = add_delta(c, it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT,
+ req->message.body.delta, tmpbuf);
+ if (strncmp(adrv, "CLIENT_ERROR", 12) == 0) {
+ write_bin_error(c, PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL, 0);
+ } else {
+ rsp->message.body.value = swap64(strtoull(tmpbuf, NULL, 10));
+ c->cas = ITEM_get_cas(it);
+ write_bin_response(c, &rsp->message.body, 0, 0,
+ sizeof(rsp->message.body.value));
+ }
+
item_remove(it); /* release our reference */
} else if (!it && req->message.body.expiration != 0xffffffff) {
/* Save some room for the response */
1  protocol_binary.h
View
@@ -68,6 +68,7 @@ extern "C"
PROTOCOL_BINARY_RESPONSE_E2BIG = 0x03,
PROTOCOL_BINARY_RESPONSE_EINVAL = 0x04,
PROTOCOL_BINARY_RESPONSE_NOT_STORED = 0x05,
+ PROTOCOL_BINARY_RESPONSE_DELTA_BADVAL = 0x06,
PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND = 0x81,
PROTOCOL_BINARY_RESPONSE_ENOMEM = 0x82
} protocol_binary_response_status;
31 t/binary.t
View
@@ -2,7 +2,7 @@
use strict;
use warnings;
-use Test::More tests => 860;
+use Test::More tests => 880;
use FindBin qw($Bin);
use lib "$Bin/lib";
use MemcachedTest;
@@ -165,6 +165,19 @@ is($mc->incr("x"), 1, "Second incr call is one");
is($mc->incr("x", 211), 212, "Adding 211 gives you 212");
is($mc->incr("x", 2**33), 8589934804, "Blast the 32bit border");
+# diag "Issue 48 - incrementing plain text.";
+{
+ $mc->set("issue48", "text", 0, 0);
+ my $rv =()= eval { $mc->incr('issue48'); };
+ ok($@ && $@->delta_badval, "Expected invalid value when incrementing text.");
+ $check->('issue48', 0, "text");
+
+ my $rv =()= eval { $mc->decr('issue48'); };
+ ok($@ && $@->delta_badval, "Expected invalid value when decrementing text.");
+ $check->('issue48', 0, "text");
+}
+
+
# diag "Test decrement";
$mc->flush;
is($mc->incr("x", undef, 5), 5, "Initial value");
@@ -646,10 +659,13 @@ package MC::Error;
use strict;
use warnings;
-use constant ERR_UNKNOWN_CMD => 0x81;
-use constant ERR_NOT_FOUND => 0x1;
-use constant ERR_EXISTS => 0x2;
-use constant ERR_TOO_BIG => 0x3;
+use constant ERR_UNKNOWN_CMD => 0x81;
+use constant ERR_NOT_FOUND => 0x1;
+use constant ERR_EXISTS => 0x2;
+use constant ERR_TOO_BIG => 0x3;
+use constant ERR_EINVAL => 0x4;
+use constant ERR_NOT_STORED => 0x5;
+use constant ERR_DELTA_BADVAL => 0x6;
use overload '""' => sub {
my $self = shift;
@@ -679,5 +695,10 @@ sub too_big {
return $self->[0] == ERR_TOO_BIG;
}
+sub delta_badval {
+ my $self = shift;
+ return $self->[0] == ERR_DELTA_BADVAL;
+}
+
# vim: filetype=perl
Please sign in to comment.
Something went wrong with that request. Please try again.