This is an automated email from the ASF dual-hosted git repository.

Kriskras99 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 974efd4  Validate negative OCF block size before conversion (#586)
974efd4 is described below

commit 974efd4edbccde55ec4849ffebec19054c40537a
Author: MitNarodia <[email protected]>
AuthorDate: Tue Jul 14 15:15:01 2026 +0530

    Validate negative OCF block size before conversion (#586)
    
    * Validate negative OCF block size before conversion
    
    * Prefix the test name with the pr number
    
    * fix: Require positive block length
    
    * chore: Explain raw bytes
    
    * chore: rename `read_ulong` to `read_usize`
    
    ---------
    
    Co-authored-by: Mit Narodia <[email protected]>
    Co-authored-by: Martin Grigorov <[email protected]>
    Co-authored-by: Kriskras99 <[email protected]>
---
 avro/src/reader/block.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++----
 avro/src/util.rs         |  6 +++--
 2 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/avro/src/reader/block.rs b/avro/src/reader/block.rs
index 8899c3a..5e9ae1b 100644
--- a/avro/src/reader/block.rs
+++ b/avro/src/reader/block.rs
@@ -142,11 +142,11 @@ impl<'r, R: Read> Block<'r, R> {
     /// the block. The objects are stored in an internal buffer to the 
`Reader`.
     fn read_block_next(&mut self) -> AvroResult<()> {
         assert!(self.is_empty(), "Expected self to be empty!");
-        match util::read_long(&mut self.reader).map_err(Error::into_details) {
+        match util::read_usize(&mut self.reader).map_err(Error::into_details) {
             Ok(block_len) => {
-                self.message_count = block_len as usize;
-                let block_bytes = util::read_long(&mut self.reader)?;
-                self.fill_buf(block_bytes as usize)?;
+                self.message_count = block_len;
+                let block_bytes = util::read_usize(&mut self.reader)?;
+                self.fill_buf(block_bytes)?;
                 let mut marker = [0u8; 16];
                 self.reader
                     .read_exact(&mut marker)
@@ -353,3 +353,52 @@ fn read_codec(metadata: &HashMap<String, Value>) -> 
AvroResult<Codec> {
 
     result.unwrap_or(Ok(Codec::Null))
 }
+
+#[cfg(test)]
+mod tests {
+    use super::Block;
+    use crate::error::Details;
+    use crate::{Codec, Schema};
+
+    #[test]
+    fn avro_rs_586_negative_block_size() {
+        let mut block = Block::<'_, &[u8]> {
+            // Block header with an object count of 1 and a block size of -1
+            reader: &[0x02, 0x01],
+            buf: vec![],
+            buf_idx: 0,
+            message_count: 0,
+            marker: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+            codec: Codec::Null,
+            writer_schema: Schema::Null,
+            schemata: vec![],
+            user_metadata: Default::default(),
+            names_refs: Default::default(),
+            human_readable: false,
+        };
+
+        let err = block.read_block_next().unwrap_err().into_details();
+        assert!(matches!(err, Details::ConvertI64ToUsize(_, _)));
+    }
+
+    #[test]
+    fn avro_rs_586_negative_block_len() {
+        let mut block = Block::<'_, &[u8]> {
+            // Block header with an object count of -1 and a block size of 0
+            reader: &[0x01, 0x00],
+            buf: vec![],
+            buf_idx: 0,
+            message_count: 0,
+            marker: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+            codec: Codec::Null,
+            writer_schema: Schema::Null,
+            schemata: vec![],
+            user_metadata: Default::default(),
+            names_refs: Default::default(),
+            human_readable: false,
+        };
+
+        let err = block.read_block_next().unwrap_err().into_details();
+        assert!(matches!(err, Details::ConvertI64ToUsize(_, _)));
+    }
+}
diff --git a/avro/src/util.rs b/avro/src/util.rs
index 8728c9e..090d5c3 100644
--- a/avro/src/util.rs
+++ b/avro/src/util.rs
@@ -73,8 +73,10 @@ impl MapHelper for Map<String, Value> {
     }
 }
 
-pub(crate) fn read_long<R: Read>(reader: &mut R) -> AvroResult<i64> {
-    zag_i64(reader)
+/// Decode a long from the reader and convert it to a usize.
+pub(crate) fn read_usize<R: Read>(reader: &mut R) -> AvroResult<usize> {
+    let long = zag_i64(reader)?;
+    usize::try_from(long).map_err(|e| Details::ConvertI64ToUsize(e, 
long).into())
 }
 
 /// Write the number as a zigzagged varint to the writer.

Reply via email to