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 fd052bd fix: Reject empty Decimal bytes during schema-aware
serialization (#684)
fd052bd is described below
commit fd052bd7306478e60fc754a8a8955a3d2a5e28ac
Author: RanaPriyansh <[email protected]>
AuthorDate: Mon Sep 21 12:44:57 2026 -0700
fix: Reject empty Decimal bytes during schema-aware serialization (#684)
* fix: Reject empty Decimal bytes during schema-aware serialization
Reject empty bytes-backed Decimal values before direct or selected union
serialization writes bytes. Preserve ordinary bytes, fixed branches, and union
selection.
Generated-by: OpenAI Codex
* fix: use contextual errors for empty Decimal bytes
---------
Co-authored-by: Priyansh Rana <[email protected]>
Co-authored-by: Martin Grigorov <[email protected]>
---
avro/src/serde/ser_schema/mod.rs | 38 ++++++++++++++++++++++++++++++++++++++
avro/src/serde/ser_schema/union.rs | 12 ++++++++++++
2 files changed, 50 insertions(+)
diff --git a/avro/src/serde/ser_schema/mod.rs b/avro/src/serde/ser_schema/mod.rs
index f47beec..8e7b596 100644
--- a/avro/src/serde/ser_schema/mod.rs
+++ b/avro/src/serde/ser_schema/mod.rs
@@ -355,6 +355,10 @@ impl<'s, 'w, W: Write, S: Borrow<Schema>> Serializer for
SchemaAwareSerializer<'
fn serialize_bytes(mut self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
match self.schema {
+ Schema::Decimal(DecimalSchema {
+ inner: InnerDecimalSchema::Bytes,
+ ..
+ }) if v.is_empty() => Err(self.error("bytes", "Bytes cannot be
empty for a Schema::Decimal")),
Schema::Bytes | Schema::BigDecimal | Schema::Decimal(DecimalSchema
{ inner: InnerDecimalSchema::Bytes, ..}) | Schema::Uuid(UuidSchema::Bytes) => {
self.write_bytes_with_len(v)
}
@@ -1459,6 +1463,40 @@ mod tests {
Ok(())
}
+ #[test]
+ fn avro_rs_683_empty_decimal_bytes() -> TestResult {
+ let schema =
+ Schema::parse_str(r#"{"type": "bytes", "logicalType": "decimal",
"precision": 42}"#)?;
+ let names = HashMap::new();
+
+ assert_serialize(Bytes::new(&[0]), &schema, &names, &[0x2, 0x0]);
+ assert_serialize_err(
+ Bytes::new(&[]),
+ &schema,
+ &names,
+ r"Failed to serialize value of type `bytes` using
Schema::Decimal(DecimalSchema { precision: 42, scale: 0, inner: Bytes }): Bytes
cannot be empty for a Schema::Decimal",
+ );
+
+ Ok(())
+ }
+
+ #[test]
+ fn avro_rs_683_union_empty_decimal_bytes() -> TestResult {
+ let schema =
+ Schema::parse_str(r#"[{"type": "bytes", "logicalType": "decimal",
"precision": 42}]"#)?;
+ let names = HashMap::new();
+
+ assert_serialize(Bytes::new(&[0]), &schema, &names, &[0x00, 0x2, 0x0]);
+ assert_serialize_err(
+ Bytes::new(&[]),
+ &schema,
+ &names,
+ r"Failed to serialize value of type `bytes` using
Schema::Union(UnionSchema { schemas: [Decimal(DecimalSchema { precision: 42,
scale: 0, inner: Bytes })] }): Bytes cannot be empty for a Schema::Decimal",
+ );
+
+ Ok(())
+ }
+
#[test]
fn test_serialize_decimal_fixed() -> TestResult {
let schema = Schema::parse_str(
diff --git a/avro/src/serde/ser_schema/union.rs
b/avro/src/serde/ser_schema/union.rs
index 37c46b5..d361bc9 100644
--- a/avro/src/serde/ser_schema/union.rs
+++ b/avro/src/serde/ser_schema/union.rs
@@ -314,6 +314,18 @@ impl<'s, 'w, W: Write, S: Borrow<Schema>> Serializer for
UnionSerializer<'s, 'w,
}
}
};
+ if with_len
+ && v.is_empty()
+ && matches!(
+ self.union.get_variant(index)?,
+ Schema::Decimal(crate::schema::DecimalSchema {
+ inner: crate::schema::InnerDecimalSchema::Bytes,
+ ..
+ })
+ )
+ {
+ return Err(self.error("bytes", "Bytes cannot be empty for a
Schema::Decimal"));
+ }
let mut bytes_written = zig_i32(index as i32, &mut *self.writer)?;
if with_len {
bytes_written += self.write_bytes_with_len(v)?;