diff --git a/src/quicklist.c b/src/quicklist.c index 7b7aa7839..1095f8791 100644 --- a/src/quicklist.c +++ b/src/quicklist.c @@ -1296,17 +1296,24 @@ void quicklistRotate(quicklist *quicklist) { /* First, get the tail entry */ unsigned char *p = ziplistIndex(quicklist->tail->zl, -1); - unsigned char *value; + unsigned char *value, *tmp; long long longval; unsigned int sz; char longstr[32] = {0}; - ziplistGet(p, &value, &sz, &longval); + ziplistGet(p, &tmp, &sz, &longval); /* If value found is NULL, then ziplistGet populated longval instead */ - if (!value) { + if (!tmp) { /* Write the longval as a string so we can re-add it */ sz = ll2string(longstr, sizeof(longstr), longval); value = (unsigned char *)longstr; + } else if (quicklist->len == 1) { + /* Copy buffer since there could be a memory overlap when move + * entity from tail to head in the same ziplist. */ + value = zmalloc(sz); + memcpy(value, tmp, sz); + } else { + value = tmp; } /* Add tail entry to head (must happen before tail is deleted). */ @@ -1321,6 +1328,8 @@ void quicklistRotate(quicklist *quicklist) { /* Remove tail entry. */ quicklistDelIndex(quicklist, quicklist->tail, &p); + if (value != (unsigned char*)longstr && value != tmp) + zfree(value); } /* pop from quicklist and return result in 'data' ptr. Value of 'data'