mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
Fix rdb.c dictionary iterator release.
Some times it was not released on error, sometimes it was released two times because the error path expected the "di" var to be NULL if the iterator was already released. Thanks to @oranagra for pinging me about potential problems of this kind inside rdb.c.
This commit is contained in:
parent
aaef5f00cc
commit
cd87b3c71f
22
src/rdb.c
22
src/rdb.c
@ -778,7 +778,11 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
while((de = dictNext(di)) != NULL) {
|
while((de = dictNext(di)) != NULL) {
|
||||||
sds ele = dictGetKey(de);
|
sds ele = dictGetKey(de);
|
||||||
if ((n = rdbSaveRawString(rdb,(unsigned char*)ele,sdslen(ele)))
|
if ((n = rdbSaveRawString(rdb,(unsigned char*)ele,sdslen(ele)))
|
||||||
== -1) return -1;
|
== -1)
|
||||||
|
{
|
||||||
|
dictReleaseIterator(di);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
nwritten += n;
|
nwritten += n;
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
@ -846,10 +850,18 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
sds value = dictGetVal(de);
|
sds value = dictGetVal(de);
|
||||||
|
|
||||||
if ((n = rdbSaveRawString(rdb,(unsigned char*)field,
|
if ((n = rdbSaveRawString(rdb,(unsigned char*)field,
|
||||||
sdslen(field))) == -1) return -1;
|
sdslen(field))) == -1)
|
||||||
|
{
|
||||||
|
dictReleaseIterator(di);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
nwritten += n;
|
nwritten += n;
|
||||||
if ((n = rdbSaveRawString(rdb,(unsigned char*)value,
|
if ((n = rdbSaveRawString(rdb,(unsigned char*)value,
|
||||||
sdslen(value))) == -1) return -1;
|
sdslen(value))) == -1)
|
||||||
|
{
|
||||||
|
dictReleaseIterator(di);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
nwritten += n;
|
nwritten += n;
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
@ -1088,7 +1100,6 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {
|
|||||||
dict *d = db->dict;
|
dict *d = db->dict;
|
||||||
if (dictSize(d) == 0) continue;
|
if (dictSize(d) == 0) continue;
|
||||||
di = dictGetSafeIterator(d);
|
di = dictGetSafeIterator(d);
|
||||||
if (!di) return C_ERR;
|
|
||||||
|
|
||||||
/* Write the SELECT DB opcode */
|
/* Write the SELECT DB opcode */
|
||||||
if (rdbSaveType(rdb,RDB_OPCODE_SELECTDB) == -1) goto werr;
|
if (rdbSaveType(rdb,RDB_OPCODE_SELECTDB) == -1) goto werr;
|
||||||
@ -1130,8 +1141,8 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
|
di = NULL; /* So that we don't release it again on error. */
|
||||||
}
|
}
|
||||||
di = NULL; /* So that we don't release it again on error. */
|
|
||||||
|
|
||||||
/* If we are storing the replication information on disk, persist
|
/* If we are storing the replication information on disk, persist
|
||||||
* the script cache as well: on successful PSYNC after a restart, we need
|
* the script cache as well: on successful PSYNC after a restart, we need
|
||||||
@ -1145,6 +1156,7 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {
|
|||||||
goto werr;
|
goto werr;
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
|
di = NULL; /* So that we don't release it again on error. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF opcode */
|
/* EOF opcode */
|
||||||
|
Loading…
Reference in New Issue
Block a user