Repository: google/OpenSK
File: libraries/cbor/src/reader.rs (Rust)

Code before:
    cbor_array_vec, cbor_bytes_lit, cbor_map_collection, cbor_tagged, cbor_text, cbor_unsigned,
};
use alloc::str;
use alloc::vec::Vec;

/// Possible errors from a deserialization operation.
#[derive(Debug, PartialEq)]
pub enum DecoderError {
    UnsupportedMajorType,
    UnknownAdditionalInfo,
    IncompleteCborData,
    TooMuchNesting,
    InvalidUtf8,
    ExtraneousData,
    OutOfOrderKey,
    NonMinimalCborEncoding,
    UnsupportedSimpleValue,
    UnsupportedFloatingPointValue,
    OutOfRangeIntegerValue,
}

/// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data.
pub fn read(encoded_cbor: &[u8]) -> Result<Value, DecoderError> {
    read_nested(encoded_cbor, Some(i8::MAX))
}

/// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data.  If
/// `max_nest` is `Some(max)`, then nested structures are only supported up to the given limit (returning
/// [`DecoderError::TooMuchNesting`] if the limit is hit).
pub fn read_nested(encoded_cbor: &[u8], max_nest: Option<i8>) -> Result<Value, DecoderError> {
    let mut reader = Reader::new(encoded_cbor);
    let value = reader.decode_complete_data_item(max_nest)?;
    if !reader.remaining_cbor.is_empty() {
        return Err(DecoderError::ExtraneousData);
    }
    Ok(value)
}

struct Reader<'a> {
    remaining_cbor: &'a [u8],
}

impl<'a> Reader<'a> {
    pub fn new(cbor: &'a [u8]) -> Reader<'a> {
        Reader {
            remaining_cbor: cbor,
        }
    }

    pub fn decode_complete_data_item(
        &mut self,

Review comment (suggestion):
Actually, now I'm wondering why we even need to support infinite nesting. Shouldn't we just have `read_nested(i8)`? When is infinite nesting useful? We could keep `read()` for convenience but I'm not even sure it's a good decision. It's better to see explicitly at call site the nesting. Users could wrap that value in a convenience `read()` function used everywhere in their project.)

Code after:
    cbor_array_vec, cbor_bytes_lit, cbor_map_collection, cbor_tagged, cbor_text, cbor_unsigned,
};
use alloc::str;
use alloc::vec::Vec;

/// Possible errors from a deserialization operation.
#[derive(Debug, PartialEq)]
pub enum DecoderError {
    UnsupportedMajorType,
    UnknownAdditionalInfo,
    IncompleteCborData,
    TooMuchNesting,
    InvalidUtf8,
    ExtraneousData,
    OutOfOrderKey,
    NonMinimalCborEncoding,
    UnsupportedSimpleValue,
    UnsupportedFloatingPointValue,
    OutOfRangeIntegerValue,
}

/// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data.
/// Maximum level of nesting supported is 127; more deeply nested structures will fail with
/// [`DecoderError::TooMuchNesting`].
pub fn read(encoded_cbor: &[u8]) -> Result<Value, DecoderError> {
    read_nested(encoded_cbor, Some(i8::MAX))
}

/// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data.  If
/// `max_nest` is `Some(max)`, then nested structures are only supported up to the given limit (returning
/// [`DecoderError::TooMuchNesting`] if the limit is hit).
pub fn read_nested(encoded_cbor: &[u8], max_nest: Option<i8>) -> Result<Value, DecoderError> {
    let mut reader = Reader::new(encoded_cbor);
    let value = reader.decode_complete_data_item(max_nest)?;
    if !reader.remaining_cbor.is_empty() {
        return Err(DecoderError::ExtraneousData);
    }
    Ok(value)
}

struct Reader<'a> {
    remaining_cbor: &'a [u8],
}

impl<'a> Reader<'a> {
    pub fn new(cbor: &'a [u8]) -> Reader<'a> {
        Reader {
            remaining_cbor: cbor,
        }
    }