From: Schuster Date: Mon, 22 Oct 2012 09:44:20 +0000 (+0200) Subject: redis-check-dump now understands dumps produced by Redis 2.6 X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/16144589f22de53d25e7232b1f90f18d5ac6fe74 redis-check-dump now understands dumps produced by Redis 2.6 (Commit message from @antirez as it was missign in the original commits, also the patch was modified a bit to still work with 2.4 dumps and to avoid if expressions that are always true due to checked types range) This commit changes redis-check-dump to account for new encodings and for the new MSTIME expire format. It also refactors the test for valid type into a function. The code is still compatible with Redis 2.4 generated dumps. This fixes issue #709. --- diff --git a/src/redis-check-dump.c b/src/redis-check-dump.c index 5eac925a..65309e76 100644 --- a/src/redis-check-dump.c +++ b/src/redis-check-dump.c @@ -31,6 +31,7 @@ #define REDIS_ENCODING_HT 3 /* Encoded as an hash table */ /* Object types only used for dumping to disk */ +#define REDIS_EXPIRETIME_MS 252 #define REDIS_EXPIRETIME 253 #define REDIS_SELECTDB 254 #define REDIS_EOF 255 @@ -111,6 +112,16 @@ static char types[256][16]; /* Prototypes */ uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l); +/* Return true if 't' is a valid object type. */ +int checkType(unsigned char t) { + /* In case a new object type is added, update the following + * condition as necessary. */ + return + (t >= REDIS_HASH_ZIPMAP && t <= REDIS_HASH_ZIPLIST) || + t <= REDIS_HASH || + t >= REDIS_EXPIRETIME_MS; +} + /* when number of bytes to read is negative, do a peek */ int readBytes(void *target, long num) { char peek = (num < 0) ? 1 : 0; @@ -152,7 +163,7 @@ int loadType(entry *e) { /* this byte needs to qualify as type */ unsigned char t; if (readBytes(&t, 1)) { - if (t <= 4 || (t >=9 && t <= 12) || t >= 253) { + if (checkType(t)) { e->type = t; return 1; } else { @@ -168,16 +179,18 @@ int loadType(entry *e) { int peekType() { unsigned char t; - if (readBytes(&t, -1) && (t <= 4 || (t >=9 && t <= 12) || t >= 253)) + if (readBytes(&t, -1) && (checkType(t))) return t; return -1; } /* discard time, just consume the bytes */ -int processTime() { +int processTime(int type) { uint32_t offset = CURR_OFFSET; - unsigned char t[4]; - if (readBytes(t, 4)) { + unsigned char t[8]; + int timelen = (type == REDIS_EXPIRETIME_MS) ? 8 : 4; + + if (readBytes(t,timelen)) { return 1; } else { SHIFT_ERROR(offset, "Could not read time"); @@ -472,8 +485,9 @@ entry loadEntry() { return e; } else { /* optionally consume expire */ - if (e.type == REDIS_EXPIRETIME) { - if (!processTime()) return e; + if (e.type == REDIS_EXPIRETIME || + e.type == REDIS_EXPIRETIME_MS) { + if (!processTime(e.type)) return e; if (!loadType(&e)) return e; }