darkbio_crypto/cbor/
mod.rs

1// crypto-rs: cryptography primitives and wrappers
2// Copyright 2025 Dark Bio AG. All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7//! Tiny CBOR encoder and decoder.
8//!
9//! https://datatracker.ietf.org/doc/html/rfc8949
10//!
11//! This is an implementation of the CBOR spec with an extremely reduced type
12//! system, focusing on security rather than flexibility or completeness. The
13//! following types are supported:
14//! - Booleans:                bool
15//! - Null:                    Option<T>::None, cbor::Null
16//! - 64bit positive integers: u64
17//! - 64bit signed integers:   i64
18//! - UTF-8 text strings:      String, &str
19//! - Byte strings:            Vec<u8>, &[u8], [u8; N]
20//! - Arrays:                  (), (X,), (X,Y), ... tuples, or structs with #[cbor(array)]
21//! - Maps:                    structs with #[cbor(key = N)] fields
22
23pub use darkbio_crypto_cbor_derive::Cbor;
24
25use std::cmp::Ordering;
26
27// Supported CBOR major types
28const MAJOR_UINT: u8 = 0;
29const MAJOR_NINT: u8 = 1;
30const MAJOR_BYTES: u8 = 2;
31const MAJOR_TEXT: u8 = 3;
32const MAJOR_ARRAY: u8 = 4;
33const MAJOR_MAP: u8 = 5;
34const MAJOR_SIMPLE: u8 = 7;
35
36// Additional info values
37const INFO_UINT8: u8 = 24;
38const INFO_UINT16: u8 = 25;
39const INFO_UINT32: u8 = 26;
40const INFO_UINT64: u8 = 27;
41
42// Simple values (major type 7)
43const SIMPLE_FALSE: u8 = 20;
44const SIMPLE_TRUE: u8 = 21;
45const SIMPLE_NULL: u8 = 22;
46
47/// Error is the failures that can occur while encoding or decoding CBOR data.
48#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
49pub enum Error {
50    #[error("invalid major type: {0}, want {1}")]
51    InvalidMajorType(u8, u8),
52    #[error("invalid additional info: {0}")]
53    InvalidAdditionalInfo(u8),
54    #[error("unexpected end of data")]
55    UnexpectedEof,
56    #[error("non-canonical encoding")]
57    NonCanonical,
58    #[error("invalid UTF-8 in text string")]
59    InvalidUtf8,
60    #[error("unexpected trailing bytes")]
61    TrailingBytes,
62    #[error("unexpected item count: {0}, want {1}")]
63    UnexpectedItemCount(u64, usize),
64    #[error("unsupported type: {0}")]
65    UnsupportedType(u8),
66    #[error("{sign} integer overflow: {value} exceeds max {max}", sign = if *.0 { "negative" } else { "positive" }, value = .1, max = .2)]
67    IntegerOverflow(bool, u64, u64),
68    #[error("duplicate map key: {0}")]
69    DuplicateMapKey(i64),
70    #[error("invalid map key order: {0} must come before {1}")]
71    InvalidMapKeyOrder(i64, i64),
72    #[error("decode failed: {0}")]
73    DecodeFailed(String),
74}
75
76/// encode attempts to encode a generic Rust value to CBOR using the tiny, strict
77/// subset of types permitted by this package.
78pub fn encode<T: Encode>(value: T) -> Vec<u8> {
79    value.encode_cbor()
80}
81
82/// decode attempts to decode a CBOR blob into a generic Rust type using the tiny,
83/// strict subset of types permitted by this package.
84pub fn decode<T: Decode>(data: &[u8]) -> Result<T, Error> {
85    T::decode_cbor(data)
86}
87
88/// verify does a dry-run decoding to verify that only the tiny, strict subset of
89/// types permitted by this package were used.
90pub fn verify(data: &[u8]) -> Result<(), Error> {
91    let mut decoder = Decoder::new(data);
92    verify_object(&mut decoder)?;
93    decoder.finish()
94}
95
96// Encoder is the low level implementation of the CBOR encoder with only the
97// handful of desired types supported.
98pub struct Encoder {
99    buf: Vec<u8>,
100}
101
102impl Encoder {
103    // new creates a CBOR encoder with an underlying buffer, pre-allocated to
104    // 1KB (small enough not to be relevant, large enough to avoid tiny appends).
105    pub fn new() -> Self {
106        Self {
107            buf: Vec::with_capacity(1024),
108        }
109    }
110
111    // finish terminates encoding and retrieves the accumulated CBOR data.
112    pub fn finish(self) -> Vec<u8> {
113        self.buf
114    }
115
116    // extend appends raw bytes to the encoder buffer (for derive macros).
117    pub fn extend(&mut self, bytes: &[u8]) {
118        self.buf.extend_from_slice(bytes);
119    }
120
121    // encode_uint encodes a positive integer into its canonical shortest-form.
122    pub fn encode_uint(&mut self, value: u64) {
123        self.encode_length(MAJOR_UINT, value);
124    }
125
126    // encode_int encodes a signed integer into its canonical shortest-form.
127    pub fn encode_int(&mut self, value: i64) {
128        if value >= 0 {
129            self.encode_length(MAJOR_UINT, value as u64);
130        } else {
131            self.encode_length(MAJOR_NINT, (-1 - value) as u64);
132        }
133    }
134
135    // encode_bytes encodes an opaque byte string.
136    pub fn encode_bytes(&mut self, value: &[u8]) {
137        self.encode_length(MAJOR_BYTES, value.len() as u64);
138        self.buf.extend_from_slice(value);
139    }
140
141    // encode_text encodes a UTF-8 text string.
142    pub fn encode_text(&mut self, value: &str) {
143        self.encode_length(MAJOR_TEXT, value.len() as u64);
144        self.buf.extend_from_slice(value.as_bytes());
145    }
146
147    // encode_array_header encodes an array size.
148    pub fn encode_array_header(&mut self, len: usize) {
149        self.encode_length(MAJOR_ARRAY, len as u64);
150    }
151
152    // encode_empty_tuple special cases the empty tuple to encode as [].
153    pub fn encode_empty_tuple(&mut self) {
154        self.encode_array_header(0);
155    }
156
157    // encode_map_header encodes a map size.
158    pub fn encode_map_header(&mut self, len: usize) {
159        self.encode_length(MAJOR_MAP, len as u64);
160    }
161
162    // encode_bool encodes a CBOR boolean value.
163    pub fn encode_bool(&mut self, value: bool) {
164        self.buf
165            .push(MAJOR_SIMPLE << 5 | if value { SIMPLE_TRUE } else { SIMPLE_FALSE });
166    }
167
168    // encode_null encodes a CBOR null value.
169    pub fn encode_null(&mut self) {
170        self.buf.push(MAJOR_SIMPLE << 5 | SIMPLE_NULL);
171    }
172
173    // encodeLength encodes a major type with an unsigned integer, which defines
174    // the length for most types, or the value itself for integers.
175    fn encode_length(&mut self, major_type: u8, len: u64) {
176        if len < 24 {
177            self.buf.push(major_type << 5 | len as u8);
178        } else if len <= u8::MAX as u64 {
179            self.buf.push(major_type << 5 | INFO_UINT8);
180            self.buf.push(len as u8);
181        } else if len <= u16::MAX as u64 {
182            self.buf.push(major_type << 5 | INFO_UINT16);
183            self.buf.extend_from_slice(&(len as u16).to_be_bytes());
184        } else if len <= u32::MAX as u64 {
185            self.buf.push(major_type << 5 | INFO_UINT32);
186            self.buf.extend_from_slice(&(len as u32).to_be_bytes());
187        } else {
188            self.buf.push(major_type << 5 | INFO_UINT64);
189            self.buf.extend_from_slice(&len.to_be_bytes());
190        }
191    }
192}
193
194impl Default for Encoder {
195    fn default() -> Self {
196        Self::new()
197    }
198}
199
200// Decoder is the low level implementation of the CBOR decoder with only the
201// handful of desired types supported.
202#[derive(Clone)]
203pub struct Decoder<'a> {
204    data: &'a [u8],
205    pos: usize,
206}
207
208impl<'a> Decoder<'a> {
209    // new creates a decoder around a data blob.
210    pub fn new(data: &'a [u8]) -> Self {
211        Self { data, pos: 0 }
212    }
213
214    // finish terminates decoding and returns an error if trailing bytes remain.
215    pub fn finish(self) -> Result<(), Error> {
216        if self.pos != self.data.len() {
217            return Err(Error::TrailingBytes);
218        }
219        Ok(())
220    }
221
222    // decode_uint decodes a positive integer, enforcing minimal canonicalness.
223    pub fn decode_uint(&mut self) -> Result<u64, Error> {
224        let (major, value) = self.decode_header()?;
225        if major != MAJOR_UINT {
226            return Err(Error::InvalidMajorType(major, MAJOR_UINT));
227        }
228        Ok(value)
229    }
230
231    // decode_int decodes a signed integer (major type 0 or 1).
232    pub fn decode_int(&mut self) -> Result<i64, Error> {
233        let (major, value) = self.decode_header()?;
234        match major {
235            MAJOR_UINT => {
236                if value > i64::MAX as u64 {
237                    return Err(Error::IntegerOverflow(false, value, i64::MAX as u64));
238                }
239                Ok(value as i64)
240            }
241            MAJOR_NINT => {
242                if value > i64::MAX as u64 {
243                    return Err(Error::IntegerOverflow(true, value, i64::MAX as u64));
244                }
245                Ok(-1 - value as i64)
246            }
247            _ => Err(Error::InvalidMajorType(major, MAJOR_UINT)),
248        }
249    }
250
251    // decode_bytes decodes a byte string.
252    pub fn decode_bytes(&mut self) -> Result<Vec<u8>, Error> {
253        // Extract the field type and attached length
254        let (major, len) = self.decode_header()?;
255        if major != MAJOR_BYTES {
256            return Err(Error::InvalidMajorType(major, MAJOR_BYTES));
257        }
258        // Retrieve the blob and return as is
259        let bytes = self.read_bytes(len)?;
260        Ok(bytes.to_vec())
261    }
262
263    // decode_bytes_fixed decodes a byte string into a fixed-size array.
264    pub fn decode_bytes_fixed<const N: usize>(&mut self) -> Result<[u8; N], Error> {
265        // Extract the field type and attached length
266        let (major, len) = self.decode_header()?;
267        if major != MAJOR_BYTES {
268            return Err(Error::InvalidMajorType(major, MAJOR_BYTES));
269        }
270        // Check that the length matches the expected array size
271        if len as usize != N {
272            return Err(Error::UnexpectedItemCount(len, N));
273        }
274        // Retrieve the bytes and copy into the fixed-size array
275        let bytes = self.read_bytes(N as u64)?;
276        let mut array = [0u8; N];
277        array.copy_from_slice(bytes);
278        Ok(array)
279    }
280
281    // decode_text decodes a UTF-8 text string.
282    pub fn decode_text(&mut self) -> Result<String, Error> {
283        // Extract the field type and attached length
284        let (major, len) = self.decode_header()?;
285        if major != MAJOR_TEXT {
286            return Err(Error::InvalidMajorType(major, MAJOR_TEXT));
287        }
288        // Retrieve the blob and reinterpret as UTF-8
289        let bytes = self.read_bytes(len)?;
290        String::from_utf8(bytes.to_vec()).map_err(|_| Error::InvalidUtf8)
291    }
292
293    // decode_array_header decodes an array header, returning its length.
294    pub fn decode_array_header(&mut self) -> Result<u64, Error> {
295        // Extract the field type and attached length
296        let (major, len) = self.decode_header()?;
297        if major != MAJOR_ARRAY {
298            return Err(Error::InvalidMajorType(major, MAJOR_ARRAY));
299        }
300        Ok(len)
301    }
302
303    // decode_map_header decodes a map header, returning the number of key-value pairs.
304    pub fn decode_map_header(&mut self) -> Result<u64, Error> {
305        // Extract the field type and attached length
306        let (major, len) = self.decode_header()?;
307        if major != MAJOR_MAP {
308            return Err(Error::InvalidMajorType(major, MAJOR_MAP));
309        }
310        Ok(len)
311    }
312
313    // decode_bool decodes a CBOR boolean value.
314    pub fn decode_bool(&mut self) -> Result<bool, Error> {
315        if self.pos >= self.data.len() {
316            return Err(Error::UnexpectedEof);
317        }
318        let byte = self.data[self.pos];
319        match byte {
320            b if b == (MAJOR_SIMPLE << 5 | SIMPLE_FALSE) => {
321                self.pos += 1;
322                Ok(false)
323            }
324            b if b == (MAJOR_SIMPLE << 5 | SIMPLE_TRUE) => {
325                self.pos += 1;
326                Ok(true)
327            }
328            _ => Err(Error::InvalidMajorType(byte >> 5, MAJOR_SIMPLE)),
329        }
330    }
331
332    // decode_null decodes a CBOR null value.
333    pub fn decode_null(&mut self) -> Result<(), Error> {
334        if self.pos >= self.data.len() {
335            return Err(Error::UnexpectedEof);
336        }
337        let byte = self.data[self.pos];
338        if byte != (MAJOR_SIMPLE << 5 | SIMPLE_NULL) {
339            return Err(Error::InvalidMajorType(byte >> 5, MAJOR_SIMPLE));
340        }
341        self.pos += 1;
342        Ok(())
343    }
344
345    // peek_null checks if the next value is null without consuming it.
346    pub fn peek_null(&self) -> bool {
347        self.pos < self.data.len() && self.data[self.pos] == (MAJOR_SIMPLE << 5 | SIMPLE_NULL)
348    }
349
350    // decode_header extracts the major type for the next field and the integer
351    // value embedded as the additional info.
352    fn decode_header(&mut self) -> Result<(u8, u64), Error> {
353        // Ensure there's still data left in the buffer
354        if self.pos >= self.data.len() {
355            return Err(Error::UnexpectedEof);
356        }
357        // Extract the type byte and split it apart
358        let byte = self.data[self.pos];
359        self.pos += 1;
360
361        let major = byte >> 5;
362        let info = byte & 0x1f;
363
364        // Extract the integer embedded in the info
365        let value = match info {
366            0..=23 => Ok(info as u64),
367            INFO_UINT8 => {
368                let bytes = self.read_bytes(1)?;
369                Ok(bytes[0] as u64)
370            }
371            INFO_UINT16 => {
372                let bytes = self.read_bytes(2)?;
373                Ok(u16::from_be_bytes([bytes[0], bytes[1]]) as u64)
374            }
375            INFO_UINT32 => {
376                let bytes = self.read_bytes(4)?;
377                Ok(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as u64)
378            }
379            INFO_UINT64 => {
380                let bytes = self.read_bytes(8)?;
381                Ok(u64::from_be_bytes([
382                    bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
383                ]))
384            }
385            _ => Err(Error::InvalidAdditionalInfo(info)),
386        }?;
387
388        // Ensure it was canonical in the first place
389        if !match info {
390            0..=23 => value < 24,
391            INFO_UINT8 => value >= 24 && value <= u8::MAX as u64,
392            INFO_UINT16 => value > u8::MAX as u64 && value <= u16::MAX as u64,
393            INFO_UINT32 => value > u16::MAX as u64 && value <= u32::MAX as u64,
394            INFO_UINT64 => value > u32::MAX as u64,
395            _ => false,
396        } {
397            return Err(Error::NonCanonical);
398        }
399        Ok((major, value))
400    }
401
402    // read_bytes retrieves the next handful of bytes from the buffer.
403    fn read_bytes(&mut self, len: u64) -> Result<&'a [u8], Error> {
404        // Ensure there's still enough data left in the buffer
405        if len > usize::MAX as u64 {
406            return Err(Error::UnexpectedEof);
407        }
408        let len = len as usize;
409
410        match self.pos.checked_add(len) {
411            None => return Err(Error::UnexpectedEof),
412            Some(end) => {
413                if end > self.data.len() {
414                    return Err(Error::UnexpectedEof);
415                }
416            }
417        }
418        // Retrieve the byte and move the cursor forward
419        let bytes = &self.data[self.pos..self.pos + len];
420        self.pos += len;
421
422        Ok(bytes)
423    }
424}
425
426/// Encode is the interface needed to encode a type to CBOR.
427pub trait Encode {
428    // encode_cbor converts the type to CBOR.
429    fn encode_cbor(&self) -> Vec<u8>;
430}
431
432/// Decode is the interface needed to decode a type from CBOR.
433pub trait Decode: Sized {
434    // decode_cbor converts CBOR to the type.
435    fn decode_cbor(data: &[u8]) -> Result<Self, Error>;
436
437    // decode_cbor_notrail converts CBOR to the type, ignoring any trailing data.
438    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error>;
439}
440
441// Encoder and decoder implementation for booleans.
442impl Encode for bool {
443    fn encode_cbor(&self) -> Vec<u8> {
444        let mut encoder = Encoder::new();
445        encoder.encode_bool(*self);
446        encoder.finish()
447    }
448}
449
450impl Decode for bool {
451    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
452        let mut decoder = Decoder::new(data);
453        let value = decoder.decode_bool()?;
454        decoder.finish()?;
455        Ok(value)
456    }
457
458    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
459        decoder.decode_bool()
460    }
461}
462
463// Encoder and decoder implementation for positive integers.
464impl Encode for u64 {
465    fn encode_cbor(&self) -> Vec<u8> {
466        let mut encoder = Encoder::new();
467        encoder.encode_uint(*self);
468        encoder.finish()
469    }
470}
471
472impl Decode for u64 {
473    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
474        let mut decoder = Decoder::new(data);
475        let value = decoder.decode_uint()?;
476        decoder.finish()?;
477        Ok(value)
478    }
479
480    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
481        decoder.decode_uint()
482    }
483}
484
485// Encoder and decoder implementation for signed integers.
486impl Encode for i64 {
487    fn encode_cbor(&self) -> Vec<u8> {
488        let mut encoder = Encoder::new();
489        encoder.encode_int(*self);
490        encoder.finish()
491    }
492}
493
494impl Decode for i64 {
495    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
496        let mut decoder = Decoder::new(data);
497        let value = decoder.decode_int()?;
498        decoder.finish()?;
499        Ok(value)
500    }
501
502    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
503        decoder.decode_int()
504    }
505}
506
507// Encoder and decoder implementation for dynamic byte blobs.
508impl Encode for Vec<u8> {
509    fn encode_cbor(&self) -> Vec<u8> {
510        let mut encoder = Encoder::new();
511        encoder.encode_bytes(self);
512        encoder.finish()
513    }
514}
515
516impl Encode for &[u8] {
517    fn encode_cbor(&self) -> Vec<u8> {
518        let mut encoder = Encoder::new();
519        encoder.encode_bytes(self);
520        encoder.finish()
521    }
522}
523
524impl Decode for Vec<u8> {
525    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
526        let mut decoder = Decoder::new(data);
527        let value = decoder.decode_bytes()?;
528        decoder.finish()?;
529        Ok(value)
530    }
531
532    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
533        decoder.decode_bytes()
534    }
535}
536
537// Encoder and decoder implementation for fixed byte blobs.
538impl<const N: usize> Encode for [u8; N] {
539    fn encode_cbor(&self) -> Vec<u8> {
540        let mut encoder = Encoder::new();
541        encoder.encode_bytes(self);
542        encoder.finish()
543    }
544}
545
546impl<const N: usize> Decode for [u8; N] {
547    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
548        let mut decoder = Decoder::new(data);
549        let value = decoder.decode_bytes_fixed::<N>()?;
550        decoder.finish()?;
551        Ok(value)
552    }
553
554    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
555        decoder.decode_bytes_fixed::<N>()
556    }
557}
558
559// Encoder and decoder implementation for UTF-8 strings.
560impl Encode for String {
561    fn encode_cbor(&self) -> Vec<u8> {
562        let mut encoder = Encoder::new();
563        encoder.encode_text(self);
564        encoder.finish()
565    }
566}
567
568impl Encode for &str {
569    fn encode_cbor(&self) -> Vec<u8> {
570        let mut encoder = Encoder::new();
571        encoder.encode_text(self);
572        encoder.finish()
573    }
574}
575
576impl Decode for String {
577    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
578        let mut decoder = Decoder::new(data);
579        let value = decoder.decode_text()?;
580        decoder.finish()?;
581        Ok(value)
582    }
583
584    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
585        decoder.decode_text()
586    }
587}
588
589// Encoder and decoder implementation for the empty tuple.
590impl Encode for () {
591    fn encode_cbor(&self) -> Vec<u8> {
592        let mut encoder = Encoder::new();
593        encoder.encode_empty_tuple();
594        encoder.finish()
595    }
596}
597
598impl Decode for () {
599    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
600        let mut decoder = Decoder::new(data);
601        let len = decoder.decode_array_header()?;
602        if len != 0 {
603            return Err(Error::UnexpectedItemCount(len, 0));
604        }
605        decoder.finish()?;
606        Ok(())
607    }
608
609    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
610        let len = decoder.decode_array_header()?;
611        if len != 0 {
612            return Err(Error::UnexpectedItemCount(len, 0));
613        }
614        Ok(())
615    }
616}
617
618// Encoder and decoder implementation for real tuples.
619macro_rules! impl_tuple {
620    ($($t:ident),+) => {
621        impl<$($t: Encode),+> Encode for ($($t,)+) {
622            fn encode_cbor(&self) -> Vec<u8> {
623                let mut encoder = Encoder::new();
624
625                // Encode the length of the tuple
626                let len = args!($($t),+);
627                encoder.encode_array_header(len);
628
629                // Encode all the tuple elements individually
630                let ($($t,)+) = self;
631                $(encoder.buf.extend_from_slice(&$t.encode_cbor());)+
632                encoder.finish()
633            }
634        }
635
636        impl<$($t: Decode),+> Decode for ($($t,)+) {
637            fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
638                let mut decoder = Decoder::new(data);
639
640                // Decode the length of the tuple
641                let len = decoder.decode_array_header()?;
642                let exp = args!($($t),+);
643                if len != exp as u64 {
644                    return Err(Error::UnexpectedItemCount(len, exp));
645                }
646                // Decode all the tuple elements individually
647                $(
648                    let $t = $t::decode_cbor_notrail(&mut decoder)?;
649                )+
650                decoder.finish()?;
651                Ok(($($t,)+))
652            }
653
654            fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
655                // Decode the length of the tuple
656                let len = decoder.decode_array_header()?;
657                let exp = args!($($t),+);
658                if len != exp as u64 {
659                    return Err(Error::UnexpectedItemCount(len, exp));
660                }
661                // Decode all the tuple elements individually
662                $(
663                    let $t = $t::decode_cbor_notrail(decoder)?;
664                )+
665                Ok(($($t,)+))
666            }
667        }
668    };
669}
670
671macro_rules! args {
672    ($($t:ident),+) => { args!(@count $($t),+) };
673    (@count $t1:ident) => { 1 };
674    (@count $t1:ident, $($t:ident),+) => { 1 + args!(@count $($t),+) };
675}
676
677#[allow(non_snake_case)]
678mod tuple_impls {
679    use super::*;
680
681    impl_tuple!(T1);
682    impl_tuple!(T1, T2);
683    impl_tuple!(T1, T2, T3);
684    impl_tuple!(T1, T2, T3, T4);
685    impl_tuple!(T1, T2, T3, T4, T5);
686    impl_tuple!(T1, T2, T3, T4, T5, T6);
687    impl_tuple!(T1, T2, T3, T4, T5, T6, T7);
688    impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
689}
690
691// Blanket encoder for references.
692impl<T: Encode> Encode for &T {
693    fn encode_cbor(&self) -> Vec<u8> {
694        (*self).encode_cbor()
695    }
696}
697
698/// Constant for convenient CBOR null encoding (use `cbor::NULL`).
699pub const NULL: Null = Null;
700
701/// Null is a unit type that encodes/decodes as CBOR null (0xf6).
702#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
703pub struct Null;
704
705impl Encode for Null {
706    fn encode_cbor(&self) -> Vec<u8> {
707        let mut encoder = Encoder::new();
708        encoder.encode_null();
709        encoder.finish()
710    }
711}
712
713impl Decode for Null {
714    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
715        let mut decoder = Decoder::new(data);
716        let result = Self::decode_cbor_notrail(&mut decoder)?;
717        decoder.finish()?;
718        Ok(result)
719    }
720
721    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
722        decoder.decode_null()?;
723        Ok(Null)
724    }
725}
726
727// Encoder and decoder implementation for Option<T> (None encodes as null).
728impl<T: Encode> Encode for Option<T> {
729    fn encode_cbor(&self) -> Vec<u8> {
730        match self {
731            Some(value) => value.encode_cbor(),
732            None => {
733                let mut encoder = Encoder::new();
734                encoder.encode_null();
735                encoder.finish()
736            }
737        }
738    }
739}
740
741impl<T: Decode> Decode for Option<T> {
742    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
743        let mut decoder = Decoder::new(data);
744        let result = Self::decode_cbor_notrail(&mut decoder)?;
745        decoder.finish()?;
746        Ok(result)
747    }
748
749    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
750        if decoder.peek_null() {
751            decoder.decode_null()?;
752            Ok(None)
753        } else {
754            Ok(Some(T::decode_cbor_notrail(decoder)?))
755        }
756    }
757}
758
759/// Raw is a placeholder type to allow only partially parsing CBOR objects when
760/// some part might depend on another (e.g. version tag, method in an RPC, etc).
761#[derive(Clone, Debug, PartialEq, Eq)]
762pub struct Raw(pub Vec<u8>);
763
764impl std::ops::Deref for Raw {
765    type Target = Vec<u8>;
766
767    fn deref(&self) -> &Self::Target {
768        &self.0
769    }
770}
771
772impl std::ops::DerefMut for Raw {
773    fn deref_mut(&mut self) -> &mut Self::Target {
774        &mut self.0
775    }
776}
777
778impl Encode for Raw {
779    fn encode_cbor(&self) -> Vec<u8> {
780        self.0.clone()
781    }
782}
783
784impl Decode for Raw {
785    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
786        let mut decoder = Decoder::new(data);
787        let result = Self::decode_cbor_notrail(&mut decoder)?;
788        decoder.finish()?;
789        Ok(result)
790    }
791
792    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
793        let start = decoder.pos;
794        skip_object(decoder)?;
795        let end = decoder.pos;
796        Ok(Raw(decoder.data[start..end].to_vec()))
797    }
798}
799
800// skip_object advances the decoder past one CBOR item without validation. It
801// does do some minimal type checks as walking the CBOR does require walking
802// all the inner fields too.
803fn skip_object(decoder: &mut Decoder<'_>) -> Result<(), Error> {
804    let (major, value) = decoder.decode_header()?;
805    match major {
806        MAJOR_UINT | MAJOR_NINT => Ok(()),
807        MAJOR_BYTES | MAJOR_TEXT => {
808            decoder.read_bytes(value)?;
809            Ok(())
810        }
811        MAJOR_ARRAY => {
812            for _ in 0..value {
813                skip_object(decoder)?;
814            }
815            Ok(())
816        }
817        MAJOR_MAP => {
818            for _ in 0..value {
819                skip_object(decoder)?;
820                skip_object(decoder)?;
821            }
822            Ok(())
823        }
824        MAJOR_SIMPLE
825            if value == SIMPLE_FALSE as u64
826                || value == SIMPLE_TRUE as u64
827                || value == SIMPLE_NULL as u64 =>
828        {
829            Ok(())
830        }
831        _ => Err(Error::UnsupportedType(major)),
832    }
833}
834
835// map_key_cmp compares two i64 keys according to CBOR deterministic encoding
836// order (RFC 8949 Section 4.2.1): bytewise lexicographic order of encoded keys.
837//
838// For integers this means: positive integers (0, 1, 2, ...) come before negative
839// integers (-1, -2, -3, ...), and within each category they're ordered by their
840// encoded length first, then by value.
841fn map_key_cmp(a: i64, b: i64) -> Ordering {
842    fn encode_key(k: i64) -> Vec<u8> {
843        let mut enc = Encoder::new();
844        enc.encode_int(k);
845        enc.finish()
846    }
847    encode_key(a).cmp(&encode_key(b))
848}
849
850// verify_object is an internal function to verify a single CBOR item without
851// full deserialization.
852fn verify_object(decoder: &mut Decoder) -> Result<(), Error> {
853    let (major, value) = decoder.decode_header()?;
854
855    match major {
856        MAJOR_UINT | MAJOR_NINT => {
857            // Integers are valid (canonicalness was already verified in the
858            // header decoding). Overflow checking is done at decode time based
859            // on the target type (u64 vs i64).
860            Ok(())
861        }
862        MAJOR_BYTES => {
863            // Opaque bytes are always valid, skip over
864            _ = decoder.read_bytes(value)?;
865            Ok(())
866        }
867        MAJOR_TEXT => {
868            // Verify that the text is indeed UTF-8
869            let bytes = decoder.read_bytes(value)?;
870            std::str::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
871            Ok(())
872        }
873        MAJOR_ARRAY => {
874            // Recursively verify each array element
875            let len = value as usize;
876            for _ in 0..len {
877                verify_object(decoder)?;
878            }
879            Ok(())
880        }
881        MAJOR_MAP => {
882            // Verify map has integer keys in deterministic order
883            let len = value as usize;
884            let mut prev_key: Option<i64> = None;
885
886            for _ in 0..len {
887                // Decode and verify the key is an integer
888                let key = decoder.decode_int()?;
889
890                // Verify deterministic ordering
891                if let Some(prev) = prev_key
892                    && map_key_cmp(prev, key) != Ordering::Less
893                {
894                    return Err(Error::InvalidMapKeyOrder(key, prev));
895                }
896                prev_key = Some(key);
897
898                // Recursively verify the value
899                verify_object(decoder)?;
900            }
901            Ok(())
902        }
903        MAJOR_SIMPLE
904            if value == SIMPLE_FALSE as u64
905                || value == SIMPLE_TRUE as u64
906                || value == SIMPLE_NULL as u64 =>
907        {
908            // Booleans and null are valid simple values
909            Ok(())
910        }
911        _ => {
912            // Any other major type is disallowed
913            Err(Error::UnsupportedType(major))
914        }
915    }
916}
917
918#[cfg(test)]
919mod tests {
920    use super::*;
921
922    // Tests that booleans encode correctly.
923    #[test]
924    fn test_bool_encoding() {
925        assert_eq!(encode(&false), vec![0xf4]);
926        assert_eq!(encode(&true), vec![0xf5]);
927    }
928
929    // Tests that booleans decode correctly.
930    #[test]
931    fn test_bool_decoding() {
932        assert_eq!(decode::<bool>(&[0xf4]).unwrap(), false);
933        assert_eq!(decode::<bool>(&[0xf5]).unwrap(), true);
934
935        // Invalid values should fail
936        assert!(decode::<bool>(&[0xf6]).is_err()); // null
937        assert!(decode::<bool>(&[0x00]).is_err()); // integer
938    }
939
940    // Tests that null encodes correctly.
941    #[test]
942    fn test_null_encoding() {
943        assert_eq!(encode(&None::<u64>), vec![0xf6]);
944        assert_eq!(encode(&Some(42u64)), encode(&42u64));
945    }
946
947    // Tests that null decodes correctly.
948    #[test]
949    fn test_null_decoding() {
950        assert_eq!(decode::<Option<u64>>(&[0xf6]).unwrap(), None);
951        assert_eq!(decode::<Option<u64>>(&encode(&42u64)).unwrap(), Some(42));
952
953        // Nested options
954        assert_eq!(decode::<Option<bool>>(&[0xf4]).unwrap(), Some(false));
955        assert_eq!(decode::<Option<bool>>(&[0xf5]).unwrap(), Some(true));
956        assert_eq!(decode::<Option<bool>>(&[0xf6]).unwrap(), None);
957
958        // Null type
959        assert_eq!(decode::<Null>(&[0xf6]).unwrap(), Null);
960        assert!(decode::<Null>(&[0xf4]).is_err()); // false is not null
961        assert!(decode::<Null>(&[0x00]).is_err()); // integer is not null
962    }
963
964    // Tests that positive integers encode correctly across the various ranges
965    // that CBOR special cases.
966    #[test]
967    fn test_uint_encoding() {
968        let cases = [
969            (0u64, vec![0x00]),
970            (23u64, vec![0x17]),
971            (24u64, vec![0x18, 0x18]),
972            (u8::MAX as u64, vec![0x18, 0xff]),
973            (u8::MAX as u64 + 1, vec![0x19, 0x01, 0x00]),
974            (u16::MAX as u64, vec![0x19, 0xff, 0xff]),
975            (u16::MAX as u64 + 1, vec![0x1a, 0x00, 0x01, 0x00, 0x00]),
976            (u32::MAX as u64, vec![0x1a, 0xff, 0xff, 0xff, 0xff]),
977            (
978                u32::MAX as u64 + 1,
979                vec![0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00],
980            ),
981            (
982                u64::MAX,
983                vec![0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
984            ),
985        ];
986
987        for (value, expected) in cases {
988            assert_eq!(
989                encode(&value),
990                expected,
991                "encoding failed for value {}",
992                value
993            );
994        }
995    }
996
997    // Tests that positive integers decode correctly across the various ranges
998    // that CBOR special cases.
999    #[test]
1000    fn test_uint_decoding() {
1001        let cases = [
1002            (vec![0x00], 0u64),
1003            (vec![0x17], 23u64),
1004            (vec![0x18, 0x18], 24u64),
1005            (vec![0x18, 0xff], u8::MAX as u64),
1006            (vec![0x19, 0x01, 0x00], u8::MAX as u64 + 1),
1007            (vec![0x19, 0xff, 0xff], u16::MAX as u64),
1008            (vec![0x1a, 0x00, 0x01, 0x00, 0x00], u16::MAX as u64 + 1),
1009            (vec![0x1a, 0xff, 0xff, 0xff, 0xff], u32::MAX as u64),
1010            (
1011                vec![0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00],
1012                u32::MAX as u64 + 1,
1013            ),
1014            (
1015                vec![0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1016                u64::MAX,
1017            ),
1018        ];
1019
1020        for (data, expected) in cases {
1021            assert_eq!(
1022                decode::<u64>(&data).unwrap(),
1023                expected,
1024                "decoding failed for data {:?}",
1025                data
1026            );
1027        }
1028    }
1029
1030    // Tests that positive integers are rejected for invalid size / encoding
1031    // combinations.
1032    #[test]
1033    fn test_uint_rejection() {
1034        // Values 0-23 must use direct embedding
1035        for value in 0..24u64 {
1036            // Should fail with INFO_UINT8
1037            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT8, value as u8];
1038            assert!(decode::<u64>(&data).is_err());
1039
1040            // Should fail with INFO_UINT16
1041            data = vec![MAJOR_UINT << 5 | INFO_UINT16];
1042            data.extend_from_slice(&(value as u16).to_be_bytes());
1043            assert!(decode::<u64>(&data).is_err());
1044
1045            // Should fail with INFO_UINT32
1046            data = vec![MAJOR_UINT << 5 | INFO_UINT32];
1047            data.extend_from_slice(&(value as u32).to_be_bytes());
1048            assert!(decode::<u64>(&data).is_err());
1049
1050            // Should fail with INFO_UINT64
1051            data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1052            data.extend_from_slice(&value.to_be_bytes());
1053            assert!(decode::<u64>(&data).is_err());
1054        }
1055
1056        // Values 24-255 must use INFO_UINT8
1057        for value in 24..=u8::MAX as u64 {
1058            // Should fail with INFO_UINT16
1059            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT16];
1060            data.extend_from_slice(&(value as u16).to_be_bytes());
1061            assert!(decode::<u64>(&data).is_err());
1062
1063            // Should fail with INFO_UINT32
1064            data = vec![MAJOR_UINT << 5 | INFO_UINT32];
1065            data.extend_from_slice(&(value as u32).to_be_bytes());
1066            assert!(decode::<u64>(&data).is_err());
1067
1068            // Should fail with INFO_UINT64
1069            data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1070            data.extend_from_slice(&value.to_be_bytes());
1071            assert!(decode::<u64>(&data).is_err());
1072        }
1073
1074        // Values 256-65535 must use INFO_UINT16
1075        for value in [(u8::MAX as u64 + 1), u16::MAX as u64] {
1076            // Should fail with INFO_UINT32
1077            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT32];
1078            data.extend_from_slice(&(value as u32).to_be_bytes());
1079            assert!(decode::<u64>(&data).is_err());
1080
1081            // Should fail with INFO_UINT64
1082            data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1083            data.extend_from_slice(&value.to_be_bytes());
1084            assert!(decode::<u64>(&data).is_err());
1085        }
1086
1087        // Values 65536-4294967295 must use INFO_UINT32
1088        for value in [(u16::MAX as u64 + 1), u32::MAX as u64] {
1089            // Should fail with INFO_UINT64
1090            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1091            data.extend_from_slice(&value.to_be_bytes());
1092            assert!(decode::<u64>(&data).is_err());
1093        }
1094    }
1095
1096    // Tests that signed integers encode correctly across the various ranges.
1097    #[test]
1098    fn test_int_encoding() {
1099        let cases = [
1100            // Positive values use major type 0
1101            (0i64, vec![0x00]),
1102            (23i64, vec![0x17]),
1103            (24i64, vec![0x18, 0x18]),
1104            (
1105                i64::MAX,
1106                vec![0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1107            ),
1108            // Negative values use major type 1 with (-1 - n) encoding
1109            (-1i64, vec![0x20]),               // -1 -> wire value 0
1110            (-24i64, vec![0x37]),              // -24 -> wire value 23
1111            (-25i64, vec![0x38, 0x18]),        // -25 -> wire value 24
1112            (-256i64, vec![0x38, 0xff]),       // -256 -> wire value 255
1113            (-257i64, vec![0x39, 0x01, 0x00]), // -257 -> wire value 256
1114            (
1115                i64::MIN,
1116                vec![0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1117            ),
1118        ];
1119
1120        for (value, expected) in cases {
1121            assert_eq!(
1122                encode(&value),
1123                expected,
1124                "encoding failed for value {}",
1125                value
1126            );
1127        }
1128    }
1129
1130    // Tests that signed integers decode correctly across the various ranges.
1131    #[test]
1132    fn test_int_decoding() {
1133        let cases = [
1134            // Positive values (major type 0)
1135            (vec![0x00], 0i64),
1136            (vec![0x17], 23i64),
1137            (vec![0x18, 0x18], 24i64),
1138            (
1139                vec![0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1140                i64::MAX,
1141            ),
1142            // Negative values (major type 1)
1143            (vec![0x20], -1i64),
1144            (vec![0x37], -24i64),
1145            (vec![0x38, 0x18], -25i64),
1146            (vec![0x38, 0xff], -256i64),
1147            (vec![0x39, 0x01, 0x00], -257i64),
1148            (
1149                vec![0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1150                i64::MIN,
1151            ),
1152        ];
1153
1154        for (data, expected) in cases {
1155            assert_eq!(
1156                decode::<i64>(&data).unwrap(),
1157                expected,
1158                "decoding failed for data {:?}",
1159                data
1160            );
1161        }
1162    }
1163
1164    // Tests that signed integers are rejected for overflow conditions.
1165    #[test]
1166    fn test_int_rejection() {
1167        // Positive value > i64::MAX (major type 0 with value i64::MAX + 1)
1168        let mut data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1169        data.extend_from_slice(&((i64::MAX as u64) + 1).to_be_bytes());
1170        let result = decode::<i64>(&data);
1171        assert!(result.is_err());
1172        match result.unwrap_err() {
1173            Error::IntegerOverflow(negative, v, max) => {
1174                assert!(!negative);
1175                assert_eq!(v, 9223372036854775808);
1176                assert_eq!(max, 9223372036854775807);
1177            }
1178            other => panic!("Expected IntegerOverflow error, got {:?}", other),
1179        }
1180
1181        // Negative value < i64::MIN (major type 1 with wire value > i64::MAX)
1182        let mut data = vec![MAJOR_NINT << 5 | INFO_UINT64];
1183        data.extend_from_slice(&((i64::MAX as u64) + 1).to_be_bytes());
1184        let result = decode::<i64>(&data);
1185        assert!(result.is_err());
1186        match result.unwrap_err() {
1187            Error::IntegerOverflow(negative, v, max) => {
1188                assert!(negative);
1189                assert_eq!(v, 9223372036854775808);
1190                assert_eq!(max, 9223372036854775807);
1191            }
1192            other => panic!("Expected IntegerOverflow error, got {:?}", other),
1193        }
1194
1195        // Non-canonical negative integer encoding
1196        let data = vec![MAJOR_NINT << 5 | INFO_UINT8, 0x10]; // -17 with INFO_UINT8
1197        let result = decode::<i64>(&data);
1198        assert!(result.is_err());
1199        match result.unwrap_err() {
1200            Error::NonCanonical => {}
1201            other => panic!("Expected NonCanonical error, got {:?}", other),
1202        }
1203    }
1204
1205    // Tests that byte strings encode correctly on a bunch of samples.
1206    #[test]
1207    fn test_bytes_encoding() {
1208        // Empty bytes
1209        let empty: Vec<u8> = vec![];
1210        let encoded = encode(&empty);
1211        assert_eq!(encoded, vec![0x40]); // major 2, length 0
1212
1213        // 1 byte
1214        let one_byte = vec![0xaa];
1215        let encoded = encode(&one_byte);
1216        assert_eq!(encoded, vec![0x41, 0xaa]); // major 2, length 1, data
1217
1218        // Longer bytes
1219        let long_bytes = vec![0xde, 0xad, 0xbe, 0xef];
1220        let encoded = encode(&long_bytes);
1221        assert_eq!(encoded, vec![0x44, 0xde, 0xad, 0xbe, 0xef]); // major 2, length 4, data
1222
1223        // Test &Vec<u8> reference
1224        let bytes_vec = vec![1, 2, 3];
1225        let bytes_vec_ref = &bytes_vec;
1226        let encoded = encode(&bytes_vec_ref);
1227        assert_eq!(encoded, vec![0x43, 1, 2, 3]);
1228
1229        // Test &[u8] slice reference
1230        let bytes_slice: &[u8] = &[4, 5, 6];
1231        let encoded = encode(&bytes_slice);
1232        assert_eq!(encoded, vec![0x43, 4, 5, 6]);
1233
1234        // Test [u8; N] fixed-size array
1235        let bytes_array: [u8; 3] = [7, 8, 9];
1236        let encoded = encode(&bytes_array);
1237        assert_eq!(encoded, vec![0x43, 7, 8, 9]);
1238
1239        // Test &[u8; N] fixed-size array reference
1240        let bytes_array_ref = &[10u8, 11, 12];
1241        let encoded = encode(&bytes_array_ref);
1242        assert_eq!(encoded, vec![0x43, 10, 11, 12]);
1243    }
1244
1245    // Tests that byte strings decode correctly on a bunch of samples.
1246    #[test]
1247    fn test_bytes_decoding() {
1248        // Empty bytes
1249        let encoded = vec![0x40];
1250        let decoded = decode::<Vec<u8>>(&encoded).unwrap();
1251        assert_eq!(decoded, Vec::<u8>::new());
1252
1253        // 1 byte
1254        let encoded = vec![0x41, 0xaa];
1255        let decoded = decode::<Vec<u8>>(&encoded).unwrap();
1256        assert_eq!(decoded, vec![0xaa]);
1257
1258        // Longer bytes
1259        let data = vec![0xde, 0xad, 0xbe, 0xef];
1260        let mut encoded = vec![0x44]; // major 2, length 4
1261        encoded.extend_from_slice(&data);
1262        let decoded = decode::<Vec<u8>>(&encoded).unwrap();
1263        assert_eq!(decoded, data);
1264
1265        // Test fixed-size array decoding
1266        let encoded = vec![0x43, 1, 2, 3]; // major 2, length 3, data [1,2,3]
1267        let decoded = decode::<[u8; 3]>(&encoded).unwrap();
1268        assert_eq!(decoded, [1, 2, 3]);
1269
1270        // Test empty fixed-size array
1271        let encoded = vec![0x40]; // major 2, length 0
1272        let decoded = decode::<[u8; 0]>(&encoded).unwrap();
1273        assert_eq!(decoded, []);
1274    }
1275
1276    // Tests that bytes decoding fails when fixed size lengths don't match.
1277    #[test]
1278    fn test_bytes_rejection() {
1279        // Try to decode 3 bytes into a 4-byte array
1280        let encoded = vec![0x43, 1, 2, 3]; // major 2, length 3
1281        let result = decode::<[u8; 4]>(&encoded);
1282        assert!(result.is_err());
1283        match result.unwrap_err() {
1284            Error::UnexpectedItemCount(3, 4) => {} // Expected error
1285            other => panic!("Expected UnexpectedItemCount(3, 4) error, got {:?}", other),
1286        }
1287
1288        // Try to decode 4 bytes into a 2-byte array
1289        let encoded = vec![0x44, 1, 2, 3, 4]; // major 2, length 4
1290        let result = decode::<[u8; 2]>(&encoded);
1291        assert!(result.is_err());
1292        match result.unwrap_err() {
1293            Error::UnexpectedItemCount(4, 2) => {} // Expected error
1294            other => panic!("Expected UnexpectedItemCount(4, 2) error, got {:?}", other),
1295        }
1296    }
1297
1298    // Tests that UTF-8 strings encode correctly on a bunch of samples.
1299    #[test]
1300    fn test_string_encoding() {
1301        // Empty string
1302        let empty = "";
1303        let encoded = encode(&empty);
1304        assert_eq!(encoded, vec![0x60]); // major 3, length 0
1305
1306        // 1 character
1307        let one_char = "a";
1308        let encoded = encode(&one_char);
1309        assert_eq!(encoded, vec![0x61, 0x61]); // major 3, length 1, 'a'
1310
1311        // Longer string
1312        let long_string = "Peter says hi!";
1313        let encoded = encode(&long_string);
1314        assert_eq!(encoded[0], 0x60 | long_string.len() as u8); // major 3, length embedded
1315        assert_eq!(&encoded[1..], long_string.as_bytes());
1316
1317        // Test String type
1318        let string_type = "Peter says hi!".to_string();
1319        let encoded = encode(&string_type);
1320        assert_eq!(encoded[0], 0x60 | string_type.len() as u8); // major 3, length embedded
1321        assert_eq!(&encoded[1..], string_type.as_bytes());
1322
1323        // Test &String type
1324        let string_ref = &"Peter says hi!".to_string();
1325        let encoded = encode(&string_ref);
1326        assert_eq!(encoded[0], 0x60 | string_ref.len() as u8); // major 3, length embedded
1327        assert_eq!(&encoded[1..], string_ref.as_bytes());
1328    }
1329
1330    // Tests that UTF-8 strings decode correctly on a bunch of samples.
1331    #[test]
1332    fn test_string_decoding() {
1333        // Empty string
1334        let encoded = vec![0x60];
1335        let decoded = decode::<String>(&encoded).unwrap();
1336        assert_eq!(decoded, "");
1337
1338        // 1 character
1339        let encoded = vec![0x61, 0x61];
1340        let decoded = decode::<String>(&encoded).unwrap();
1341        assert_eq!(decoded, "a");
1342
1343        // Longer string
1344        let test_str = "Peter says hi!";
1345        let mut encoded = vec![0x60 | test_str.len() as u8];
1346        encoded.extend_from_slice(test_str.as_bytes());
1347        let decoded = decode::<String>(&encoded).unwrap();
1348        assert_eq!(decoded, test_str);
1349    }
1350
1351    // Tests that UTF-8 strings are rejected if containing invalid data.
1352    #[test]
1353    fn test_string_rejection() {
1354        // 0xff is not valid UTF-8
1355        let encoded = vec![0x61, 0xff]; // major 3, length 1, invalid byte
1356        let result = decode::<String>(&encoded);
1357        assert!(result.is_err());
1358
1359        match result.unwrap_err() {
1360            Error::InvalidUtf8 => {} // Expected error
1361            other => panic!("Expected InvalidUtf8 error, got {:?}", other),
1362        }
1363
1364        // Incomplete multi-byte sequence
1365        let encoded = vec![0x62, 0xc2, 0x00]; // major 3, length 2, incomplete UTF-8
1366        let result = decode::<String>(&encoded);
1367        assert!(result.is_err());
1368
1369        match result.unwrap_err() {
1370            Error::InvalidUtf8 => {} // Expected error
1371            other => panic!("Expected InvalidUtf8 error, got {:?}", other),
1372        }
1373    }
1374
1375    // Tests that tuples encode correctly on a bunch of samples.
1376    #[test]
1377    fn test_tuple_encoding() {
1378        // 0-tuple
1379        let empty = ();
1380        let encoded = encode(&empty);
1381        assert_eq!(encoded, vec![0x80]); // major 4, length 0 (empty array)
1382
1383        // 1-tuple (wonky Rust syntax)
1384        let one_tuple = (42u64,);
1385        let encoded = encode(&one_tuple);
1386        assert_eq!(encoded[0], 0x81); // major 4, length 1 (array with 1 element)
1387        assert_eq!(encoded[1], 0x18); // major 0, INFO_UINT8
1388        assert_eq!(encoded[2], 42);
1389
1390        // 2-tuple
1391        let t = ("hello".to_string(), 42u64);
1392        let encoded = encode(&t);
1393        assert_eq!(encoded[0], 0x82); // major 4, length 2 (array with 2 elements)
1394        // First element: "hello" -> 0x65 + "hello" bytes
1395        assert_eq!(encoded[1], 0x65); // major 3, length 5
1396        assert_eq!(&encoded[2..7], b"hello");
1397        // Second element: 42 -> 0x182a
1398        assert_eq!(encoded[7], 0x18); // major 0, INFO_UINT8
1399        assert_eq!(encoded[8], 42);
1400    }
1401
1402    // Tests that tuples decode correctly on a bunch of samples.
1403    #[test]
1404    fn test_tuple_decoding() {
1405        // 0-tuple
1406        let encoded = vec![0x80]; // empty array
1407        let decoded = decode::<()>(&encoded).unwrap();
1408        assert_eq!(decoded, ());
1409
1410        // 1-tuple (wonky Rust syntax)
1411        let mut encoded = vec![0x81]; // array length 1
1412        encoded.extend_from_slice(&encode(&42u64)); // single element
1413        let decoded = decode::<(u64,)>(&encoded).unwrap();
1414        assert_eq!(decoded, (42u64,));
1415
1416        // 2-tuple
1417        let mut encoded = vec![0x82]; // array length 2
1418        encoded.extend_from_slice(&encode(&"hello".to_string())); // first element
1419        encoded.extend_from_slice(&encode(&42u64)); // second element
1420        let decoded = decode::<(String, u64)>(&encoded).unwrap();
1421        assert_eq!(decoded, ("hello".to_string(), 42u64));
1422    }
1423
1424    // Tests that tuples are rejected if the size of the array does not match the
1425    // expected size.
1426    #[test]
1427    fn test_tuple_rejection() {
1428        // Try to decode array with 1 element as 2-tuple
1429        let mut encoded = vec![0x81]; // array length 1
1430        encoded.extend_from_slice(&encode(&42u64)); // single element
1431        let result = decode::<(u64, u64)>(&encoded);
1432        assert!(result.is_err());
1433        match result.unwrap_err() {
1434            Error::UnexpectedItemCount(1, 2) => {} // Expected error
1435            other => panic!("Expected UnexpectedItemCount(1, 2) error, got {:?}", other),
1436        }
1437
1438        // Try to decode array with 3 elements as 2-tuple
1439        let mut encoded = vec![0x83]; // array length 3
1440        encoded.extend_from_slice(&encode(&42u64));
1441        encoded.extend_from_slice(&encode(&"test".to_string()));
1442        encoded.extend_from_slice(&encode(&vec![1u8, 2]));
1443        let result = decode::<(u64, String)>(&encoded);
1444        assert!(result.is_err());
1445        match result.unwrap_err() {
1446            Error::UnexpectedItemCount(3, 2) => {} // Expected error
1447            other => panic!("Expected UnexpectedItemCount(3, 2) error, got {:?}", other),
1448        }
1449
1450        // Try to decode array with 1 element as empty tuple
1451        let mut encoded = vec![0x81]; // array length 1
1452        encoded.extend_from_slice(&encode(&42u64));
1453        let result = decode::<()>(&encoded);
1454        assert!(result.is_err());
1455        match result.unwrap_err() {
1456            Error::UnexpectedItemCount(1, 0) => {} // Expected error
1457            other => panic!("Expected UnexpectedItemCount(1, 0) error, got {:?}", other),
1458        }
1459    }
1460
1461    // Test struct for array encoding/decoding with derive macros.
1462    #[derive(Debug, PartialEq, Cbor)]
1463    #[cbor(array)]
1464    struct TestArray {
1465        first: u64,
1466        second: String,
1467        third: Vec<u8>,
1468    }
1469
1470    // Tests that array structs encode correctly in field declaration order.
1471    #[test]
1472    fn test_array_encoding() {
1473        let arr = TestArray {
1474            first: 42,
1475            second: "hello".to_string(),
1476            third: vec![1, 2, 3],
1477        };
1478        let encoded = encode(&arr);
1479
1480        // Should be: [42, "hello", h'010203']
1481        let mut expected = vec![0x83]; // array with 3 elements
1482        expected.extend_from_slice(&encode(&42u64));
1483        expected.extend_from_slice(&encode(&"hello".to_string()));
1484        expected.extend_from_slice(&encode(&vec![1u8, 2, 3]));
1485
1486        assert_eq!(encoded, expected);
1487    }
1488
1489    // Tests that array structs decode correctly.
1490    #[test]
1491    fn test_array_decoding() {
1492        let mut data = vec![0x83]; // array with 3 elements
1493        data.extend_from_slice(&encode(&100u64));
1494        data.extend_from_slice(&encode(&"world".to_string()));
1495        data.extend_from_slice(&encode(&vec![4u8, 5, 6]));
1496
1497        let decoded = decode::<TestArray>(&data).unwrap();
1498        assert_eq!(decoded.first, 100);
1499        assert_eq!(decoded.second, "world");
1500        assert_eq!(decoded.third, vec![4, 5, 6]);
1501    }
1502
1503    // Tests that array structs are rejected if the size does not match.
1504    #[test]
1505    fn test_array_rejection() {
1506        // Too few elements (2 instead of 3)
1507        let mut data = vec![0x82]; // array with 2 elements
1508        data.extend_from_slice(&encode(&42u64));
1509        data.extend_from_slice(&encode(&"test".to_string()));
1510        let result = decode::<TestArray>(&data);
1511        assert!(result.is_err());
1512        match result.unwrap_err() {
1513            Error::UnexpectedItemCount(2, 3) => {}
1514            other => panic!("Expected UnexpectedItemCount(2, 3) error, got {:?}", other),
1515        }
1516        // Too many elements (4 instead of 3)
1517        let mut data = vec![0x84]; // array with 4 elements
1518        data.extend_from_slice(&encode(&42u64));
1519        data.extend_from_slice(&encode(&"test".to_string()));
1520        data.extend_from_slice(&encode(&vec![1u8]));
1521        data.extend_from_slice(&encode(&42u64));
1522        let result = decode::<TestArray>(&data);
1523        assert!(result.is_err());
1524        match result.unwrap_err() {
1525            Error::UnexpectedItemCount(4, 3) => {}
1526            other => panic!("Expected UnexpectedItemCount(4, 3) error, got {:?}", other),
1527        }
1528    }
1529
1530    // Test struct for map encoding/decoding with derive macros.
1531    #[derive(Debug, PartialEq, Cbor)]
1532    struct TestMap {
1533        #[cbor(key = 1)]
1534        key1: u64,
1535        #[cbor(key = 2)]
1536        key2: u64,
1537        #[cbor(key = -1)]
1538        key_neg1: u64,
1539    }
1540
1541    // Tests that maps encode correctly with deterministic key ordering.
1542    #[test]
1543    fn test_map_encoding() {
1544        // Map with positive and negative keys (should be sorted by bytewise order)
1545        let map = TestMap {
1546            key1: 42,
1547            key2: 67,
1548            key_neg1: 100,
1549        };
1550        let encoded = encode(&map);
1551
1552        // Keys in bytewise order: 0x01, 0x02, 0x20 (1, 2, -1)
1553        assert_eq!(encoded[0], 0xa3); // map with 3 entries
1554        assert_eq!(encoded[1], 0x01); // key 1
1555        assert_eq!(encoded[2], 0x18);
1556        assert_eq!(encoded[3], 42);
1557        assert_eq!(encoded[4], 0x02); // key 2
1558        assert_eq!(encoded[5], 0x18);
1559        assert_eq!(encoded[6], 67);
1560        assert_eq!(encoded[7], 0x20); // key -1
1561        assert_eq!(encoded[8], 0x18);
1562        assert_eq!(encoded[9], 100);
1563    }
1564
1565    // Tests that maps decode correctly.
1566    #[test]
1567    fn test_map_decoding() {
1568        // Multiple entries (in correct deterministic order)
1569        let decoded = decode::<TestMap>(&vec![
1570            0xa3, // map with 3 entries
1571            0x01, 0x18, 0x2a, // 1: 42
1572            0x02, 0x18, 0x43, // 2: 67
1573            0x20, 0x18, 0x64, // -1: 100
1574        ])
1575        .unwrap();
1576        assert_eq!(decoded.key1, 42);
1577        assert_eq!(decoded.key2, 67);
1578        assert_eq!(decoded.key_neg1, 100);
1579    }
1580
1581    // Tests that maps with invalid key ordering are rejected.
1582    #[test]
1583    fn test_map_rejection() {
1584        // Keys out of order: 2 before 1
1585        let result = decode::<TestMap>(&vec![
1586            0xa3, // map with 3 entries
1587            0x02, 0x18, 0x43, // 2: 67 (should come after 1)
1588            0x01, 0x18, 0x2a, // 1: 42
1589            0x20, 0x18, 0x64, // -1: 100
1590        ]);
1591        assert!(result.is_err());
1592
1593        // Wrong key value
1594        let result = decode::<TestMap>(&vec![
1595            0xa3, // map with 3 entries
1596            0x05, 0x18, 0x2a, // 5: 42 (should be 1)
1597            0x02, 0x18, 0x43, // 2: 67
1598            0x20, 0x18, 0x64, // -1: 100
1599        ]);
1600        assert!(result.is_err());
1601    }
1602
1603    // Tests that Raw encodes correctly (passthrough of inner bytes).
1604    #[test]
1605    fn test_raw_encoding() {
1606        // Unsigned integer (42)
1607        let raw = Raw(vec![0x18, 0x2a]);
1608        assert_eq!(encode(&raw), vec![0x18, 0x2a]);
1609
1610        // String "hello"
1611        let raw = Raw(vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f]);
1612        assert_eq!(encode(&raw), vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f]);
1613
1614        // Tuple with Raw inside: ("method", <raw bytes for u64 1>)
1615        let raw = Raw(vec![0x01]);
1616        let encoded = encode(&("method", raw));
1617        assert_eq!(
1618            encoded,
1619            vec![
1620                0x82, // array of 2
1621                0x66, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // "method"
1622                0x01  // raw: u64 1
1623            ]
1624        );
1625    }
1626
1627    // Tests that Raw decodes correctly (captures raw CBOR bytes).
1628    #[test]
1629    fn test_raw_decoding() {
1630        // Unsigned integer (42)
1631        let data = vec![0x18, 0x2a];
1632        let raw: Raw = decode(&data).unwrap();
1633        assert_eq!(raw.0, vec![0x18, 0x2a]);
1634
1635        // String "hello"
1636        let data = vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f];
1637        let raw: Raw = decode(&data).unwrap();
1638        assert_eq!(raw.0, vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f]);
1639
1640        // Tuple with Raw: ("method", <raw params>)
1641        let data = vec![
1642            0x82, // array of 2
1643            0x66, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // "method"
1644            0x82, 0x01, 0x63, 0x61, 0x72, 0x67, // (1, "arg")
1645        ];
1646        let (method, params): (String, Raw) = decode(&data).unwrap();
1647        assert_eq!(method, "method");
1648        assert_eq!(params.0, vec![0x82, 0x01, 0x63, 0x61, 0x72, 0x67]);
1649    }
1650
1651    // Tests that Raw rejects unsupported major types.
1652    #[test]
1653    fn test_raw_rejection() {
1654        // Major type 6 (tags) - unsupported
1655        let data = vec![0xc0, 0x01]; // tag(0) followed by 1
1656        assert!(matches!(
1657            decode::<Raw>(&data),
1658            Err(Error::UnsupportedType(6))
1659        ));
1660
1661        // Major type 7 (floats) - unsupported, but bools/null are now supported
1662        let data = vec![0xf5]; // true - now valid
1663        assert!(decode::<Raw>(&data).is_ok());
1664
1665        // Float16 is still unsupported
1666        let data = vec![0xf9, 0x3c, 0x00]; // 1.0 as float16
1667        assert!(matches!(
1668            decode::<Raw>(&data),
1669            Err(Error::UnsupportedType(7))
1670        ));
1671
1672        // Trailing bytes
1673        let data = vec![0x18, 0x2a, 0x00]; // u64 42 + trailing 0x00
1674        assert!(matches!(decode::<Raw>(&data), Err(Error::TrailingBytes)));
1675    }
1676
1677    // Tests that the dry-decoding verifier properly restricts the allowed types.
1678    #[test]
1679    fn test_verify() {
1680        // Valid types should pass
1681        assert!(verify(&encode(&42u64)).is_ok());
1682        assert!(verify(&encode(&-42i64)).is_ok());
1683        assert!(verify(&encode(&"hello")).is_ok());
1684        assert!(verify(&encode(&vec![1u8, 2, 3])).is_ok());
1685        assert!(verify(&encode(&())).is_ok());
1686        assert!(verify(&encode(&(42u64, "test"))).is_ok());
1687        assert!(verify(&encode(&(-42i64, "test"))).is_ok());
1688        assert!(
1689            verify(&encode(&TestMap {
1690                key1: 1,
1691                key2: 2,
1692                key_neg1: 3,
1693            }))
1694            .is_ok()
1695        );
1696
1697        // Large integers are valid at verify time (overflow is checked at decode)
1698        let mut large_uint = vec![MAJOR_UINT << 5 | INFO_UINT64];
1699        large_uint.extend_from_slice(&u64::MAX.to_be_bytes());
1700        assert!(verify(&large_uint).is_ok());
1701
1702        let mut large_nint = vec![MAJOR_NINT << 5 | INFO_UINT64];
1703        large_nint.extend_from_slice(&u64::MAX.to_be_bytes());
1704        assert!(verify(&large_nint).is_ok());
1705
1706        // Trailing bytes
1707        let mut bad_data = encode(&42u64);
1708        bad_data.push(0x00);
1709        assert!(verify(&bad_data).is_err());
1710        match verify(&bad_data).unwrap_err() {
1711            Error::TrailingBytes => {}
1712            other => panic!("Expected TrailingBytes error, got {:?}", other),
1713        }
1714
1715        // Maps with string keys are rejected (key decoding fails)
1716        let map_str_key = vec![0xa1, 0x61, 0x61, 0x61, 0x62]; // {"a": "b"}
1717        assert!(verify(&map_str_key).is_err());
1718        match verify(&map_str_key).unwrap_err() {
1719            Error::InvalidMajorType(3, 0) => {} // text key when expecting int
1720            other => panic!(
1721                "Expected InvalidMajorType error for string key, got {:?}",
1722                other
1723            ),
1724        }
1725
1726        // Major type 6 (tags) - unsupported
1727        let tagged_data = vec![
1728            0xc0, 0x74, 0x32, 0x30, 0x31, 0x33, 0x2d, 0x30, 0x33, 0x2d, 0x32, 0x31, 0x54, 0x32,
1729            0x30, 0x3a, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x5a,
1730        ]; // tag 0 datetime
1731        assert!(verify(&tagged_data).is_err());
1732        match verify(&tagged_data).unwrap_err() {
1733            Error::UnsupportedType(6) => {}
1734            other => panic!("Expected UnsupportedType(6) error, got {:?}", other),
1735        }
1736
1737        // Booleans and null are now supported
1738        assert!(verify(&encode(&false)).is_ok());
1739        assert!(verify(&encode(&true)).is_ok());
1740        assert!(verify(&encode(&None::<u64>)).is_ok());
1741
1742        // undefined (0xf7) is still unsupported
1743        let undefined_val = vec![0xf7];
1744        assert!(verify(&undefined_val).is_err());
1745        match verify(&undefined_val).unwrap_err() {
1746            Error::UnsupportedType(7) => {}
1747            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
1748        }
1749
1750        // Float16
1751        let float16 = vec![0xf9, 0x3c, 0x00]; // 1.0 as float16
1752        assert!(verify(&float16).is_err());
1753        match verify(&float16).unwrap_err() {
1754            Error::UnsupportedType(7) => {}
1755            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
1756        }
1757
1758        // Float32
1759        let float32 = vec![0xfa, 0x3f, 0x80, 0x00, 0x00]; // 1.0 as float32
1760        assert!(verify(&float32).is_err());
1761        match verify(&float32).unwrap_err() {
1762            Error::UnsupportedType(7) => {}
1763            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
1764        }
1765
1766        // Float64
1767        let float64 = vec![0xfb, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; // 1.0 as float64
1768        assert!(verify(&float64).is_err());
1769        match verify(&float64).unwrap_err() {
1770            Error::UnsupportedType(7) => {}
1771            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
1772        }
1773
1774        // Invalid UTF-8 in text string
1775        let invalid_text = vec![0x61, 0xff]; // text string with invalid UTF-8
1776        assert!(verify(&invalid_text).is_err());
1777        match verify(&invalid_text).unwrap_err() {
1778            Error::InvalidUtf8 => {}
1779            other => panic!("Expected InvalidUtf8 error, got {:?}", other),
1780        }
1781
1782        // Non-canonical encodings
1783        let non_canonical = vec![0x18, 0x10]; // 16 encoded as INFO_UINT8 instead of direct
1784        assert!(verify(&non_canonical).is_err());
1785        match verify(&non_canonical).unwrap_err() {
1786            Error::NonCanonical => {}
1787            other => panic!("Expected NonCanonical error, got {:?}", other),
1788        }
1789
1790        // Nested arrays with booleans are now valid
1791        let nested_bool = vec![0x81, 0xf4]; // [false]
1792        assert!(verify(&nested_bool).is_ok());
1793
1794        // Nested arrays with floats are still invalid
1795        let nested_float = vec![0x81, 0xf9, 0x3c, 0x00]; // [1.0 as float16]
1796        assert!(verify(&nested_float).is_err());
1797        match verify(&nested_float).unwrap_err() {
1798            Error::UnsupportedType(7) => {}
1799            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
1800        }
1801
1802        // Incomplete data
1803        let incomplete = vec![0x61]; // text string header without data
1804        assert!(verify(&incomplete).is_err());
1805        match verify(&incomplete).unwrap_err() {
1806            Error::UnexpectedEof => {}
1807            other => panic!("Expected UnexpectedEof error, got {:?}", other),
1808        }
1809
1810        // Invalid additional info
1811        let invalid_info = vec![0x1c]; // UINT with additional info 28 (reserved)
1812        assert!(verify(&invalid_info).is_err());
1813        match verify(&invalid_info).unwrap_err() {
1814            Error::InvalidAdditionalInfo(28) => {}
1815            other => panic!("Expected InvalidAdditionalInfo(28) error, got {:?}", other),
1816        }
1817    }
1818
1819    // Tests a length overflow issue caught by the fuzzer:
1820    //  - https://github.com/dark-bio/crypto-rs/pull/3
1821    #[test]
1822    fn test_issue_3() {
1823        let encoded = vec![123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
1824        let result = decode::<String>(&encoded);
1825        assert!(result.is_err());
1826    }
1827}