mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -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;
|
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_*
|
/* Load an encoded length. If the loaded length is a normal length as stored
|
||||||
* definitions in rdb.h for more information. */
|
* with rdbSaveLen(), the read length is set to '*lenptr'. If instead the
|
||||||
uint64_t rdbLoadLen(rio *rdb, int *isencoded) {
|
* 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];
|
unsigned char buf[2];
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
if (isencoded) *isencoded = 0;
|
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;
|
type = (buf[0]&0xC0)>>6;
|
||||||
if (type == RDB_ENCVAL) {
|
if (type == RDB_ENCVAL) {
|
||||||
/* Read a 6 bit encoding type. */
|
/* Read a 6 bit encoding type. */
|
||||||
if (isencoded) *isencoded = 1;
|
if (isencoded) *isencoded = 1;
|
||||||
return buf[0]&0x3F;
|
*lenptr = buf[0]&0x3F;
|
||||||
} else if (type == RDB_6BITLEN) {
|
} else if (type == RDB_6BITLEN) {
|
||||||
/* Read a 6 bit len. */
|
/* Read a 6 bit len. */
|
||||||
return buf[0]&0x3F;
|
*lenptr = buf[0]&0x3F;
|
||||||
} else if (type == RDB_14BITLEN) {
|
} else if (type == RDB_14BITLEN) {
|
||||||
/* Read a 14 bit len. */
|
/* Read a 14 bit len. */
|
||||||
if (rioRead(rdb,buf+1,1) == 0) return RDB_LENERR;
|
if (rioRead(rdb,buf+1,1) == 0) return -1;
|
||||||
return ((buf[0]&0x3F)<<8)|buf[1];
|
*lenptr = ((buf[0]&0x3F)<<8)|buf[1];
|
||||||
} else if (buf[0] == RDB_32BITLEN) {
|
} else if (buf[0] == RDB_32BITLEN) {
|
||||||
/* Read a 32 bit len. */
|
/* Read a 32 bit len. */
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
if (rioRead(rdb,&len,4) == 0) return RDB_LENERR;
|
if (rioRead(rdb,&len,4) == 0) return -1;
|
||||||
return ntohl(len);
|
*lenptr = ntohl(len);
|
||||||
} else if (buf[0] == RDB_64BITLEN) {
|
} else if (buf[0] == RDB_64BITLEN) {
|
||||||
/* Read a 64 bit len. */
|
/* Read a 64 bit len. */
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
if (rioRead(rdb,&len,8) == 0) return RDB_LENERR;
|
if (rioRead(rdb,&len,8) == 0) return -1;
|
||||||
return ntohu64(len);
|
*lenptr = ntohu64(len);
|
||||||
} else {
|
} else {
|
||||||
rdbExitReportCorruptRDB("Unknown length encoding in rdbLoadLen()");
|
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
|
/* 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) {
|
void *rdbLoadLzfStringObject(rio *rdb, int flags) {
|
||||||
int plain = flags & RDB_LOAD_PLAIN;
|
int plain = flags & RDB_LOAD_PLAIN;
|
||||||
int sds = flags & RDB_LOAD_SDS;
|
int sds = flags & RDB_LOAD_SDS;
|
||||||
unsigned int len, clen;
|
uint64_t len, clen;
|
||||||
unsigned char *c = NULL;
|
unsigned char *c = NULL;
|
||||||
char *val = NULL;
|
char *val = NULL;
|
||||||
|
|
||||||
@ -414,7 +433,7 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags) {
|
|||||||
int plain = flags & RDB_LOAD_PLAIN;
|
int plain = flags & RDB_LOAD_PLAIN;
|
||||||
int sds = flags & RDB_LOAD_SDS;
|
int sds = flags & RDB_LOAD_SDS;
|
||||||
int isencoded;
|
int isencoded;
|
||||||
uint32_t len;
|
uint64_t len;
|
||||||
|
|
||||||
len = rdbLoadLen(rdb,&isencoded);
|
len = rdbLoadLen(rdb,&isencoded);
|
||||||
if (isencoded) {
|
if (isencoded) {
|
||||||
@ -1291,7 +1310,7 @@ void rdbLoadProgressCallback(rio *r, const void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int rdbLoad(char *filename) {
|
int rdbLoad(char *filename) {
|
||||||
uint32_t dbid;
|
uint64_t dbid;
|
||||||
int type, rdbver;
|
int type, rdbver;
|
||||||
redisDb *db = server.db+0;
|
redisDb *db = server.db+0;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
@ -1364,7 +1383,7 @@ int rdbLoad(char *filename) {
|
|||||||
} else if (type == RDB_OPCODE_RESIZEDB) {
|
} else if (type == RDB_OPCODE_RESIZEDB) {
|
||||||
/* RESIZEDB: Hint about the size of the keys in the currently
|
/* RESIZEDB: Hint about the size of the keys in the currently
|
||||||
* selected data base, in order to avoid useless rehashing. */
|
* 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)
|
if ((db_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
||||||
goto eoferr;
|
goto eoferr;
|
||||||
if ((expires_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
if ((expires_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR)
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
#define RDB_32BITLEN 0x80
|
#define RDB_32BITLEN 0x80
|
||||||
#define RDB_64BITLEN 0x81
|
#define RDB_64BITLEN 0x81
|
||||||
#define RDB_ENCVAL 3
|
#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
|
/* 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
|
* set, the remaining six bits specify a special encoding for the object
|
||||||
|
@ -171,7 +171,7 @@ static int processTime(int type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t loadLength(int *isencoded) {
|
static uint64_t loadLength(int *isencoded) {
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
int type;
|
int type;
|
||||||
@ -190,10 +190,16 @@ static uint32_t loadLength(int *isencoded) {
|
|||||||
/* Read a 14 bit len */
|
/* Read a 14 bit len */
|
||||||
if (!readBytes(buf+1,1)) return RDB_LENERR;
|
if (!readBytes(buf+1,1)) return RDB_LENERR;
|
||||||
return ((buf[0] & 0x3F) << 8) | buf[1];
|
return ((buf[0] & 0x3F) << 8) | buf[1];
|
||||||
} else {
|
} else if (buf[0] == RDB_32BITLEN) {
|
||||||
/* Read a 32 bit len */
|
/* Read a 32 bit len */
|
||||||
if (!readBytes(&len, 4)) return RDB_LENERR;
|
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() {
|
static char* loadLzfStringObject() {
|
||||||
unsigned int slen, clen;
|
uint64_t slen, clen;
|
||||||
char *c, *s;
|
char *c, *s;
|
||||||
|
|
||||||
if ((clen = loadLength(NULL)) == RDB_LENERR) return NULL;
|
if ((clen = loadLength(NULL)) == RDB_LENERR) return NULL;
|
||||||
@ -254,9 +260,9 @@ static char* loadLzfStringObject() {
|
|||||||
|
|
||||||
/* returns NULL when not processable, char* when valid */
|
/* returns NULL when not processable, char* when valid */
|
||||||
static char* loadStringObject() {
|
static char* loadStringObject() {
|
||||||
uint32_t offset = CURR_OFFSET;
|
uint64_t offset = CURR_OFFSET;
|
||||||
|
uint64_t len;
|
||||||
int isencoded;
|
int isencoded;
|
||||||
uint32_t len;
|
|
||||||
|
|
||||||
len = loadLength(&isencoded);
|
len = loadLength(&isencoded);
|
||||||
if (isencoded) {
|
if (isencoded) {
|
||||||
@ -269,7 +275,7 @@ static char* loadStringObject() {
|
|||||||
return loadLzfStringObject();
|
return loadLzfStringObject();
|
||||||
default:
|
default:
|
||||||
/* unknown encoding */
|
/* unknown encoding */
|
||||||
SHIFT_ERROR(offset, "Unknown string encoding (0x%02x)", len);
|
SHIFT_ERROR(offset, "Unknown string encoding (0x%02llx)", len);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,8 +350,8 @@ static int processDoubleValue(double** store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int loadPair(entry *e) {
|
static int loadPair(entry *e) {
|
||||||
uint32_t offset = CURR_OFFSET;
|
uint64_t offset = CURR_OFFSET;
|
||||||
uint32_t i;
|
uint64_t i;
|
||||||
|
|
||||||
/* read key first */
|
/* read key first */
|
||||||
char *key;
|
char *key;
|
||||||
@ -356,7 +362,7 @@ static int loadPair(entry *e) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t length = 0;
|
uint64_t length = 0;
|
||||||
if (e->type == RDB_TYPE_LIST ||
|
if (e->type == RDB_TYPE_LIST ||
|
||||||
e->type == RDB_TYPE_SET ||
|
e->type == RDB_TYPE_SET ||
|
||||||
e->type == RDB_TYPE_ZSET ||
|
e->type == RDB_TYPE_ZSET ||
|
||||||
@ -384,7 +390,7 @@ static int loadPair(entry *e) {
|
|||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processStringObject(NULL)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,12 +399,12 @@ static int loadPair(entry *e) {
|
|||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processStringObject(NULL)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processDoubleValue(NULL)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,12 +413,12 @@ static int loadPair(entry *e) {
|
|||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processStringObject(NULL)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
offset = CURR_OFFSET;
|
offset = CURR_OFFSET;
|
||||||
if (!processStringObject(NULL)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -428,7 +434,7 @@ static int loadPair(entry *e) {
|
|||||||
|
|
||||||
static entry loadEntry() {
|
static entry loadEntry() {
|
||||||
entry e = { NULL, -1, 0 };
|
entry e = { NULL, -1, 0 };
|
||||||
uint32_t length, offset[4];
|
uint64_t length, offset[4];
|
||||||
|
|
||||||
/* reset error container */
|
/* reset error container */
|
||||||
errors.level = 0;
|
errors.level = 0;
|
||||||
@ -445,7 +451,7 @@ static entry loadEntry() {
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
if (length > 63) {
|
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;
|
return e;
|
||||||
}
|
}
|
||||||
} else if (e.type == RDB_OPCODE_EOF) {
|
} else if (e.type == RDB_OPCODE_EOF) {
|
||||||
|
Loading…
Reference in New Issue
Block a user