From cd87b3c71f79062d9e95abada186e1cac03f5cc6 Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 9 May 2018 11:03:27 +0200 Subject: [PATCH] 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. --- src/rdb.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/rdb.c b/src/rdb.c index 27c3aa786..728a1c216 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -778,7 +778,11 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) { while((de = dictNext(di)) != NULL) { sds ele = dictGetKey(de); if ((n = rdbSaveRawString(rdb,(unsigned char*)ele,sdslen(ele))) - == -1) return -1; + == -1) + { + dictReleaseIterator(di); + return -1; + } nwritten += n; } dictReleaseIterator(di); @@ -846,10 +850,18 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) { sds value = dictGetVal(de); if ((n = rdbSaveRawString(rdb,(unsigned char*)field, - sdslen(field))) == -1) return -1; + sdslen(field))) == -1) + { + dictReleaseIterator(di); + return -1; + } nwritten += n; if ((n = rdbSaveRawString(rdb,(unsigned char*)value, - sdslen(value))) == -1) return -1; + sdslen(value))) == -1) + { + dictReleaseIterator(di); + return -1; + } nwritten += n; } dictReleaseIterator(di); @@ -1088,7 +1100,6 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) { dict *d = db->dict; if (dictSize(d) == 0) continue; di = dictGetSafeIterator(d); - if (!di) return C_ERR; /* Write the SELECT DB opcode */ 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); + 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 * 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; } dictReleaseIterator(di); + di = NULL; /* So that we don't release it again on error. */ } /* EOF opcode */