cube_format: a geometry encodes the version it is, not a constant
V3::encode wrote a hardcoded VERSION_V3. It had no callers, so the mistake cost nothing — and then userspace's v4 writer became the first caller, and a v4 geometry would have been published under a v3 header: every reader walking a 42-byte index 40 bytes at a time, finding a store that is silently wrong. One wrong byte, found before the first v4 image was written rather than after.
This commit is contained in:
@@ -219,12 +219,18 @@ impl V3 {
|
||||
|
||||
/// Write the header this geometry describes. `image_bytes` is filled in by the caller's
|
||||
/// arithmetic, since only it knows how long the values are.
|
||||
///
|
||||
/// The version written is the geometry's own rather than a constant. A v4 geometry has a
|
||||
/// 42-byte index, and a header saying v3 would tell every reader to walk it 40 bytes at a time
|
||||
/// — one wrong byte that silently mis-addresses the whole store. This had no callers when it
|
||||
/// was written, so the mistake cost nothing; it has one now, and finding it before the first
|
||||
/// v4 image is written is the whole value of fixing it here.
|
||||
pub fn encode(&self, out: &mut [u8], curve: u8, image_bytes: u64) -> Result<usize, Bad> {
|
||||
if out.len() < HEADER_LEN_V3 {
|
||||
return Err(Bad::Extent);
|
||||
}
|
||||
out[0..4].copy_from_slice(MAGIC);
|
||||
out[4] = VERSION_V3;
|
||||
out[4] = self.version;
|
||||
out[5] = curve;
|
||||
out[6..14].copy_from_slice(&image_bytes.to_le_bytes());
|
||||
out[14..22].copy_from_slice(&self.record_count.to_le_bytes());
|
||||
|
||||
Reference in New Issue
Block a user