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 c12ab35  fix: Don't return `Value::Null` on EOF in `decode.rs` (#664)
c12ab35 is described below

commit c12ab35ab5844993b825fd2ef335147c0cb21973
Author: Kriskras99 <[email protected]>
AuthorDate: Mon Sep 7 08:47:23 2026 +0200

    fix: Don't return `Value::Null` on EOF in `decode.rs` (#664)
    
    This corrupt a union that is being decoded and makes the decoded value
    not match the schema.
    
    Reported-by: Security scans
---
 avro/src/decode.rs | 69 ++++++++++++++++++------------------------------------
 1 file changed, 23 insertions(+), 46 deletions(-)

diff --git a/avro/src/decode.rs b/avro/src/decode.rs
index e29daa7..24d61d2 100644
--- a/avro/src/decode.rs
+++ b/avro/src/decode.rs
@@ -180,19 +180,13 @@ fn decode_internal_body<R: Read, S: Borrow<Schema>>(
         Schema::Null => Ok(Value::Null),
         Schema::Boolean => {
             let mut buf = [0u8; 1];
-            match reader.read_exact(&mut buf[..]) {
-                Ok(_) => match buf[0] {
-                    0u8 => Ok(Value::Boolean(false)),
-                    1u8 => Ok(Value::Boolean(true)),
-                    _ => Err(Details::BoolValue(buf[0]).into()),
-                },
-                Err(io_err) => {
-                    if let ErrorKind::UnexpectedEof = io_err.kind() {
-                        Ok(Value::Null)
-                    } else {
-                        Err(Details::ReadBoolean(io_err).into())
-                    }
-                }
+            reader
+                .read_exact(&mut buf[..])
+                .map_err(Details::ReadBoolean)?;
+            match buf[0] {
+                0u8 => Ok(Value::Boolean(false)),
+                1u8 => Ok(Value::Boolean(true)),
+                _ => Err(Details::BoolValue(buf[0]).into()),
             }
         }
         Schema::Decimal(DecimalSchema { inner, .. }) => match inner {
@@ -312,18 +306,10 @@ fn decode_internal_body<R: Read, S: Borrow<Schema>>(
             let len = decode_len(reader)?;
             ctx.debit_bytes(len)?;
             let mut buf = vec![0u8; len];
-            match reader.read_exact(&mut buf) {
-                Ok(_) => Ok(Value::String(
-                    String::from_utf8(buf).map_err(Details::ConvertToUtf8)?,
-                )),
-                Err(io_err) => {
-                    if let ErrorKind::UnexpectedEof = io_err.kind() {
-                        Ok(Value::Null)
-                    } else {
-                        Err(Details::ReadString(io_err).into())
-                    }
-                }
-            }
+            reader.read_exact(&mut buf).map_err(Details::ReadString)?;
+            Ok(Value::String(
+                String::from_utf8(buf).map_err(Details::ConvertToUtf8)?,
+            ))
         }
         Schema::Fixed(FixedSchema { size, .. }) => {
             ctx.debit_bytes(*size)?;
@@ -405,27 +391,18 @@ fn decode_internal_body<R: Read, S: Borrow<Schema>>(
 
             Ok(Value::Map(items))
         }
-        Schema::Union(inner) => match 
zag_i64(reader).map_err(Error::into_details) {
-            Ok(index) => {
-                let variants = inner.variants();
-                let variant = variants
-                    .get(usize::try_from(index).map_err(|e| 
Details::ConvertI64ToUsize(e, index))?)
-                    .ok_or(Details::GetUnionVariant {
-                        index,
-                        num_variants: variants.len(),
-                    })?;
-                let value = decode_internal(variant, names, 
enclosing_namespace, reader, ctx)?;
-                Ok(Value::Union(index as u32, Box::new(value)))
-            }
-            Err(Details::ReadVariableIntegerBytes(io_err)) => {
-                if let ErrorKind::UnexpectedEof = io_err.kind() {
-                    Ok(Value::Union(0, Box::new(Value::Null)))
-                } else {
-                    Err(Details::ReadVariableIntegerBytes(io_err).into())
-                }
-            }
-            Err(io_err) => Err(Error::new(io_err)),
-        },
+        Schema::Union(inner) => {
+            let index = zag_i64(reader)?;
+            let variants = inner.variants();
+            let variant = variants
+                .get(usize::try_from(index).map_err(|e| 
Details::ConvertI64ToUsize(e, index))?)
+                .ok_or(Details::GetUnionVariant {
+                    index,
+                    num_variants: variants.len(),
+                })?;
+            let value = decode_internal(variant, names, enclosing_namespace, 
reader, ctx)?;
+            Ok(Value::Union(index as u32, Box::new(value)))
+        }
         Schema::Record(RecordSchema { name, fields, .. }) => {
             let fully_qualified_name = 
name.fully_qualified_name(enclosing_namespace);
             ctx.debit_items::<(String, Value)>(fields.len())?;

Reply via email to