| 186 | |
| 187 | #[mz_ore::test] |
| 188 | fn zero_width_array_elements_decode() { |
| 189 | // The remaining-input bound must not reject valid arrays whose elements |
| 190 | // encode to zero bytes. `null` and empty records have no per-element byte |
| 191 | // floor, so a ten-element block legitimately follows its count with no |
| 192 | // element bytes at all (Materialize's own writer emits `array<null>` of |
| 193 | // ten as `[20, 0]`: block count 10, then the terminating zero block). |
| 194 | use std::str::FromStr; |
| 195 | |
| 196 | use super::{AvroDeserializer, GeneralDeserializer}; |
| 197 | use crate::types::Value; |
| 198 | use crate::util::zig_i64; |
| 199 | use crate::{Schema, ValueDecoder}; |
| 200 | |
| 201 | for (items, want) in [ |
| 202 | (r#""null""#, Value::Null), |
| 203 | ( |
| 204 | r#"{"type": "record", "name": "Empty", "fields": []}"#, |
| 205 | Value::Record(vec![]), |
| 206 | ), |
| 207 | ] { |
| 208 | let schema = |
| 209 | Schema::from_str(&format!(r#"{{"type": "array", "items": {items}}}"#)).unwrap(); |
| 210 | let mut body = Vec::new(); |
| 211 | zig_i64(10, &mut body); // ten elements... |
| 212 | body.push(0); // ...then the terminating zero block. No element bytes. |
| 213 | let dsr = GeneralDeserializer { |
| 214 | schema: schema.top_node(), |
| 215 | }; |
| 216 | let mut reader: &[u8] = &body; |
| 217 | let decoded = dsr |
| 218 | .deserialize(&mut reader, ValueDecoder) |
| 219 | .expect("a zero-width array element type must decode, not be rejected"); |
| 220 | assert_eq!(decoded, Value::Array(vec![want; 10])); |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | #[mz_ore::test] |
| 225 | fn valid_null_array_falsely_rejected() { |