X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/9f9e1ceaa0d4451a21aa56739e63cca012399317..7982173fef8bd6de9805e782edb9aa827184b010:/src/t_string.c diff --git a/src/t_string.c b/src/t_string.c index e442a49f..736b1673 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -96,10 +96,8 @@ static int getBitOffsetFromArgument(redisClient *c, robj *o, size_t *offset) { if (getLongLongFromObjectOrReply(c,o,&loffset,err) != REDIS_OK) return REDIS_ERR; - /* Limit offset to SIZE_T_MAX or 512MB in bytes */ - if ((loffset < 0) || - ((unsigned long long)loffset >= (unsigned)SIZE_T_MAX) || - ((unsigned long long)loffset >> 3) >= (512*1024*1024)) + /* Limit offset to 512MB in bytes */ + if ((loffset < 0) || ((unsigned long long)loffset >> 3) >= (512*1024*1024)) { addReplyError(c,err); return REDIS_ERR; @@ -257,6 +255,43 @@ void setrangeCommand(redisClient *c) { addReplyLongLong(c,sdslen(o->ptr)); } +void getrangeCommand(redisClient *c) { + robj *o; + long start, end; + char *str, llbuf[32]; + size_t strlen; + + if (getLongFromObjectOrReply(c,c->argv[2],&start,NULL) != REDIS_OK) + return; + if (getLongFromObjectOrReply(c,c->argv[3],&end,NULL) != REDIS_OK) + return; + if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL || + checkType(c,o,REDIS_STRING)) return; + + if (o->encoding == REDIS_ENCODING_INT) { + str = llbuf; + strlen = ll2string(llbuf,sizeof(llbuf),(long)o->ptr); + } else { + str = o->ptr; + strlen = sdslen(str); + } + + /* Convert negative indexes */ + if (start < 0) start = strlen+start; + if (end < 0) end = strlen+end; + if (start < 0) start = 0; + if (end < 0) end = 0; + if ((unsigned)end >= strlen) end = strlen-1; + + /* Precondition: end >= 0 && end < strlen, so the only condition where + * nothing can be returned is: start > end. */ + if (start > end) { + addReply(c,shared.nullbulk); + } else { + addReplyBulkCBuffer(c,(char*)str+start,end-start+1); + } +} + void mgetCommand(redisClient *c) { int j; @@ -400,43 +435,6 @@ void appendCommand(redisClient *c) { addReplyLongLong(c,totlen); } -void substrCommand(redisClient *c) { - robj *o; - long start = atoi(c->argv[2]->ptr); - long end = atoi(c->argv[3]->ptr); - size_t rangelen, strlen; - sds range; - - if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL || - checkType(c,o,REDIS_STRING)) return; - - o = getDecodedObject(o); - strlen = sdslen(o->ptr); - - /* convert negative indexes */ - if (start < 0) start = strlen+start; - if (end < 0) end = strlen+end; - if (start < 0) start = 0; - if (end < 0) end = 0; - - /* indexes sanity checks */ - if (start > end || (size_t)start >= strlen) { - /* Out of range start or start > end result in null reply */ - addReply(c,shared.nullbulk); - decrRefCount(o); - return; - } - if ((size_t)end >= strlen) end = strlen-1; - rangelen = (end-start)+1; - - /* Return the result */ - addReplySds(c,sdscatprintf(sdsempty(),"$%zu\r\n",rangelen)); - range = sdsnewlen((char*)o->ptr+start,rangelen); - addReplySds(c,range); - addReply(c,shared.crlf); - decrRefCount(o); -} - void strlenCommand(redisClient *c) { robj *o;