@@ -76,6 +76,7 @@ struct {
7676 rio * rio ;
7777 robj * key ; /* Current key we are reading. */
7878 int key_type ; /* Current key type if != -1. */
79+ int rdbver ; /* RDB version. */
7980 unsigned long keys ; /* Number of keys processed. */
8081 unsigned long expires ; /* Number of keys with an expire. */
8182 unsigned long already_expired ; /* Number of keys already expired. */
@@ -625,13 +626,17 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) {
625626 goto err ;
626627 }
627628 rdbver = atoi (buf + 6 );
628- if (rdbver < 1 || rdbver > RDB_VERSION ||
629+ if (rdbver < 1 ||
629630 (rdbver < RDB_FOREIGN_VERSION_MIN && !is_redis_magic ) ||
630- (rdbver >= RDB_FOREIGN_VERSION_MIN && rdbver <= RDB_FOREIGN_VERSION_MAX ) ||
631631 (rdbver > RDB_FOREIGN_VERSION_MAX && !is_valkey_magic )) {
632632 rdbCheckError ("Can't handle RDB format version %d" , rdbver );
633633 goto err ;
634+ } else if (rdbver > RDB_VERSION ) {
635+ rdbCheckInfo ("Future RDB version %d detected" , rdbver );
636+ } else if (rdbIsForeignVersion (rdbver )) {
637+ rdbCheckInfo ("Foreign RDB version %d detected" , rdbver );
634638 }
639+ rdbstate .rdbver = rdbver ;
635640
636641 expiretime = -1 ;
637642 while (1 ) {
@@ -689,6 +694,12 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) {
689694 if ((db_size = rdbLoadLen (& rdb , NULL )) == RDB_LENERR ) goto eoferr ;
690695 if ((expires_size = rdbLoadLen (& rdb , NULL )) == RDB_LENERR ) goto eoferr ;
691696 continue ; /* Read type again. */
697+ } else if (type == RDB_OPCODE_SLOT_INFO ) {
698+ /* Hint used in foreign RDB versions. */
699+ if (rdbLoadLen (& rdb , NULL ) == RDB_LENERR ) goto eoferr ;
700+ if (rdbLoadLen (& rdb , NULL ) == RDB_LENERR ) goto eoferr ;
701+ if (rdbLoadLen (& rdb , NULL ) == RDB_LENERR ) goto eoferr ;
702+ continue ; /* Read type again. */
692703 } else if (type == RDB_OPCODE_AUX ) {
693704 /* AUX: generic string-string fields. Use to add state to RDB
694705 * which is backward compatible. Implementations of RDB loading
@@ -742,11 +753,19 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) {
742753 }
743754 rdbstate .functions_num ++ ;
744755 continue ;
745- } else {
746- if (!rdbIsObjectType (type )) {
756+ } else if (rdbIsForeignVersion (rdbver ) &&
757+ type >= RDB_FOREIGN_TYPE_MIN &&
758+ type <= RDB_FOREIGN_TYPE_MAX ) {
759+ rdbCheckError ("Unknown object type %d in RDB file with foreign version %d" , type , rdbver );
760+ goto err ;
761+ } else if (!rdbIsObjectType (type )) {
762+ if (rdbver > RDB_VERSION ) {
763+ rdbCheckError ("Unknown object type %d in RDB file with future version %d" , type , rdbver );
764+ } else {
747765 rdbCheckError ("Invalid object type: %d" , type );
748- goto err ;
749766 }
767+ goto err ;
768+ } else {
750769 rdbstate .key_type = type ;
751770 }
752771
@@ -894,8 +913,13 @@ int redis_check_rdb_main(int argc, char **argv, FILE *fp) {
894913 rdbCheckInfo ("Checking RDB file %s" , argv [1 ]);
895914 rdbCheckSetupSignals ();
896915 int retval = redis_check_rdb (argv [1 ], fp );
916+ rdbCheckInfo ("Check RDB returned error code %d (0 means success)" , retval );
897917 if (retval == 0 ) {
898- rdbCheckInfo ("\\o/ RDB looks OK! \\o/" );
918+ if (rdbIsForeignVersion (rdbstate .rdbver ) || rdbstate .rdbver > RDB_VERSION ) {
919+ rdbCheckInfo ("\\o/ RDB looks OK, but loading requires config 'rdb-version-check relaxed'" );
920+ } else {
921+ rdbCheckInfo ("\\o/ RDB looks OK! \\o/" );
922+ }
899923 rdbShowGenericInfo ();
900924 }
901925 if (fp ) return (retval == 0 ) ? C_OK : C_ERR ;
0 commit comments