[PATCH] Bugfix for incorrect length when decr a value
Steve Chu
stvchu at gmail.com
Thu Oct 18 10:38:48 UTC 2007
Sorry, all.
I made a mistake, the vlen *is* 5, because 9999 with a suffix of
blank, but that is really weird. libmemcache is ok for this.
On 10/18/07, Steve Chu <stvchu at gmail.com> wrote:
> Anybody can have a try:
> -----------------------------------------------
> # telnet 127.0.0.1 11211
> Trying 127.0.0.1...
> Connected to 127.0.0.1 (127.0.0.1).
> Escape character is '^]'.
> get test
> END
> add test 0 0 4
> 9999
> STORED
> incr test 1
> 10000
> get test
> VALUE test 0 5
> 10000
> END
> decr test 1
> 9999
> get test
> VALUE test 0 5
> 9999
> END
> --------------
> The vlen does not shrink when *decr* from 10000 to 9999, it is still 5!!
> This bug does not affect most dynamic language client(php .etc), but
> for clients that
> use this vlen, they don't work, for example, libmemcache.
> Also it does not follow the memcache protocol.
> Here comes the pacth:
> ===========================================================
> --- memcached-trunk/memcached.c 2007-10-18 15:57:28.000000000 +0800
> +++ memcached-new/memcached.c 2007-10-18 15:54:49.000000000 +0800
> @@ -1366,6 +1366,7 @@ char *do_add_delta(item *it, const bool
> char *ptr;
> int64_t value;
> int res;
> + item *new_it;
>
> ptr = ITEM_data(it);
> while ((*ptr != '\0') && (*ptr < '0' && *ptr > '9')) ptr++; //
> BUG: can't be true
> @@ -1384,20 +1385,17 @@ char *do_add_delta(item *it, const bool
> }
> sprintf(buf, "%llu", value);
> res = strlen(buf);
> - if (res + 2 > it->nbytes) { /* need to realloc */
> - item *new_it;
> - new_it = do_item_alloc(ITEM_key(it), it->nkey,
> atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 );
> - if (new_it == 0) {
> - return "SERVER_ERROR out of memory";
> - }
> - memcpy(ITEM_data(new_it), buf, res);
> - memcpy(ITEM_data(new_it) + res, "\r\n", 3);
> - do_item_replace(it, new_it);
> - do_item_remove(new_it); /* release our reference */
> - } else { /* replace in-place */
> - memcpy(ITEM_data(it), buf, res);
> - memset(ITEM_data(it) + res, ' ', it->nbytes - res - 2);
> +
> + /* just alloc one, not plan to new one only when res + 2 > it->nbytes */
> + new_it = do_item_alloc(ITEM_key(it), it->nkey,
> atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 );
> +
> + if (new_it == 0) {
> + return "SERVER_ERROR out of memory";
> }
> + memcpy(ITEM_data(new_it), buf, res);
> + memcpy(ITEM_data(new_it) + res, "\r\n", 3);
> + do_item_replace(it, new_it);
> + do_item_remove(new_it); /* release our reference */
>
> return buf;
> }
> ========================================================
>
> --
> Steve Chu
> http://www.sina.com
>
--
Steve Chu
http://stvchu.org
More information about the memcached
mailing list