diff --git a/crates/curp/src/server/storage/wal/error.rs b/crates/curp/src/server/storage/wal/error.rs index 9c43afe92..bc705a3ef 100644 --- a/crates/curp/src/server/storage/wal/error.rs +++ b/crates/curp/src/server/storage/wal/error.rs @@ -8,7 +8,7 @@ pub(crate) enum WALError { /// The WAL segment might reach on end /// /// NOTE: This exists because we cannot tell the difference between a corrupted WAL - /// and a normally ended WAL, as the segment files are all preallocated with zeros + /// and a normally ended WAL, as the segment files are all preallocated with zeros #[error("WAL ended")] MaybeEnded, /// The WAL corrupt error diff --git a/crates/curp/src/server/storage/wal/segment.rs b/crates/curp/src/server/storage/wal/segment.rs index 7dc3a70b8..97def61cd 100644 --- a/crates/curp/src/server/storage/wal/segment.rs +++ b/crates/curp/src/server/storage/wal/segment.rs @@ -159,7 +159,18 @@ impl WALSegment { let mut pos = 0; let mut entries = Vec::new(); while pos < buf.len() { - let (item, n) = decoder.decode(&buf[pos..])?; + let (item, n) = match decoder.decode(&buf[pos..]) { + Ok(d) => d, + Err(WALError::MaybeEnded) => { + if !buf[pos..].iter().all(|b| *b == 0) { + return Err(WALError::Corrupted(CorruptType::Codec( + "Read zero".to_owned(), + ))); + } + return Ok(entries); + } + Err(e) => return Err(e), + }; entries.push(item); pos += n; }