[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