summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDustin Sallings <dustin@spy.net>2009-03-18 18:54:01 -0700
committerDustin Sallings <dustin@spy.net>2009-03-19 01:52:54 -0700
commit0fe0928b51782ceea91f537c8f0d05d80471c174 (patch)
treee91425b4bbdd5cc22703f33f18e1ee97d6828690
parent63ba0e14d0aed8d2d82c10d0b4706f204927da0c (diff)
downloadmemcached-0fe0928b51782ceea91f537c8f0d05d80471c174.tar.gz
Use safe strto.*l functions for parsing info in text sets.
Thanks to Toru for pointing this out.
-rw-r--r--memcached.c27
-rw-r--r--t/cas.t18
2 files changed, 33 insertions, 12 deletions
diff --git a/memcached.c b/memcached.c
index 205c8cb..1772b8c 100644
--- a/memcached.c
+++ b/memcached.c
@@ -2599,7 +2599,8 @@ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens,
static void process_update_command(conn *c, token_t *tokens, const size_t ntokens, int comm, bool handle_cas) {
char *key;
size_t nkey;
- int flags;
+ unsigned int flags;
+ int32_t exptime_int = 0;
time_t exptime;
int vlen;
uint64_t req_cas_id=0;
@@ -2617,19 +2618,23 @@ static void process_update_command(conn *c, token_t *tokens, const size_t ntoken
key = tokens[KEY_TOKEN].value;
nkey = tokens[KEY_TOKEN].length;
- flags = strtoul(tokens[2].value, NULL, 10);
- exptime = strtol(tokens[3].value, NULL, 10);
- vlen = strtol(tokens[4].value, NULL, 10);
+ if (! (safe_strtoul(tokens[2].value, (uint32_t *)&flags)
+ && safe_strtol(tokens[3].value, &exptime_int)
+ && safe_strtol(tokens[4].value, (int32_t *)&vlen))) {
+ out_string(c, "CLIENT_ERROR bad command line format");
+ return;
+ }
+
+ /* Ubuntu 8.04 breaks when I pass exptime to safe_strtol */
+ exptime = exptime_int;
// does cas value exist?
if (handle_cas) {
- req_cas_id = strtoull(tokens[5].value, NULL, 10);
- }
-
- if (errno == ERANGE || ((flags == 0 || exptime == 0) && errno == EINVAL)
- || vlen < 0) {
- out_string(c, "CLIENT_ERROR bad command line format");
- return;
+ if (!safe_strtoull(tokens[5].value, &req_cas_id)
+ || vlen < 0 ) {
+ out_string(c, "CLIENT_ERROR bad command line format");
+ return;
+ }
}
if (settings.detail_enabled) {
diff --git a/t/cas.t b/t/cas.t
index a84fdd9..f2c2f50 100644
--- a/t/cas.t
+++ b/t/cas.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl
use strict;
-use Test::More tests => 39;
+use Test::More tests => 43;
use FindBin qw($Bin);
use lib "$Bin/lib";
use MemcachedTest;
@@ -16,6 +16,22 @@ my @result2;
ok($sock != $sock2, "have two different connections open");
+sub check_args {
+ my ($line, $name) = @_;
+
+ my $svr = new_memcached();
+ my $s = $svr->sock;
+
+ print $s $line;
+ is(scalar <$s>, "CLIENT_ERROR bad command line format\r\n", $name);
+ undef $svr;
+}
+
+check_args "cas bad blah 0 0 0\r\n\r\n", "bad flags";
+check_args "cas bad 0 blah 0 0\r\n\r\n", "bad exp";
+check_args "cas bad 0 0 blah 0\r\n\r\n", "bad cas";
+check_args "cas bad 0 0 0 blah\r\n\r\n", "bad size";
+
# gets foo (should not exist)
print $sock "gets foo\r\n";
is(scalar <$sock>, "END\r\n", "gets failed");