mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
RDB v8: fix rdbLoadLen() return value.
This commit is contained in:
parent
e6554bed92
commit
27e5f385c1
55
src/rdb.c
55
src/rdb.c
@ -128,41 +128,60 @@ int rdbSaveLen(rio *rdb, uint64_t len) {
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
/* Load an encoded length. The "isencoded" argument is set to 1 if the length
|
||||
* is not actually a length but an "encoding type". See the RDB_ENC_*
|
||||
* definitions in rdb.h for more information. */
|
||||
uint64_t rdbLoadLen(rio *rdb, int *isencoded) {
|
||||
|
||||
/* Load an encoded length. If the loaded length is a normal length as stored
|
||||
* with rdbSaveLen(), the read length is set to '*lenptr'. If instead the
|
||||
* loaded length describes a special encoding that follows, then '*isencoded'
|
||||
* is set to 1 and the encoding format is stored at '*lenptr'.
|
||||
*
|
||||
* See the RDB_ENC_* definitions in rdb.h for more information on special
|
||||
* encodings.
|
||||
*
|
||||
* The function returns -1 on error, 0 on success. */
|
||||
int rdbLoadLenByRef(rio *rdb, int *isencoded, uint64_t *lenptr) {
|
||||
unsigned char buf[2];
|
||||
int type;
|
||||
|
||||
if (isencoded) *isencoded = 0;
|
||||
if (rioRead(rdb,buf,1) == 0) return RDB_LENERR;
|
||||
if (rioRead(rdb,buf,1) == 0) return -1;
|
||||
type = (buf[0]&0xC0)>>6;
|
||||
if (type == RDB_ENCVAL) {
|
||||
/* Read a 6 bit encoding type. */
|
||||
if (isencoded) *isencoded = 1;
|
||||
return buf[0]&0x3F;
|
||||
*lenptr = buf[0]&0x3F;
|
||||
} else if (type == RDB_6BITLEN) {
|
||||
/* Read a 6 bit len. */
|
||||
return buf[0]&0x3F;
|
||||
*lenptr = buf[0]&0x3F;
|
||||
} else if (type == RDB_14BITLEN) {
|
||||
/* Read a 14 bit len. */
|
||||
if (rioRead(rdb,buf+1,1) == 0) return RDB_LENERR;
|
||||
return ((buf[0]&0x3F)<<8)|buf[1];
|
||||
if (rioRead(rdb,buf+1,1) == 0) return -1;
|
||||
*lenptr = ((buf[0]&0x3F)<<8)|buf[1];
|
||||
} else if (buf[0] == RDB_32BITLEN) {
|
||||
/* Read a 32 bit len. */
|
||||
uint32_t len;
|
||||
if (rioRead(rdb,&len,4) == 0) return RDB_LENERR;
|
||||
return ntohl(len);
|
||||
if (rioRead(rdb,&len,4) == 0) return -1;
|
||||
*lenptr = ntohl(len);
|
||||
} else if (buf[0] == RDB_64BITLEN) {
|
||||
/* Read a 64 bit len. */
|
||||
uint64_t len;
|
||||
if (rioRead(rdb,&len,8) == 0) return RDB_LENERR;
|
||||
return ntohu64(len);
|
||||
if (rioRead(rdb,&len,8) == 0) return -1;
|
||||
*lenptr = ntohu64(len);
|
||||
} else {
|
||||
rdbExitReportCorruptRDB("Unknown length encoding in rdbLoadLen()");
|
||||
return 0; /* Never reached. */
|
||||
return -1; /* Never reached. */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is like rdbLoadLenByRef() but directly returns the value read
|
||||
* from the RDB stream, signaling an error by returning RDB_LENERR
|
||||
* (since it is a too large count to be applicable in any Redis data
|
||||
* structure). */
|
||||
uint64_t rdbLoadLen(rio *rdb, int *isencoded) {
|
||||
uint64_t len;
|
||||
|
||||
if (rdbLoadLenByRef(rdb,isencoded,&len) == -1) return RDB_LENERR;
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Encodes the "value" argument as integer when it fits in the supported ranges
|
||||
@ -299,7 +318,7 @@ ssize_t rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) {
|
||||
void *rdbLoadLzfStringObject(rio *rdb, int flags) {
|
||||
int plain = flags & RDB_LOAD_PLAIN;
|
||||
int sds = flags & RDB_LOAD_SDS;
|
||||
unsigned int len, clen;
|
||||
uint64_t len, clen;
|
||||
unsigned char *c = NULL;
|
||||
char *val = NULL;
|
||||
|
||||
@ -414,7 +433,7 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags) {
|
||||
int plain = flags & RDB_LOAD_PLAIN;
|
||||
int sds = flags & RDB_LOAD_SDS;
|
||||
int isencoded;
|
||||
uint32_t len;
|
||||
uint64_t len;
|
||||
|
||||
len = rdbLoadLen(rdb,&isencoded);
|
||||
if (isencoded) {
|
||||
@ -1291,7 +1310,7 @@ void rdbLoadProgressCallback(rio *r, const void *buf, size_t len) {
|
||||
}
|
||||
|
||||
int rdbLoad(char *filename) {
|
||||
uint32_t dbid;
|
||||
uint64_t dbid;
|
||||
int type, rdbver;
|
||||
redisDb *db = server.db+0;
|
||||
char buf[1024];
|
||||
@ -1364,7 +1383,7 @@ int rdbLoad(char *filename) {
|
||||
} else if (type == RDB_OPCODE_RESIZEDB) {
|
||||
/* RESIZEDB: Hint about the size of the keys in the currently
|
||||
* selected data base, in order to avoid useless rehashing. */
|
||||
uint32_t db_size, expires_size;
|
||||
uint64_t db_size, expires_size;
|
||||
if ((db_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
||||
goto eoferr;
|
||||
if ((expires_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
||||
|
@ -59,7 +59,7 @@
|
||||
#define RDB_32BITLEN 0x80
|
||||
#define RDB_64BITLEN 0x81
|
||||
#define RDB_ENCVAL 3
|
||||
#define RDB_LENERR UINT_MAX
|
||||
#define RDB_LENERR UINT64_MAX
|
||||
|
||||
/* When a length of a string object stored on disk has the first two bits
|
||||
* set, the remaining six bits specify a special encoding for the object
|
||||
|
@ -171,7 +171,7 @@ static int processTime(int type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t loadLength(int *isencoded) {
|
||||
static uint64_t loadLength(int *isencoded) {
|
||||
unsigned char buf[2];
|
||||
uint32_t len;
|
||||
int type;
|
||||
@ -190,10 +190,16 @@ static uint32_t loadLength(int *isencoded) {
|
||||
/* Read a 14 bit len */
|
||||
if (!readBytes(buf+1,1)) return RDB_LENERR;
|
||||
return ((buf[0] & 0x3F) << 8) | buf[1];
|
||||
} else {
|
||||
} else if (buf[0] == RDB_32BITLEN) {
|
||||
/* Read a 32 bit len */
|
||||
if (!readBytes(&len, 4)) return RDB_LENERR;
|
||||
return (unsigned int)ntohl(len);
|
||||
return ntohl(len);
|
||||
} else if (buf[0] == RDB_64BITLEN) {
|
||||
/* Read a 64 bit len */
|
||||
if (!readBytes(&len, 8)) return RDB_LENERR;
|
||||
return ntohu64(len);
|
||||
} else {
|
||||
return RDB_LENERR;
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +236,7 @@ static char *loadIntegerObject(int enctype) {
|
||||
}
|
||||
|
||||
static char* loadLzfStringObject() {
|
||||
unsigned int slen, clen;
|
||||
uint64_t slen, clen;
|
||||
char *c, *s;
|
||||
|
||||
if ((clen = loadLength(NULL)) == RDB_LENERR) return NULL;
|
||||
@ -254,9 +260,9 @@ static char* loadLzfStringObject() {
|
||||
|
||||
/* returns NULL when not processable, char* when valid */
|
||||
static char* loadStringObject() {
|
||||
uint32_t offset = CURR_OFFSET;
|
||||
uint64_t offset = CURR_OFFSET;
|
||||
uint64_t len;
|
||||
int isencoded;
|
||||
uint32_t len;
|
||||
|
||||
len = loadLength(&isencoded);
|
||||
if (isencoded) {
|
||||
@ -269,7 +275,7 @@ static char* loadStringObject() {
|
||||
return loadLzfStringObject();
|
||||
default:
|
||||
/* unknown encoding */
|
||||
SHIFT_ERROR(offset, "Unknown string encoding (0x%02x)", len);
|
||||
SHIFT_ERROR(offset, "Unknown string encoding (0x%02llx)", len);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -344,8 +350,8 @@ static int processDoubleValue(double** store) {
|
||||
}
|
||||
|
||||
static int loadPair(entry *e) {
|
||||
uint32_t offset = CURR_OFFSET;
|
||||
uint32_t i;
|
||||
uint64_t offset = CURR_OFFSET;
|
||||
uint64_t i;
|
||||
|
||||
/* read key first */
|
||||
char *key;
|
||||
@ -356,7 +362,7 @@ static int loadPair(entry *e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t length = 0;
|
||||
uint64_t length = 0;
|
||||
if (e->type == RDB_TYPE_LIST ||
|
||||
e->type == RDB_TYPE_SET ||
|
||||
e->type == RDB_TYPE_ZSET ||
|
||||
@ -384,7 +390,7 @@ static int loadPair(entry *e) {
|
||||
for (i = 0; i < length; i++) {
|
||||
offset = CURR_OFFSET;
|
||||
if (!processStringObject(NULL)) {
|
||||
SHIFT_ERROR(offset, "Error reading element at index %d (length: %d)", i, length);
|
||||
SHIFT_ERROR(offset, "Error reading element at index %llu (length: %llu)", i, length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -393,12 +399,12 @@ static int loadPair(entry *e) {
|
||||
for (i = 0; i < length; i++) {
|
||||
offset = CURR_OFFSET;
|
||||
if (!processStringObject(NULL)) {
|
||||
SHIFT_ERROR(offset, "Error reading element key at index %d (length: %d)", i, length);
|
||||
SHIFT_ERROR(offset, "Error reading element key at index %llu (length: %llu)", i, length);
|
||||
return 0;
|
||||
}
|
||||
offset = CURR_OFFSET;
|
||||
if (!processDoubleValue(NULL)) {
|
||||
SHIFT_ERROR(offset, "Error reading element value at index %d (length: %d)", i, length);
|
||||
SHIFT_ERROR(offset, "Error reading element value at index %llu (length: %llu)", i, length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -407,12 +413,12 @@ static int loadPair(entry *e) {
|
||||
for (i = 0; i < length; i++) {
|
||||
offset = CURR_OFFSET;
|
||||
if (!processStringObject(NULL)) {
|
||||
SHIFT_ERROR(offset, "Error reading element key at index %d (length: %d)", i, length);
|
||||
SHIFT_ERROR(offset, "Error reading element key at index %llu (length: %llu)", i, length);
|
||||
return 0;
|
||||
}
|
||||
offset = CURR_OFFSET;
|
||||
if (!processStringObject(NULL)) {
|
||||
SHIFT_ERROR(offset, "Error reading element value at index %d (length: %d)", i, length);
|
||||
SHIFT_ERROR(offset, "Error reading element value at index %llu (length: %llu)", i, length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -428,7 +434,7 @@ static int loadPair(entry *e) {
|
||||
|
||||
static entry loadEntry() {
|
||||
entry e = { NULL, -1, 0 };
|
||||
uint32_t length, offset[4];
|
||||
uint64_t length, offset[4];
|
||||
|
||||
/* reset error container */
|
||||
errors.level = 0;
|
||||
@ -445,7 +451,7 @@ static entry loadEntry() {
|
||||
return e;
|
||||
}
|
||||
if (length > 63) {
|
||||
SHIFT_ERROR(offset[1], "Database number out of range (%d)", length);
|
||||
SHIFT_ERROR(offset[1], "Database number out of range (%llu)", length);
|
||||
return e;
|
||||
}
|
||||
} else if (e.type == RDB_OPCODE_EOF) {
|
||||
|
Loading…
Reference in New Issue
Block a user