diff options
author | Dustin Sallings <dustin@spy.net> | 2009-03-18 18:54:01 -0700 |
---|---|---|
committer | Dustin Sallings <dustin@spy.net> | 2009-03-19 01:52:54 -0700 |
commit | 0fe0928b51782ceea91f537c8f0d05d80471c174 (patch) | |
tree | e91425b4bbdd5cc22703f33f18e1ee97d6828690 | |
parent | 63ba0e14d0aed8d2d82c10d0b4706f204927da0c (diff) | |
download | memcached-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.c | 27 | ||||
-rw-r--r-- | t/cas.t | 18 |
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) { @@ -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"); |