diff --git a/seaweed-volume/src/storage/needle/needle.rs b/seaweed-volume/src/storage/needle/needle.rs index b55fce04c..1ab948907 100644 --- a/seaweed-volume/src/storage/needle/needle.rs +++ b/seaweed-volume/src/storage/needle/needle.rs @@ -281,7 +281,7 @@ impl Needle { } /// Read the version 2/3 body data from bytes (size bytes starting after header). - /// Tolerates EOF/truncated data (matching Go's readNeedleDataVersion2 which tolerates io.EOF). + /// Returns IndexOutOfRange errors for truncated data (matching Go's readNeedleDataVersion2). pub fn read_body_v2(&mut self, bytes: &[u8]) -> Result<(), NeedleError> { let len_bytes = bytes.len(); let mut index = 0; @@ -300,20 +300,18 @@ impl Needle { // Data if index + self.data_size as usize > len_bytes { - // Tolerate truncated data: read what we can - self.data = bytes[index..].to_vec(); - return Ok(()); + return Err(NeedleError::IndexOutOfRange(1)); } self.data = bytes[index..index + self.data_size as usize].to_vec(); index += self.data_size as usize; - // Read non-data metadata (also tolerates EOF) + // Read non-data metadata self.read_body_v2_non_data(&bytes[index..])?; Ok(()) } /// Read version 2/3 metadata fields (everything after Data). - /// Tolerates truncated data (matching Go's readNeedleDataVersion2 EOF tolerance). + /// Returns IndexOutOfRange errors for truncated data (matching Go's readNeedleDataVersion2). fn read_body_v2_non_data(&mut self, bytes: &[u8]) -> Result { let len_bytes = bytes.len(); let mut index = 0; @@ -331,7 +329,7 @@ impl Needle { self.name_size = bytes[index]; index += 1; if index + self.name_size as usize > len_bytes { - return Ok(index); // tolerate EOF + return Err(NeedleError::IndexOutOfRange(2)); } self.name = bytes[index..index + self.name_size as usize].to_vec(); index += self.name_size as usize; @@ -342,7 +340,7 @@ impl Needle { self.mime_size = bytes[index]; index += 1; if index + self.mime_size as usize > len_bytes { - return Ok(index); // tolerate EOF + return Err(NeedleError::IndexOutOfRange(3)); } self.mime = bytes[index..index + self.mime_size as usize].to_vec(); index += self.mime_size as usize; @@ -351,7 +349,7 @@ impl Needle { // LastModified (5 bytes) if index < len_bytes && self.has_last_modified_date() { if index + LAST_MODIFIED_BYTES_LENGTH > len_bytes { - return Ok(index); // tolerate EOF + return Err(NeedleError::IndexOutOfRange(4)); } self.last_modified = bytes_to_u64_5(&bytes[index..index + LAST_MODIFIED_BYTES_LENGTH]); index += LAST_MODIFIED_BYTES_LENGTH; @@ -360,7 +358,7 @@ impl Needle { // TTL (2 bytes) if index < len_bytes && self.has_ttl() { if index + TTL_BYTES_LENGTH > len_bytes { - return Ok(index); // tolerate EOF + return Err(NeedleError::IndexOutOfRange(5)); } self.ttl = Some(TTL::from_bytes(&bytes[index..index + TTL_BYTES_LENGTH])); index += TTL_BYTES_LENGTH; @@ -369,12 +367,12 @@ impl Needle { // Pairs if index < len_bytes && self.has_pairs() { if index + 2 > len_bytes { - return Ok(index); // tolerate EOF + return Err(NeedleError::IndexOutOfRange(6)); } self.pairs_size = u16::from_be_bytes([bytes[index], bytes[index + 1]]); index += 2; if index + self.pairs_size as usize > len_bytes { - return Ok(index); // tolerate EOF + return Err(NeedleError::IndexOutOfRange(7)); } self.pairs = bytes[index..index + self.pairs_size as usize].to_vec(); index += self.pairs_size as usize;