Skip to content

Commit 0fbf687

Browse files
Copilotdoublegate
andcommitted
fix: bump mmap format version to prevent bincode compatibility issues
Increment file format version from 1 to 2 to distinguish the new rkyv+length-prefix encoding from the old bincode format. Version 1 files are now explicitly rejected with a clear error message directing users to regenerate their scan results. This prevents silent data corruption when attempting to read old bincode files with the new rkyv deserialization code. - Writer: Changed header version from 1 to 2 with explanatory comment - Reader: Added version check that rejects v1 files with helpful error message - Added test to verify version 1 files are properly rejected Co-authored-by: doublegate <6858123+doublegate@users.noreply.github.com>
1 parent 6c360eb commit 0fbf687

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

crates/prtip-scanner/src/output/mmap_reader.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,18 @@ impl MmapResultReader {
3434

3535
// Parse header
3636
let version = u64::from_le_bytes(mmap[0..8].try_into().unwrap());
37-
if version != 1 {
37+
if version == 1 {
3838
return Err(io::Error::new(
3939
io::ErrorKind::InvalidData,
40-
format!("Unsupported version: {}", version),
40+
"Incompatible file format: version 1 (bincode) is no longer supported. \
41+
This file was created with an older version of the scanner. \
42+
Please regenerate scan results with the current version (rkyv format, version 2).",
43+
));
44+
}
45+
if version != 2 {
46+
return Err(io::Error::new(
47+
io::ErrorKind::InvalidData,
48+
format!("Unsupported version: {}. Expected version 2 (rkyv format).", version),
4149
));
4250
}
4351

@@ -242,4 +250,44 @@ mod tests {
242250
assert!(reader.get_entry(1).is_none());
243251
assert!(reader.get_entry(100).is_none());
244252
}
253+
254+
#[test]
255+
fn test_mmap_version_1_rejected() {
256+
use std::io::Write;
257+
258+
let temp = NamedTempFile::new().unwrap();
259+
let path = temp.path().to_owned();
260+
261+
// Create a file with version 1 header (old bincode format)
262+
{
263+
let mut file = std::fs::OpenOptions::new()
264+
.write(true)
265+
.create(true)
266+
.truncate(true)
267+
.open(&path)
268+
.unwrap();
269+
270+
// Write a version 1 header
271+
file.write_all(&1u64.to_le_bytes()).unwrap(); // version = 1
272+
file.write_all(&0u64.to_le_bytes()).unwrap(); // entry_count = 0
273+
file.write_all(&(ENTRY_SIZE as u64).to_le_bytes())
274+
.unwrap(); // entry_size
275+
file.write_all(&0u64.to_le_bytes()).unwrap(); // checksum
276+
// Pad to HEADER_SIZE
277+
file.write_all(&vec![0u8; HEADER_SIZE - 32]).unwrap();
278+
}
279+
280+
// Attempt to open should fail with clear error message
281+
let result = MmapResultReader::open(&path);
282+
assert!(result.is_err());
283+
if let Err(err) = result {
284+
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
285+
let err_msg = err.to_string();
286+
assert!(
287+
err_msg.contains("version 1") && err_msg.contains("bincode"),
288+
"Error message should mention version 1 and bincode format: {}",
289+
err_msg
290+
);
291+
}
292+
}
245293
}

crates/prtip-scanner/src/output/mmap_writer.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ impl MmapResultWriter {
137137
}
138138

139139
fn write_header(&mut self) -> io::Result<()> {
140-
// Version: 1
141-
self.mmap[0..8].copy_from_slice(&1u64.to_le_bytes());
140+
// Version: 2 (rkyv format with length prefix)
141+
// Version 1 was bincode format (deprecated)
142+
self.mmap[0..8].copy_from_slice(&2u64.to_le_bytes());
142143
// Entry count: 0
143144
self.mmap[8..16].copy_from_slice(&0u64.to_le_bytes());
144145
// Entry size: ENTRY_SIZE

0 commit comments

Comments
 (0)