Skip to main content

ave_common/
wrapper.rs

1//! JSON value wrapper with bounded Borsh serialization.
2
3use std::{
4    io::{Read, Write},
5    ops::Deref,
6};
7
8use borsh::{BorshDeserialize, BorshSerialize};
9use serde::{Deserialize, Serialize};
10use serde_json::{Map, Number, Value};
11
12// Maximum recursion depth for deserializing nested structures
13// Prevents stack overflow from deeply nested JSON/Borsh data
14const MAX_RECURSION_DEPTH: usize = 128;
15
16// Maximum array/object length to prevent memory exhaustion
17const MAX_COLLECTION_SIZE: u32 = 100_000;
18
19/// `serde_json::Value` with Borsh support and basic decoding limits.
20///
21/// This wrapper is used when Ave payloads need to cross Borsh-based boundaries
22/// without losing their JSON representation.
23#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
24pub struct ValueWrapper(pub Value);
25
26impl Deref for ValueWrapper {
27    type Target = Value;
28
29    fn deref(&self) -> &Self::Target {
30        &self.0
31    }
32}
33
34impl Default for ValueWrapper {
35    fn default() -> Self {
36        Self(Value::Null)
37    }
38}
39
40/// Serializes JSON values with explicit type tags.
41impl BorshSerialize for ValueWrapper {
42    #[inline]
43    fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
44        match &self.0 {
45            // Serialize boolean: type tag (0) + boolean value
46            Value::Bool(data) => {
47                BorshSerialize::serialize(&0u8, writer)?;
48                BorshSerialize::serialize(&data, writer)
49            }
50            // Serialize number: type tag (1) + numeric sub-type tag + value
51            Value::Number(data) => {
52                BorshSerialize::serialize(&1u8, writer)?;
53                'data: {
54                    // Try f64 first
55                    if data.is_f64() {
56                        let Some(data) = data.as_f64() else {
57                            break 'data;
58                        };
59                        BorshSerialize::serialize(&0u8, writer)?;
60                        return BorshSerialize::serialize(&data, writer);
61                    }
62                    // Try i64
63                    else if data.is_i64() {
64                        let Some(data) = data.as_i64() else {
65                            break 'data;
66                        };
67                        BorshSerialize::serialize(&1u8, writer)?;
68                        return BorshSerialize::serialize(&data, writer);
69                    }
70                    // Try u64
71                    else if data.is_u64() {
72                        let Some(data) = data.as_u64() else {
73                            break 'data;
74                        };
75                        BorshSerialize::serialize(&2u8, writer)?;
76                        return BorshSerialize::serialize(&data, writer);
77                    }
78                }
79                Err(std::io::Error::new(
80                    std::io::ErrorKind::InvalidData,
81                    "Invalid number type",
82                ))
83            }
84            // Serialize string: type tag (2) + string data
85            Value::String(data) => {
86                BorshSerialize::serialize(&2u8, writer)?;
87                BorshSerialize::serialize(&data, writer)
88            }
89            // Serialize array: type tag (3) + length + elements
90            Value::Array(data) => {
91                BorshSerialize::serialize(&3u8, writer)?;
92                // Check array length fits in u32
93                let len = u32::try_from(data.len()).map_err(|_| {
94                    std::io::Error::new(
95                        std::io::ErrorKind::InvalidInput,
96                        format!(
97                            "Array too large to serialize: {} elements exceeds u32::MAX",
98                            data.len()
99                        ),
100                    )
101                })?;
102                BorshSerialize::serialize(&len, writer)?;
103                for element in data {
104                    let element = Self(element.to_owned());
105                    BorshSerialize::serialize(&element, writer)?;
106                }
107                Ok(())
108            }
109            // Serialize object: type tag (4) + length + key-value pairs
110            Value::Object(data) => {
111                BorshSerialize::serialize(&4u8, writer)?;
112                // Check object length fits in u32
113                let len = u32::try_from(data.len()).map_err(|_| {
114                    std::io::Error::new(
115                        std::io::ErrorKind::InvalidInput,
116                        format!(
117                            "Object too large to serialize: {} keys exceeds u32::MAX",
118                            data.len()
119                        ),
120                    )
121                })?;
122                BorshSerialize::serialize(&len, writer)?;
123                for (key, value) in data {
124                    BorshSerialize::serialize(&key, writer)?;
125                    let value = Self(value.to_owned());
126                    BorshSerialize::serialize(&value, writer)?;
127                }
128                Ok(())
129            }
130            // Serialize null: just type tag (5)
131            Value::Null => BorshSerialize::serialize(&5u8, writer),
132        }
133    }
134}
135
136impl ValueWrapper {
137    /// Internal deserialization with recursion depth tracking.
138    fn deserialize_reader_with_depth<R: Read>(
139        reader: &mut R,
140        depth: usize,
141    ) -> std::io::Result<Self> {
142        if depth > MAX_RECURSION_DEPTH {
143            return Err(std::io::Error::new(
144                std::io::ErrorKind::InvalidInput,
145                format!(
146                    "Recursion depth limit exceeded: maximum depth is {}",
147                    MAX_RECURSION_DEPTH
148                ),
149            ));
150        }
151
152        // Read the type discriminator byte
153        let order: u8 = BorshDeserialize::deserialize_reader(reader)?;
154        match order {
155            // Type 0: Boolean
156            0 => {
157                let data: bool = BorshDeserialize::deserialize_reader(reader)?;
158                Ok(Self(Value::Bool(data)))
159            }
160            // Type 1: Number (requires reading numeric sub-type)
161            1 => {
162                let internal_order: u8 =
163                    BorshDeserialize::deserialize_reader(reader)?;
164                match internal_order {
165                    // Sub-type 0: f64
166                    0 => {
167                        let data: f64 =
168                            BorshDeserialize::deserialize_reader(reader)?;
169                        let Some(data_f64) = Number::from_f64(data) else {
170                            return Err(std::io::Error::new(
171                                std::io::ErrorKind::InvalidInput,
172                                format!("Invalid f64 Number: {}", data),
173                            ));
174                        };
175                        Ok(Self(Value::Number(data_f64)))
176                    }
177                    // Sub-type 1: i64
178                    1 => {
179                        let data: i64 =
180                            BorshDeserialize::deserialize_reader(reader)?;
181                        Ok(Self(Value::Number(Number::from(data))))
182                    }
183                    // Sub-type 2: u64
184                    2 => {
185                        let data: u64 =
186                            BorshDeserialize::deserialize_reader(reader)?;
187                        Ok(Self(Value::Number(Number::from(data))))
188                    }
189                    _ => Err(std::io::Error::new(
190                        std::io::ErrorKind::InvalidInput,
191                        format!(
192                            "Invalid Number representation: {}",
193                            internal_order
194                        ),
195                    )),
196                }
197            }
198            // Type 2: String
199            2 => {
200                let data: String =
201                    BorshDeserialize::deserialize_reader(reader)?;
202                Ok(Self(Value::String(data)))
203            }
204            // Type 3: Array (read length, then elements)
205            3 => {
206                let len = u32::deserialize_reader(reader)?;
207
208                // Security check: prevent excessive array sizes
209                if len > MAX_COLLECTION_SIZE {
210                    return Err(std::io::Error::new(
211                        std::io::ErrorKind::InvalidInput,
212                        format!(
213                            "Array size too large: {} exceeds maximum of {}",
214                            len, MAX_COLLECTION_SIZE
215                        ),
216                    ));
217                }
218
219                if len == 0 {
220                    Ok(Self(Value::Array(Vec::new())))
221                } else {
222                    let mut result = Vec::with_capacity(len as usize);
223                    // Use checked arithmetic to prevent depth overflow
224                    let next_depth = depth.checked_add(1).ok_or_else(|| {
225                        std::io::Error::new(
226                            std::io::ErrorKind::InvalidInput,
227                            "Recursion depth counter overflow",
228                        )
229                    })?;
230                    for _ in 0..len {
231                        result.push(
232                            Self::deserialize_reader_with_depth(
233                                reader, next_depth,
234                            )?
235                            .0,
236                        );
237                    }
238                    Ok(Self(Value::Array(result)))
239                }
240            }
241            // Type 4: Object (read length, then key-value pairs)
242            4 => {
243                let len = u32::deserialize_reader(reader)?;
244
245                // Security check: prevent excessive object sizes
246                if len > MAX_COLLECTION_SIZE {
247                    return Err(std::io::Error::new(
248                        std::io::ErrorKind::InvalidInput,
249                        format!(
250                            "Object size too large: {} exceeds maximum of {}",
251                            len, MAX_COLLECTION_SIZE
252                        ),
253                    ));
254                }
255
256                let mut result = Map::new();
257                // Use checked arithmetic to prevent depth overflow
258                let next_depth = depth.checked_add(1).ok_or_else(|| {
259                    std::io::Error::new(
260                        std::io::ErrorKind::InvalidInput,
261                        "Recursion depth counter overflow",
262                    )
263                })?;
264                for _ in 0..len {
265                    let key = String::deserialize_reader(reader)?;
266                    let value = Self::deserialize_reader_with_depth(
267                        reader, next_depth,
268                    )?;
269                    result.insert(key, value.0);
270                }
271                Ok(Self(Value::Object(result)))
272            }
273            // Type 5: Null
274            5 => Ok(Self(Value::Null)),
275            // Unknown type discriminator
276            _ => Err(std::io::Error::new(
277                std::io::ErrorKind::InvalidInput,
278                format!("Invalid Value representation: {}", order),
279            )),
280        }
281    }
282}
283
284impl BorshDeserialize for ValueWrapper {
285    #[inline]
286    fn deserialize_reader<R: Read>(reader: &mut R) -> std::io::Result<Self> {
287        // Start deserialization with depth 0
288        Self::deserialize_reader_with_depth(reader, 0)
289    }
290}
291
292#[cfg(test)]
293mod tests {
294    use super::*;
295    use std::io::Cursor;
296
297    // Basic serialization round-trip: string values
298    #[test]
299    fn test_value_wrapper_string() {
300        let value = ValueWrapper(Value::String("test".to_owned()));
301        let vec = borsh::to_vec(&value).unwrap();
302        let value2: ValueWrapper =
303            BorshDeserialize::try_from_slice(&vec).unwrap();
304        assert_eq!(value, value2);
305    }
306
307    // Basic serialization round-trip: boolean values (true/false)
308    #[test]
309    fn test_value_wrapper_bool() {
310        let value = ValueWrapper(Value::Bool(true));
311        let vec = borsh::to_vec(&value).unwrap();
312        let value2: ValueWrapper =
313            BorshDeserialize::try_from_slice(&vec).unwrap();
314        assert_eq!(value, value2);
315
316        let value_false = ValueWrapper(Value::Bool(false));
317        let vec_false = borsh::to_vec(&value_false).unwrap();
318        let value2_false: ValueWrapper =
319            BorshDeserialize::try_from_slice(&vec_false).unwrap();
320        assert_eq!(value_false, value2_false);
321    }
322
323    // Basic serialization round-trip: f64 numbers
324    #[test]
325    fn test_value_wrapper_number_f64() {
326        let value =
327            ValueWrapper(Value::Number(Number::from_f64(3.14).unwrap()));
328        let vec = borsh::to_vec(&value).unwrap();
329        let value2: ValueWrapper =
330            BorshDeserialize::try_from_slice(&vec).unwrap();
331        assert_eq!(value, value2);
332    }
333
334    // Basic serialization round-trip: i64 numbers (negative values)
335    #[test]
336    fn test_value_wrapper_number_i64() {
337        let value = ValueWrapper(Value::Number(Number::from(-42i64)));
338        let vec = borsh::to_vec(&value).unwrap();
339        let value2: ValueWrapper =
340            BorshDeserialize::try_from_slice(&vec).unwrap();
341        assert_eq!(value, value2);
342    }
343
344    // Basic serialization round-trip: u64 numbers (positive values)
345    #[test]
346    fn test_value_wrapper_number_u64() {
347        let value = ValueWrapper(Value::Number(Number::from(12345u64)));
348        let vec = borsh::to_vec(&value).unwrap();
349        let value2: ValueWrapper =
350            BorshDeserialize::try_from_slice(&vec).unwrap();
351        assert_eq!(value, value2);
352    }
353
354    // Basic serialization round-trip: null values
355    #[test]
356    fn test_value_wrapper_null() {
357        let value = ValueWrapper(Value::Null);
358        let vec = borsh::to_vec(&value).unwrap();
359        let value2: ValueWrapper =
360            BorshDeserialize::try_from_slice(&vec).unwrap();
361        assert_eq!(value, value2);
362    }
363
364    // Arrays with mixed types serialize correctly
365    #[test]
366    fn test_value_wrapper_array() {
367        let value = ValueWrapper(Value::Array(vec![
368            Value::Bool(true),
369            Value::String("test".to_owned()),
370            Value::Number(Number::from(42)),
371            Value::Null,
372        ]));
373        let vec = borsh::to_vec(&value).unwrap();
374        let value2: ValueWrapper =
375            BorshDeserialize::try_from_slice(&vec).unwrap();
376        assert_eq!(value, value2);
377    }
378
379    // Empty arrays are handled correctly
380    #[test]
381    fn test_value_wrapper_empty_array() {
382        let value = ValueWrapper(Value::Array(vec![]));
383        let vec = borsh::to_vec(&value).unwrap();
384        let value2: ValueWrapper =
385            BorshDeserialize::try_from_slice(&vec).unwrap();
386        assert_eq!(value, value2);
387    }
388
389    // Objects with string keys and mixed value types
390    #[test]
391    fn test_value_wrapper_object() {
392        let mut map = Map::new();
393        map.insert("name".to_string(), Value::String("Alice".to_owned()));
394        map.insert("age".to_string(), Value::Number(Number::from(30)));
395        map.insert("active".to_string(), Value::Bool(true));
396
397        let value = ValueWrapper(Value::Object(map));
398        let vec = borsh::to_vec(&value).unwrap();
399        let value2: ValueWrapper =
400            BorshDeserialize::try_from_slice(&vec).unwrap();
401        assert_eq!(value, value2);
402    }
403
404    // Empty objects are handled correctly
405    #[test]
406    fn test_value_wrapper_empty_object() {
407        let value = ValueWrapper(Value::Object(Map::new()));
408        let vec = borsh::to_vec(&value).unwrap();
409        let value2: ValueWrapper =
410            BorshDeserialize::try_from_slice(&vec).unwrap();
411        assert_eq!(value, value2);
412    }
413
414    // Nested structures (objects within objects, arrays within objects)
415    #[test]
416    fn test_value_wrapper_nested_structure() {
417        let mut inner_map = Map::new();
418        inner_map.insert("x".to_string(), Value::Number(Number::from(1)));
419        inner_map.insert("y".to_string(), Value::Number(Number::from(2)));
420
421        let mut outer_map = Map::new();
422        outer_map.insert("point".to_string(), Value::Object(inner_map));
423        outer_map.insert(
424            "values".to_string(),
425            Value::Array(vec![
426                Value::Number(Number::from(1)),
427                Value::Number(Number::from(2)),
428                Value::Number(Number::from(3)),
429            ]),
430        );
431
432        let value = ValueWrapper(Value::Object(outer_map));
433        let vec = borsh::to_vec(&value).unwrap();
434        let value2: ValueWrapper =
435            BorshDeserialize::try_from_slice(&vec).unwrap();
436        assert_eq!(value, value2);
437    }
438
439    // Accepts structures at max recursion depth (128 levels)
440    #[test]
441    fn test_value_wrapper_max_recursion_depth() {
442        let mut value = Value::Null;
443        for _ in 0..MAX_RECURSION_DEPTH {
444            value = Value::Array(vec![value]);
445        }
446
447        let wrapper = ValueWrapper(value);
448        let vec = borsh::to_vec(&wrapper).unwrap();
449
450        let result: Result<ValueWrapper, _> =
451            BorshDeserialize::try_from_slice(&vec);
452        assert!(result.is_ok());
453    }
454
455    // Rejects structures exceeding max recursion depth (prevents stack overflow)
456    #[test]
457    fn test_value_wrapper_exceeds_recursion_depth() {
458        let mut value = Value::Null;
459        for _ in 0..=MAX_RECURSION_DEPTH {
460            value = Value::Array(vec![value]);
461        }
462
463        let wrapper = ValueWrapper(value);
464        let vec = borsh::to_vec(&wrapper).unwrap();
465
466        let result: Result<ValueWrapper, _> =
467            BorshDeserialize::try_from_slice(&vec);
468        assert!(result.is_err());
469        assert!(
470            result
471                .unwrap_err()
472                .to_string()
473                .contains("Recursion depth limit exceeded")
474        );
475    }
476
477    // Accepts arrays at max collection size (100,000 elements)
478    #[test]
479    fn test_value_wrapper_large_array() {
480        let large_array = vec![Value::Null; MAX_COLLECTION_SIZE as usize];
481        let value = ValueWrapper(Value::Array(large_array));
482        let vec = borsh::to_vec(&value).unwrap();
483        let value2: ValueWrapper =
484            BorshDeserialize::try_from_slice(&vec).unwrap();
485        assert_eq!(value, value2);
486    }
487
488    // Rejects arrays exceeding max size (prevents memory exhaustion)
489    #[test]
490    fn test_value_wrapper_array_size_overflow() {
491        let mut bytes = vec![3u8]; // Type tag for Array
492        let oversized_len = MAX_COLLECTION_SIZE + 1;
493        bytes.extend_from_slice(&oversized_len.to_le_bytes());
494
495        let result: Result<ValueWrapper, _> =
496            BorshDeserialize::try_from_slice(&bytes);
497        assert!(result.is_err());
498        assert!(
499            result
500                .unwrap_err()
501                .to_string()
502                .contains("Array size too large")
503        );
504    }
505
506    // Rejects objects exceeding max size (prevents memory exhaustion)
507    #[test]
508    fn test_value_wrapper_object_size_overflow() {
509        let mut bytes = vec![4u8]; // Type tag for Object
510        let oversized_len = MAX_COLLECTION_SIZE + 1;
511        bytes.extend_from_slice(&oversized_len.to_le_bytes());
512
513        let result: Result<ValueWrapper, _> =
514            BorshDeserialize::try_from_slice(&bytes);
515        assert!(result.is_err());
516        assert!(
517            result
518                .unwrap_err()
519                .to_string()
520                .contains("Object size too large")
521        );
522    }
523
524    // Rejects unknown type discriminators (valid: 0-5)
525    #[test]
526    fn test_value_wrapper_invalid_type_tag() {
527        let bytes = vec![6u8];
528
529        let result: Result<ValueWrapper, _> =
530            BorshDeserialize::try_from_slice(&bytes);
531        assert!(result.is_err());
532        assert!(
533            result
534                .unwrap_err()
535                .to_string()
536                .contains("Invalid Value representation")
537        );
538    }
539
540    // Rejects invalid number sub-types (valid: 0=f64, 1=i64, 2=u64)
541    #[test]
542    fn test_value_wrapper_invalid_number_type() {
543        let bytes = vec![1u8, 3u8];
544
545        let result: Result<ValueWrapper, _> =
546            BorshDeserialize::try_from_slice(&bytes);
547        assert!(result.is_err());
548        assert!(
549            result
550                .unwrap_err()
551                .to_string()
552                .contains("Invalid Number representation")
553        );
554    }
555
556    // Unicode strings (multi-byte characters, emojis) are handled correctly
557    #[test]
558    fn test_value_wrapper_unicode_strings() {
559        let value = ValueWrapper(Value::String("Hello δΈ–η•Œ 🌍".to_owned()));
560        let vec = borsh::to_vec(&value).unwrap();
561        let value2: ValueWrapper =
562            BorshDeserialize::try_from_slice(&vec).unwrap();
563        assert_eq!(value, value2);
564    }
565
566    // Empty strings are valid
567    #[test]
568    fn test_value_wrapper_empty_string() {
569        let value = ValueWrapper(Value::String(String::new()));
570        let vec = borsh::to_vec(&value).unwrap();
571        let value2: ValueWrapper =
572            BorshDeserialize::try_from_slice(&vec).unwrap();
573        assert_eq!(value, value2);
574    }
575
576    // Special float values: +0.0 and -0.0 are valid (but NaN/Infinity are not)
577    #[test]
578    fn test_value_wrapper_special_floats() {
579        let value = ValueWrapper(Value::Number(Number::from_f64(0.0).unwrap()));
580        let vec = borsh::to_vec(&value).unwrap();
581        let value2: ValueWrapper =
582            BorshDeserialize::try_from_slice(&vec).unwrap();
583        assert_eq!(value, value2);
584
585        let value =
586            ValueWrapper(Value::Number(Number::from_f64(-0.0).unwrap()));
587        let vec = borsh::to_vec(&value).unwrap();
588        let value2: ValueWrapper =
589            BorshDeserialize::try_from_slice(&vec).unwrap();
590        assert_eq!(value, value2);
591    }
592
593    // Clone trait works correctly
594    #[test]
595    fn test_value_wrapper_clone() {
596        let value = ValueWrapper(Value::String("test".to_owned()));
597        let cloned = value.clone();
598        assert_eq!(value, cloned);
599    }
600
601    // Debug trait produces readable output
602    #[test]
603    fn test_value_wrapper_debug() {
604        let value = ValueWrapper(Value::String("test".to_owned()));
605        let debug_str = format!("{:?}", value);
606        assert!(debug_str.contains("test"));
607    }
608
609    // Deref trait allows direct access to Value methods
610    #[test]
611    fn test_value_wrapper_as_str() {
612        let value = ValueWrapper(Value::String("hello".to_owned()));
613        assert_eq!(value.as_str(), Some("hello"));
614
615        let non_string = ValueWrapper(Value::Number(Number::from(42)));
616        assert_eq!(non_string.as_str(), None);
617    }
618
619    // Object key access via Deref (get method)
620    #[test]
621    fn test_value_wrapper_get() {
622        let mut map = Map::new();
623        map.insert("name".to_string(), Value::String("Alice".to_owned()));
624        map.insert("age".to_string(), Value::Number(Number::from(30)));
625
626        let value = ValueWrapper(Value::Object(map));
627        assert_eq!(value.get("name"), Some(&Value::String("Alice".to_owned())));
628        assert_eq!(value.get("age"), Some(&Value::Number(Number::from(30))));
629        assert_eq!(value.get("missing"), None);
630
631        let non_object =
632            ValueWrapper(Value::String("not an object".to_owned()));
633        assert_eq!(non_object.get("key"), None);
634    }
635
636    // Deref allows calling Value type-checking methods
637    #[test]
638    fn test_value_wrapper_deref() {
639        let value = ValueWrapper(Value::String("test".to_owned()));
640        assert!(value.is_string());
641        assert!(!value.is_number());
642
643        let number = ValueWrapper(Value::Number(Number::from(42)));
644        assert!(number.is_number());
645        assert!(!number.is_string());
646    }
647
648    // Default produces Null value
649    #[test]
650    fn test_value_wrapper_default() {
651        let value = ValueWrapper::default();
652        assert_eq!(value.0, Value::Null);
653        assert!(value.is_null());
654    }
655
656    // Hash trait allows use in HashMap/HashSet
657    #[test]
658    fn test_value_wrapper_hash() {
659        use std::collections::HashMap;
660
661        let wrapper1 = ValueWrapper(Value::String("key1".to_owned()));
662        let wrapper2 = ValueWrapper(Value::String("key2".to_owned()));
663
664        let mut map = HashMap::new();
665        map.insert(wrapper1.clone(), "value1");
666        map.insert(wrapper2.clone(), "value2");
667
668        assert_eq!(map.get(&wrapper1), Some(&"value1"));
669        assert_eq!(map.get(&wrapper2), Some(&"value2"));
670    }
671
672    // Helper: deserialize from raw bytes
673    fn deser(bytes: Vec<u8>) -> std::io::Result<ValueWrapper> {
674        let mut c = Cursor::new(bytes);
675        ValueWrapper::deserialize_reader(&mut c)
676    }
677
678    // Helper: push single byte (type discriminators)
679    fn push_u8(buf: &mut Vec<u8>, v: u8) {
680        buf.push(v);
681    }
682
683    // Helper: push u32 in little-endian (collection lengths)
684    fn push_u32(buf: &mut Vec<u8>, v: u32) {
685        buf.extend_from_slice(&v.to_le_bytes());
686    }
687
688    // Helper: push i64 in little-endian (signed integers)
689    fn push_i64(buf: &mut Vec<u8>, v: i64) {
690        buf.extend_from_slice(&v.to_le_bytes());
691    }
692
693    // Helper: push u64 in little-endian (unsigned integers)
694    fn push_u64(buf: &mut Vec<u8>, v: u64) {
695        buf.extend_from_slice(&v.to_le_bytes());
696    }
697
698    // Helper: push f64 in little-endian (floating point numbers)
699    fn push_f64(buf: &mut Vec<u8>, v: f64) {
700        buf.extend_from_slice(&v.to_le_bytes());
701    }
702
703    // Helper: push Borsh-encoded string (u32 length + UTF-8 bytes)
704    fn push_borsh_string(buf: &mut Vec<u8>, s: &str) {
705        let b = s.as_bytes();
706        push_u32(buf, b.len() as u32);
707        buf.extend_from_slice(b);
708    }
709
710    // Rejects invalid type discriminator (255 is not in 0-5 range)
711    #[test]
712    fn rejects_unknown_discriminator() {
713        let bytes = vec![255u8];
714        assert!(deser(bytes).is_err());
715    }
716
717    // Rejects invalid number sub-type (99 is not in 0-2 range)
718    #[test]
719    fn rejects_number_unknown_internal_order() {
720        let mut bytes = Vec::new();
721        push_u8(&mut bytes, 1); // Type: Number
722        push_u8(&mut bytes, 99); // invalid sub-type
723        assert!(deser(bytes).is_err());
724    }
725
726    // Rejects NaN values (not representable in JSON)
727    #[test]
728    fn rejects_nan_f64_number() {
729        let mut bytes = Vec::new();
730        push_u8(&mut bytes, 1); // Type: Number
731        push_u8(&mut bytes, 0); // Sub-type: f64
732        push_f64(&mut bytes, f64::NAN);
733        assert!(deser(bytes).is_err());
734    }
735
736    // Rejects Infinity values (not representable in JSON)
737    #[test]
738    fn rejects_infinite_f64_number() {
739        let mut bytes = Vec::new();
740        push_u8(&mut bytes, 1); // Type: Number
741        push_u8(&mut bytes, 0); // Sub-type: f64
742        push_f64(&mut bytes, f64::INFINITY);
743        assert!(deser(bytes).is_err());
744    }
745
746    // Rejects array length header exceeding MAX_COLLECTION_SIZE
747    #[test]
748    fn rejects_array_too_large() {
749        let mut bytes = Vec::new();
750        push_u8(&mut bytes, 3); // Type: Array
751        let len = (MAX_COLLECTION_SIZE as u32) + 1;
752        push_u32(&mut bytes, len);
753        assert!(deser(bytes).is_err());
754    }
755
756    // Rejects object length header exceeding MAX_COLLECTION_SIZE
757    #[test]
758    fn rejects_object_too_large() {
759        let mut bytes = Vec::new();
760        push_u8(&mut bytes, 4); // Type: Object
761        let len = (MAX_COLLECTION_SIZE as u32) + 1;
762        push_u32(&mut bytes, len);
763        assert!(deser(bytes).is_err());
764    }
765
766    // Rejects deeply nested arrays exceeding recursion limit
767    #[test]
768    fn rejects_recursion_depth_exceeded_nested_arrays() {
769        let mut bytes = Vec::new();
770
771        let levels = (MAX_RECURSION_DEPTH as usize) + 2;
772        for _ in 0..levels {
773            push_u8(&mut bytes, 3); // Array
774            push_u32(&mut bytes, 1); // len=1
775        }
776        push_u8(&mut bytes, 5); // Null
777
778        assert!(deser(bytes).is_err());
779    }
780
781    // Rejects invalid UTF-8 byte sequences in strings
782    #[test]
783    fn rejects_invalid_utf8_string() {
784        let mut bytes = Vec::new();
785        push_u8(&mut bytes, 2); // Type: String
786        push_u32(&mut bytes, 1); // length=1
787        bytes.push(0xFF); // invalid UTF-8 byte
788
789        assert!(deser(bytes).is_err());
790    }
791
792    // Rejects incomplete f64 value (missing 8 bytes)
793    #[test]
794    fn rejects_truncated_payload_mid_value() {
795        let mut bytes = Vec::new();
796        push_u8(&mut bytes, 1); // Number
797        push_u8(&mut bytes, 0); // f64
798        // missing 8 bytes for f64 value
799        assert!(deser(bytes).is_err());
800    }
801
802    // Rejects object with incomplete key-value pair (truncated value)
803    #[test]
804    fn rejects_object_with_truncated_kv_pair() {
805        let mut bytes = Vec::new();
806        push_u8(&mut bytes, 4); // Object
807        push_u32(&mut bytes, 1); // 1 pair
808
809        push_borsh_string(&mut bytes, "k");
810
811        push_u8(&mut bytes, 2); // String
812        push_u32(&mut bytes, 10); // claims length=10
813        // missing actual string bytes
814
815        assert!(deser(bytes).is_err());
816    }
817
818    // Rejects incomplete i64 value (only 3 bytes instead of 8)
819    #[test]
820    fn rejects_number_i64_ok_but_truncated() {
821        let mut bytes = Vec::new();
822        push_u8(&mut bytes, 1); // Number
823        push_u8(&mut bytes, 1); // i64
824
825        bytes.extend_from_slice(&[1, 2, 3]); // only 3 bytes
826        assert!(deser(bytes).is_err());
827    }
828
829    // Tests push_i64: serializes negative i64 correctly
830    #[test]
831    fn accepts_i64_number_via_push_i64() {
832        let mut bytes = Vec::new();
833        push_u8(&mut bytes, 1); // Type: Number
834        push_u8(&mut bytes, 1); // Sub-type: i64
835        push_i64(&mut bytes, -123456789);
836
837        let result = deser(bytes).expect("should deserialize i64");
838        assert_eq!(result.0, Value::Number(Number::from(-123456789i64)));
839    }
840
841    // Tests push_i64: handles boundary values (MIN/MAX)
842    #[test]
843    fn accepts_i64_min_max_values() {
844        let mut bytes_min = Vec::new();
845        push_u8(&mut bytes_min, 1); // Type: Number
846        push_u8(&mut bytes_min, 1); // Sub-type: i64
847        push_i64(&mut bytes_min, i64::MIN);
848
849        let result_min = deser(bytes_min).expect("should deserialize i64::MIN");
850        assert_eq!(result_min.0, Value::Number(Number::from(i64::MIN)));
851
852        let mut bytes_max = Vec::new();
853        push_u8(&mut bytes_max, 1); // Type: Number
854        push_u8(&mut bytes_max, 1); // Sub-type: i64
855        push_i64(&mut bytes_max, i64::MAX);
856
857        let result_max = deser(bytes_max).expect("should deserialize i64::MAX");
858        assert_eq!(result_max.0, Value::Number(Number::from(i64::MAX)));
859    }
860
861    // Tests push_i64: handles zero, positive, and negative values
862    #[test]
863    fn accepts_i64_zero_positive_negative() {
864        let mut bytes_zero = Vec::new();
865        push_u8(&mut bytes_zero, 1);
866        push_u8(&mut bytes_zero, 1);
867        push_i64(&mut bytes_zero, 0);
868        let result_zero = deser(bytes_zero).expect("should deserialize 0");
869        assert_eq!(result_zero.0, Value::Number(Number::from(0i64)));
870
871        let mut bytes_pos = Vec::new();
872        push_u8(&mut bytes_pos, 1);
873        push_u8(&mut bytes_pos, 1);
874        push_i64(&mut bytes_pos, 42);
875        let result_pos = deser(bytes_pos).expect("should deserialize positive");
876        assert_eq!(result_pos.0, Value::Number(Number::from(42i64)));
877
878        let mut bytes_neg = Vec::new();
879        push_u8(&mut bytes_neg, 1);
880        push_u8(&mut bytes_neg, 1);
881        push_i64(&mut bytes_neg, -42);
882        let result_neg = deser(bytes_neg).expect("should deserialize negative");
883        assert_eq!(result_neg.0, Value::Number(Number::from(-42i64)));
884    }
885
886    // Tests push_u64: serializes unsigned integers correctly
887    #[test]
888    fn accepts_u64_number_via_push_u64() {
889        let mut bytes = Vec::new();
890        push_u8(&mut bytes, 1); // Type: Number
891        push_u8(&mut bytes, 2); // Sub-type: u64
892        push_u64(&mut bytes, 987654321);
893
894        let result = deser(bytes).expect("should deserialize u64");
895        assert_eq!(result.0, Value::Number(Number::from(987654321u64)));
896    }
897
898    // Tests push_u64: handles boundary values (MIN=0, MAX)
899    #[test]
900    fn accepts_u64_min_max_values() {
901        let mut bytes_min = Vec::new();
902        push_u8(&mut bytes_min, 1); // Type: Number
903        push_u8(&mut bytes_min, 2); // Sub-type: u64
904        push_u64(&mut bytes_min, u64::MIN);
905
906        let result_min = deser(bytes_min).expect("should deserialize u64::MIN");
907        assert_eq!(result_min.0, Value::Number(Number::from(u64::MIN)));
908
909        let mut bytes_max = Vec::new();
910        push_u8(&mut bytes_max, 1); // Type: Number
911        push_u8(&mut bytes_max, 2); // Sub-type: u64
912        push_u64(&mut bytes_max, u64::MAX);
913
914        let result_max = deser(bytes_max).expect("should deserialize u64::MAX");
915        assert_eq!(result_max.0, Value::Number(Number::from(u64::MAX)));
916    }
917
918    // Tests push_f64: serializes floating point numbers correctly
919    #[test]
920    fn accepts_f64_number_via_push_f64() {
921        let mut bytes = Vec::new();
922        push_u8(&mut bytes, 1); // Type: Number
923        push_u8(&mut bytes, 0); // Sub-type: f64
924        push_f64(&mut bytes, 3.14159);
925
926        let result = deser(bytes).expect("should deserialize f64");
927        assert_eq!(result.0, Value::Number(Number::from_f64(3.14159).unwrap()));
928    }
929
930    // Tests push_f64: handles special values (+0, -0, very large/small)
931    #[test]
932    fn accepts_f64_special_values() {
933        let mut bytes_pos_zero = Vec::new();
934        push_u8(&mut bytes_pos_zero, 1);
935        push_u8(&mut bytes_pos_zero, 0);
936        push_f64(&mut bytes_pos_zero, 0.0);
937        let result = deser(bytes_pos_zero).expect("should deserialize +0.0");
938        assert_eq!(result.0, Value::Number(Number::from_f64(0.0).unwrap()));
939
940        let mut bytes_neg_zero = Vec::new();
941        push_u8(&mut bytes_neg_zero, 1);
942        push_u8(&mut bytes_neg_zero, 0);
943        push_f64(&mut bytes_neg_zero, -0.0);
944        let result = deser(bytes_neg_zero).expect("should deserialize -0.0");
945        assert_eq!(result.0, Value::Number(Number::from_f64(-0.0).unwrap()));
946
947        let mut bytes_large = Vec::new();
948        push_u8(&mut bytes_large, 1);
949        push_u8(&mut bytes_large, 0);
950        push_f64(&mut bytes_large, 1.7976931348623157e308);
951        let result = deser(bytes_large).expect("should deserialize large f64");
952        assert!(result.0.is_number());
953
954        let mut bytes_small = Vec::new();
955        push_u8(&mut bytes_small, 1);
956        push_u8(&mut bytes_small, 0);
957        push_f64(&mut bytes_small, -2.2250738585072014e-308);
958        let result =
959            deser(bytes_small).expect("should deserialize small negative f64");
960        assert!(result.0.is_number());
961    }
962
963    // Duplicate object keys: last value wins (semantic note: not ideal but accepted)
964    #[test]
965    fn accepts_but_overwrites_duplicate_object_keys_semantic_issue() {
966        let mut bytes = Vec::new();
967        push_u8(&mut bytes, 4); // Object
968        push_u32(&mut bytes, 2); // 2 pairs
969
970        push_borsh_string(&mut bytes, "a");
971        push_u8(&mut bytes, 1); // Number
972        push_u8(&mut bytes, 2); // u64
973        push_u64(&mut bytes, 1);
974
975        push_borsh_string(&mut bytes, "a"); // duplicate key
976        push_u8(&mut bytes, 1); // Number
977        push_u8(&mut bytes, 2); // u64
978        push_u64(&mut bytes, 2);
979
980        let v = deser(bytes).expect("should deserialize");
981        match v.0 {
982            serde_json::Value::Object(map) => {
983                assert_eq!(
984                    map.get("a").unwrap(),
985                    &serde_json::Value::Number(serde_json::Number::from(2u64))
986                );
987            }
988            _ => panic!("expected object"),
989        }
990    }
991}