diff --git a/CHANGELOG.md b/CHANGELOG.md index 3848913..b02ef43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ ## Unreleased - ReleaseDate +### Fixed + +- `Base64Vec` can now be deserialized from CBOR byte strings longer than 4096 + bytes, as well as from indefinite-length (chunked) byte strings. Previously, + these failed with "invalid type: bytes, expected bytes". + ## [0.1.1] - 2026-10-20 ### Changed diff --git a/src/base64_vec.rs b/src/base64_vec.rs index 45547fb..81c6745 100644 --- a/src/base64_vec.rs +++ b/src/base64_vec.rs @@ -286,7 +286,7 @@ mod serde_impls { } } - deserializer.deserialize_bytes(BytesVisitor) + deserializer.deserialize_byte_buf(BytesVisitor) } } diff --git a/tests/integration/base64_serde.rs b/tests/integration/base64_serde.rs index 387d3c5..720e3a4 100644 --- a/tests/integration/base64_serde.rs +++ b/tests/integration/base64_serde.rs @@ -140,3 +140,38 @@ fn base64_vec_direct() { serde_json::from_str(&json).expect("deserialized"); assert_eq!(fixture, roundtrip); } + +/// Tests that deserializing large byte buffers works with ciborium. +/// +/// ciborium's deserialize_bytes only accepts definite-length byte strings that +/// fit its 4096-byte scratch buffer, so we must call `deserialize_byte_buf` +/// instead. +#[test] +fn base64_cbor_large_and_indefinite_length() { + let large: Vec = (0..=255).cycle().take(4097).collect(); + let attr = WithBase64VecAttr { data: large.clone() }; + let direct = WithBase64VecDirect { data: Base64Vec::new(large) }; + + let mut cbor = Vec::new(); + ciborium::ser::into_writer(&attr, &mut cbor) + .expect("serializing large value as CBOR succeeded"); + let attr_roundtrip: WithBase64VecAttr = + ciborium::de::from_reader(&cbor[..]) + .expect("large CBOR byte string deserialized via attr"); + assert_eq!(attr, attr_roundtrip); + let direct_roundtrip: WithBase64VecDirect = + ciborium::de::from_reader(&cbor[..]) + .expect("large CBOR byte string deserialized directly"); + assert_eq!(direct, direct_roundtrip); + + // This is the CBOR encoding for {"data": (_ h'0102' h'03')}, an + // indefinite-length byte string split into two chunks. + let indefinite = hex!("a1 6464617461 5f 42 0102 41 03 ff"); + let attr: WithBase64VecAttr = ciborium::de::from_reader(&indefinite[..]) + .expect("indefinite-length CBOR byte string deserialized via attr"); + assert_eq!(attr.data, [1, 2, 3]); + let direct: WithBase64VecDirect = + ciborium::de::from_reader(&indefinite[..]) + .expect("indefinite-length CBOR byte string deserialized directly"); + assert_eq!(direct.data, Base64Vec::new(vec![1, 2, 3])); +}