X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/2f996f02174343ce766710fc6871e2e6df8e73c6..8fedd04dccd08e9a25652a22c2034d3f38f72d0f:/src/object.c diff --git a/src/object.c b/src/object.c index 51582619..92af1d6a 100644 --- a/src/object.c +++ b/src/object.c @@ -1,5 +1,6 @@ #include "redis.h" #include +#include robj *createObject(int type, void *ptr) { robj *o; @@ -73,7 +74,16 @@ robj *createZiplistObject(void) { robj *createSetObject(void) { dict *d = dictCreate(&setDictType,NULL); - return createObject(REDIS_SET,d); + robj *o = createObject(REDIS_SET,d); + o->encoding = REDIS_ENCODING_HT; + return o; +} + +robj *createIntsetObject(void) { + intset *is = intsetNew(); + robj *o = createObject(REDIS_SET,is); + o->encoding = REDIS_ENCODING_INTSET; + return o; } robj *createHashObject(void) { @@ -114,7 +124,16 @@ void freeListObject(robj *o) { } void freeSetObject(robj *o) { - dictRelease((dict*) o->ptr); + switch (o->encoding) { + case REDIS_ENCODING_HT: + dictRelease((dict*) o->ptr); + break; + case REDIS_ENCODING_INTSET: + zfree(o->ptr); + break; + default: + redisPanic("Unknown set encoding type"); + } } void freeZsetObject(robj *o) { @@ -319,7 +338,7 @@ int getDoubleFromObject(robj *o, double *target) { redisAssert(o->type == REDIS_STRING); if (o->encoding == REDIS_ENCODING_RAW) { value = strtod(o->ptr, &eptr); - if (eptr[0] != '\0') return REDIS_ERR; + if (eptr[0] != '\0' || isnan(value)) return REDIS_ERR; } else if (o->encoding == REDIS_ENCODING_INT) { value = (long)o->ptr; } else { @@ -357,6 +376,8 @@ int getLongLongFromObject(robj *o, long long *target) { if (o->encoding == REDIS_ENCODING_RAW) { value = strtoll(o->ptr, &eptr, 10); if (eptr[0] != '\0') return REDIS_ERR; + if (errno == ERANGE && (value == LLONG_MIN || value == LLONG_MAX)) + return REDIS_ERR; } else if (o->encoding == REDIS_ENCODING_INT) { value = (long)o->ptr; } else { @@ -364,7 +385,7 @@ int getLongLongFromObject(robj *o, long long *target) { } } - *target = value; + if (target) *target = value; return REDIS_OK; } @@ -374,7 +395,7 @@ int getLongLongFromObjectOrReply(redisClient *c, robj *o, long long *target, con if (msg != NULL) { addReplySds(c, sdscatprintf(sdsempty(), "-ERR %s\r\n", msg)); } else { - addReplySds(c, sdsnew("-ERR value is not an integer\r\n")); + addReplySds(c, sdsnew("-ERR value is not an integer or out of range\r\n")); } return REDIS_ERR; } @@ -408,6 +429,7 @@ char *strEncoding(int encoding) { case REDIS_ENCODING_ZIPMAP: return "zipmap"; case REDIS_ENCODING_LINKEDLIST: return "linkedlist"; case REDIS_ENCODING_ZIPLIST: return "ziplist"; + case REDIS_ENCODING_INTSET: return "intset"; default: return "unknown"; } }