diff --git a/src/rdb.c b/src/rdb.c index 4cfb05719..ecb165194 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -3454,9 +3454,9 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) } else if (deep_integrity_validation) { /* lpGetEdgeStreamID walks the listpack, so only run after * deep integrity validation has confirmed it's well-formed. */ - streamID rax_first_entry, rax_last_entry; - if (!lpGetEdgeStreamID(head_lp, 1, &head_master, &rax_first_entry) || - !lpGetEdgeStreamID(tail_lp, 0, &tail_master, &rax_last_entry)) + streamID rax_first_id, rax_last_id; + if (!lpGetEdgeStreamID(head_lp, 1, &head_master, &rax_first_id) || + !lpGetEdgeStreamID(tail_lp, 0, &tail_master, &rax_last_id)) { rdbReportCorruptRDB("Stream edge entries unreadable"); decrRefCount(o); @@ -3466,7 +3466,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) /* The rax tail may lag behind last_id (XSETID can advance * last_id past the tail, XDEL can drop the tail entry) but * must never exceed it. */ - if (streamCompareID(&rax_last_entry, &s->last_id) > 0) { + if (streamCompareID(&rax_last_id, &s->last_id) > 0) { rdbReportCorruptRDB("Stream last_id smaller than last entry"); decrRefCount(o); return NULL; @@ -3475,7 +3475,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) /* first_id skips leading tombstones, so it must lie within * [rax_first_entry, last_id]. */ if (s->length && - (streamCompareID(&s->first_id, &rax_first_entry) < 0 || + (streamCompareID(&s->first_id, &rax_first_id) < 0 || streamCompareID(&s->first_id, &s->last_id) > 0)) { rdbReportCorruptRDB("Stream first_id out of range"); diff --git a/tests/integration/corrupt-dump.tcl b/tests/integration/corrupt-dump.tcl index c4d586462..a890b5908 100644 --- a/tests/integration/corrupt-dump.tcl +++ b/tests/integration/corrupt-dump.tcl @@ -1084,6 +1084,7 @@ test {corrupt payload: stream last_id smaller than actual tail entry} { # lowers last_id. catch {r RESTORE mystream 0 "\x1A\x02\x10\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x10\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x02\x03\x00\x01\x00\x00\x00\x02\x00\x40\x64\x40\x64\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00" REPLACE} err assert_match "*Bad data format*" $err + verify_log_message 0 "*Stream last_id smaller than last entry*" 0 r ping } } @@ -1097,6 +1098,7 @@ test {corrupt payload: stream empty rax with non-zero first_id} { # non-zero first_id with an empty rax can only be corruption. catch {r RESTORE mystream 0 "\x1A\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x40\x64\x40\x64\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00" REPLACE} err assert_match "*Bad data format*" $err + verify_log_message 0 "*Stream first_id non-zero in empty stream*" 0 r ping } } @@ -1111,6 +1113,7 @@ test {corrupt payload: stream max_deleted_entry_id beyond last_id} { # last_id, so max_deleted > last_id is corruption. catch {r RESTORE mystream 0 "\x1A\x01\x10\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x01\x01\x00\x01\x00\x02\x00\x01\x00\x40\x64\x40\x64\x00\x00\x00\x0D\x00\xBD\x89\x4D\xF3\x41\xC5\xE0\x8E" REPLACE} err assert_match "*Bad data format*" $err + verify_log_message 0 "*Stream max_deleted_entry_id beyond last_id*" 0 r ping } } @@ -1126,6 +1129,7 @@ test {corrupt payload: stream first_id below rax head entry} { # rax. A first_id smaller than the head entry is corruption. catch {r RESTORE mystream 0 "\x1A\x01\x10\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x01\x01\x00\x00\x00\x00\x00\x01\x00\x40\x64\x40\x64\x00\x00\x00\x0D\x00\xBD\x89\x4D\xF3\x41\xC5\xE0\x8E" REPLACE} err assert_match "*Bad data format*" $err + verify_log_message 0 "*Stream first_id out of range*" 0 r ping } } @@ -1140,6 +1144,7 @@ test {corrupt payload: stream first_id above last_id} { # corruption. catch {r RESTORE mystream 0 "\x1A\x01\x10\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x01\x01\x00\x02\x00\x00\x00\x01\x00\x40\x64\x40\x64\x00\x00\x00\x0D\x00\xBD\x89\x4D\xF3\x41\xC5\xE0\x8E" REPLACE} err assert_match "*Bad data format*" $err + verify_log_message 0 "*Stream first_id out of range*" 0 r ping } } @@ -1155,6 +1160,7 @@ test {corrupt payload: stream entries_added smaller than length} { # number of live entries. catch {r RESTORE mystream 0 "\x1A\x01\x10\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x01\x01\x00\x01\x00\x00\x00\x00\x00\x40\x64\x40\x64\x00\x00\x00\x0D\x00\xBD\x89\x4D\xF3\x41\xC5\xE0\x8E" REPLACE} err assert_match "*Bad data format*" $err + verify_log_message 0 "*Stream entries_added smaller than length*" 0 r ping } } @@ -1176,6 +1182,7 @@ test {corrupt payload: stream listpacks in non-ascending master order} { # is the canonical signature for this class of bypass. catch {r RESTORE mystream 0 "\x1A\x02\x10\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x10\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x1D\x00\x00\x00\x0A\x00\x01\x01\x00\x01\x01\x01\x81\x6B\x02\x00\x01\x02\x01\x00\x01\x00\x01\x81\x76\x02\x04\x01\xFF\x02\x05\x00\x05\x00\x00\x00\x02\x00\x40\x64\x40\x64\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00" REPLACE} err assert_match "*Bad data format*" $err + verify_log_message 0 "*Stream listpacks not in ascending order*" 0 r ping } }