Commit cd87b3c7 authored by antirez's avatar antirez
Browse files

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.
parent aaef5f00
...@@ -778,7 +778,11 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment