diff --git a/src/rdb.c b/src/rdb.c index 6665467e7cd..7b8e0969244 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -2729,11 +2729,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { quicklist *ql = quicklistNew(server.list_max_listpack_size, server.list_compress_depth); - if ( -#ifdef ENABLE_SWAP - !rdbLoadObjectGetSkipEmptyCheckFlag() && -#endif - !ziplistValidateIntegrity(encoded, encoded_len, 1, + if (!ziplistValidateIntegrity(encoded, encoded_len, 1, _listZiplistEntryConvertAndValidate, ql)) { @@ -2746,9 +2742,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) } if ( #ifdef ENABLE_SWAP - !rdbLoadObjectGetSkipEmptyCheckFlag() && + !rdbLoadObjectGetSkipEmptyCheckFlag() && #endif - ql->len == 0) { + ql->len == 0) { zfree(encoded); o->ptr = NULL; @@ -2810,11 +2806,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) case RDB_TYPE_ZSET_ZIPLIST: { unsigned char *lp = lpNew(encoded_len); - if ( -#ifdef ENABLE_SWAP - !rdbLoadObjectGetSkipEmptyCheckFlag() && -#endif - !ziplistPairsConvertAndValidateIntegrity(encoded, encoded_len, &lp)) { + if (!ziplistPairsConvertAndValidateIntegrity(encoded, encoded_len, &lp)) { rdbReportCorruptRDB("Zset ziplist integrity check failed."); zfree(lp); zfree(encoded); @@ -2872,11 +2864,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) case RDB_TYPE_HASH_ZIPLIST: { unsigned char *lp = lpNew(encoded_len); - if ( -#ifdef ENABLE_SWAP - !rdbLoadObjectGetSkipEmptyCheckFlag() && -#endif - !ziplistPairsConvertAndValidateIntegrity(encoded, encoded_len, &lp)) { + if (!ziplistPairsConvertAndValidateIntegrity(encoded, encoded_len, &lp)) { rdbReportCorruptRDB("Hash ziplist integrity check failed."); zfree(lp); zfree(encoded); diff --git a/tests/assets/swap/rordb-ziplist.rordb b/tests/assets/swap/rordb-ziplist.rordb new file mode 100644 index 00000000000..1f5bacca9f5 Binary files /dev/null and b/tests/assets/swap/rordb-ziplist.rordb differ diff --git a/tests/swap/unit/rordb_ziplist_load.tcl b/tests/swap/unit/rordb_ziplist_load.tcl new file mode 100644 index 00000000000..adda392fe48 --- /dev/null +++ b/tests/swap/unit/rordb_ziplist_load.tcl @@ -0,0 +1,36 @@ +tags {"rdb"} { + + # This fixture is an OLD-version (6.2.6-based ROR) generated rordb file that + # contains a hash and a zset stored in the legacy *ziplist* encoding + # (RDB_TYPE_HASH_ZIPLIST / RDB_TYPE_ZSET_ZIPLIST). + # + # Regression guard for the rordb-load ziplist bug: when loading a rordb + # (SkipEmptyCheckFlag = 1), rdbLoadObject() used to skip the + # ziplist->listpack data conversion(ziplistPairsConvertAndValidateIntegrity), + # leaving an empty object and silently dropping every field. + # + # With the fix, the conversion always runs, so the fields survive the load. + + set server_path [tmpdir "server.rordb-ziplist-load"] + + test "load rordb with legacy ziplist-encoded hash/zset preserves all fields" { + exec cp tests/assets/swap/rordb-ziplist.rordb $server_path + start_server [list overrides [list "dir" $server_path "dbfilename" "rordb-ziplist.rordb"]] { + assert_equal [r dbsize] 2 + + # hash: 3 fields must survive the ziplist->listpack conversion + assert_equal [r hlen ziphash] 3 + assert_equal [lsort [r hgetall ziphash]] [lsort {f1 v1 f2 v2 f3 v3}] + assert_equal [r hget ziphash f1] v1 + assert_equal [r hget ziphash f2] v2 + assert_equal [r hget ziphash f3] v3 + + # zset: 3 members must survive the ziplist->listpack conversion + assert_equal [r zcard zipzset] 3 + assert_equal [r zrange zipzset 0 -1 withscores] {a 1 b 2 c 3} + + # full read triggers swap-in merge; must not crash / underflow + assert_equal [r ping] {PONG} + } + } +}