#[ macro_use]
extern crate serde_derive;
use serde_cbor;
use serde_cbor::de;
#[ test]
fn test_str() {
let s: &str =
de::from_slice_with_scratch(&[0 x66, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72], &mut []).unwrap();
assert_eq!(s, "foobar" );
}
#[ test]
fn test_bytes() {
let s: &[u8] =
de::from_slice_with_scratch(&[0 x46, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72], &mut []).unwrap();
assert_eq!(s, b"foobar" );
}
#[ test]
fn test_int() {
let num: i64 = de::from_slice_with_scratch(&[0 x39, 0 x07, 0 xde], &mut []).unwrap();
assert_eq!(num, -2015 );
}
#[ test]
fn test_float() {
let float: f64 = de::from_slice_with_scratch(b"\xfa\x47\xc3\x50\x00" , &mut []).unwrap();
assert_eq!(float, 100000 .0 );
}
#[ test]
fn test_indefinite_object() {
#[ derive(Debug, Deserialize, PartialEq)]
struct Foo {
a: u64,
b: [u64; 2 ],
}
let expected = Foo { a: 1 , b: [2 , 3 ] };
let actual: Foo =
de::from_slice_with_scratch(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff" , &mut []).unwrap();
assert_eq!(expected, actual);
}
#[ cfg(feature = "std" )]
mod std_tests {
use std::collections::BTreeMap;
use serde::de as serde_de;
use serde_cbor::value::Value;
use serde_cbor::{de, error, to_vec, Deserializer};
#[ test]
fn test_string1() {
let value: error::Result<Value> =
de::from_slice(&[0 x66, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72]);
assert_eq!(value.unwrap(), Value::Text("foobar" .to_owned()));
}
#[ test]
fn test_string2() {
let value: error::Result<Value> = de::from_slice(&[
0 x71, 0 x49, 0 x20, 0 x6d, 0 x65, 0 x74, 0 x20, 0 x61, 0 x20, 0 x74, 0 x72, 0 x61, 0 x76, 0 x65,
0 x6c, 0 x6c, 0 x65, 0 x72,
]);
assert_eq!(value.unwrap(), Value::Text("I met a traveller" .to_owned()));
}
#[ test]
fn test_string3() {
let slice = b"\x78\x2fI met a traveller from an antique land who said" ;
let value: error::Result<Value> = de::from_slice(slice);
assert_eq!(
value.unwrap(),
Value::Text("I met a traveller from an antique land who said" .to_owned())
);
}
#[ test]
fn test_byte_string() {
let value: error::Result<Value> =
de::from_slice(&[0 x46, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72]);
assert_eq!(value.unwrap(), Value::Bytes(b"foobar" .to_vec()));
}
#[ test]
fn test_numbers1() {
let value: error::Result<Value> = de::from_slice(&[0 x00]);
assert_eq!(value.unwrap(), Value::Integer(0 ));
}
#[ test]
fn test_numbers2() {
let value: error::Result<Value> = de::from_slice(&[0 x1a, 0 x00, 0 xbc, 0 x61, 0 x4e]);
assert_eq!(value.unwrap(), Value::Integer(12345678 ));
}
#[ test]
fn test_numbers3() {
let value: error::Result<Value> = de::from_slice(&[0 x39, 0 x07, 0 xde]);
assert_eq!(value.unwrap(), Value::Integer(-2015 ));
}
#[ test]
fn test_bool() {
let value: error::Result<Value> = de::from_slice(b"\xf4" );
assert_eq!(value.unwrap(), Value::Bool(false ));
}
#[ test]
fn test_trailing_bytes() {
let value: error::Result<Value> = de::from_slice(b"\xf4trailing" );
assert!(value.is_err());
}
#[ test]
fn test_list1() {
let value: error::Result<Value> = de::from_slice(b"\x83\x01\x02\x03" );
assert_eq!(
value.unwrap(),
Value::Array(vec![
Value::Integer(1 ),
Value::Integer(2 ),
Value::Integer(3 )
])
);
}
#[ test]
fn test_list2() {
let value: error::Result<Value> = de::from_slice(b"\x82\x01\x82\x02\x81\x03" );
assert_eq!(
value.unwrap(),
Value::Array(vec![
Value::Integer(1 ),
Value::Array(vec![
Value::Integer(2 ),
Value::Array(vec![Value::Integer(3 )])
])
])
);
}
#[ test]
fn test_object() {
let value: error::Result<Value> = de::from_slice(b"\xa5aaaAabaBacaCadaDaeaE" );
let mut object = BTreeMap::new();
object.insert(Value::Text("a" .to_owned()), Value::Text("A" .to_owned()));
object.insert(Value::Text("b" .to_owned()), Value::Text("B" .to_owned()));
object.insert(Value::Text("c" .to_owned()), Value::Text("C" .to_owned()));
object.insert(Value::Text("d" .to_owned()), Value::Text("D" .to_owned()));
object.insert(Value::Text("e" .to_owned()), Value::Text("E" .to_owned()));
assert_eq!(value.unwrap(), Value::Map(object));
}
#[ test]
fn test_indefinite_object() {
let value: error::Result<Value> = de::from_slice(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff" );
let mut object = BTreeMap::new();
object.insert(Value::Text("a" .to_owned()), Value::Integer(1 ));
object.insert(
Value::Text("b" .to_owned()),
Value::Array(vec![Value::Integer(2 ), Value::Integer(3 )]),
);
assert_eq!(value.unwrap(), Value::Map(object));
}
#[ test]
fn test_indefinite_list() {
let value: error::Result<Value> = de::from_slice(b"\x9f\x01\x02\x03\xff" );
assert_eq!(
value.unwrap(),
Value::Array(vec![
Value::Integer(1 ),
Value::Integer(2 ),
Value::Integer(3 )
])
);
}
#[ test]
fn test_indefinite_string() {
let value: error::Result<Value> =
de::from_slice(b"\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff" );
assert_eq!(
value.unwrap(),
Value::Text("Mary Had a Little Lamb" .to_owned())
);
}
#[ test]
fn test_indefinite_byte_string() {
let value: error::Result<Value> = de::from_slice(b"\x5f\x42\x01\x23\x42\x45\x67\xff" );
assert_eq!(value.unwrap(), Value::Bytes(b"\x01#Eg" .to_vec()));
}
#[ test]
fn test_multiple_indefinite_strings() {
let input = b"\x82\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff\x5f\x42\x01\x23\x42\x45\x67\xff" ;
_test_multiple_indefinite_strings(de::from_slice(input));
_test_multiple_indefinite_strings(de::from_mut_slice(input.to_vec().as_mut()));
let mut buf = [0 u8; 64 ];
_test_multiple_indefinite_strings(de::from_slice_with_scratch(input, &mut buf));
}
fn _test_multiple_indefinite_strings(value: error::Result<Value>) {
// This assures that buffer rewinding in infinite buffers works as intended.
assert_eq!(
value.unwrap(),
Value::Array(vec![
Value::Text("Mary Had a Little Lamb" .to_owned()),
Value::Bytes(b"\x01#Eg" .to_vec())
])
);
}
#[ test]
fn test_float() {
let value: error::Result<Value> = de::from_slice(b"\xfa\x47\xc3\x50\x00" );
assert_eq!(value.unwrap(), Value::Float(100000 .0 ));
}
#[ test]
fn test_self_describing() {
let value: error::Result<Value> =
de::from_slice(&[0 xd9, 0 xd9, 0 xf7, 0 x66, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72]);
let expected = Value::Text("foobar" .to_owned());
let strip_tags = |x: Value| {
if let Value::Tag(_, inner) = x {
*inner
} else {
x
}
};
assert_eq!(strip_tags(value.unwrap()), expected);
}
#[ test]
fn test_f16() {
let mut x: Value = de::from_slice(&[0 xf9, 0 x41, 0 x00]).unwrap();
assert_eq!(x, Value::Float(2 .5 ));
x = de::from_slice(&[0 xf9, 0 x41, 0 x90]).unwrap();
assert_eq!(x, Value::Float(2 .78125 ));
x = de::from_slice(&[0 xf9, 0 x50, 0 x90]).unwrap();
assert_eq!(x, Value::Float(36 .5 ));
x = de::from_slice(&[0 xf9, 0 xd0, 0 x90]).unwrap();
assert_eq!(x, Value::Float(-36 .5 ));
}
#[ test]
fn test_crazy_list() {
let slice = b"\x88\x1b\x00\x00\x00\x1c\xbe\x99\x1d\xc7\x3b\x00\x7a\xcf\x51\xdc\x51\x70\xdb\x3a\x1b\x3a\x06\xdd\xf5\xf6\xf7\xfb\x41\x76\x5e\xb1\xf8\x00\x00\x00\xf9\x7c\x00" ;
let value: Vec<Value> = de::from_slice(slice).unwrap();
assert_eq!(
value,
vec![
Value::Integer(123456789959 ),
Value::Integer(-34567897654325468 ),
Value::Integer(-456787678 ),
Value::Bool(true ),
Value::Null,
Value::Null,
Value::Float(23456543 .5 ),
Value::Float(::std::f64::INFINITY)
]
);
}
#[ test]
fn test_nan() {
let value: f64 = de::from_slice(b"\xf9\x7e\x00" ).unwrap();
assert!(value.is_nan());
}
#[ test]
fn test_32f16() {
let value: f32 = de::from_slice(b"\xf9\x50\x00" ).unwrap();
assert_eq!(value, 32 .0 f32);
}
#[ test]
// The file was reported as not working by user kie0tauB
// but it parses to a cbor value.
fn test_kietaub_file() {
let file = include_bytes!("kietaub.cbor" );
let value_result: error::Result<Value> = de::from_slice(file);
value_result.unwrap();
}
#[ test]
fn test_option_roundtrip() {
let obj1 = Some(10 u32);
let v = to_vec(&obj1).unwrap();
let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);
println!("{:?}" , obj2);
assert_eq!(obj1, obj2.unwrap());
}
#[ test]
fn test_option_none_roundtrip() {
let obj1 = None;
let v = to_vec(&obj1).unwrap();
println!("{:?}" , v);
let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);
assert_eq!(obj1, obj2.unwrap());
}
#[ test]
fn test_variable_length_map() {
let slice = b"\xbf\x67\x6d\x65\x73\x73\x61\x67\x65\x64\x70\x6f\x6e\x67\xff" ;
let value: Value = de::from_slice(slice).unwrap();
let mut map = BTreeMap::new();
map.insert(
Value::Text("message" .to_string()),
Value::Text("pong" .to_string()),
);
assert_eq!(value, Value::Map(map))
}
#[ test]
fn test_object_determinism_roundtrip() {
let expected = b"\xa2aa\x01ab\x82\x02\x03" ;
// 0.1% chance of not catching failure
for _ in 0 ..10 {
assert_eq!(
&to_vec(&de::from_slice::<Value>(expected).unwrap()).unwrap(),
expected
);
}
}
#[ test]
fn stream_deserializer() {
let slice = b"\x01\x66foobar" ;
let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
assert_eq!(Value::Integer(1 ), it.next().unwrap().unwrap());
assert_eq!(
Value::Text("foobar" .to_string()),
it.next().unwrap().unwrap()
);
assert!(it.next().is_none());
}
#[ test]
fn stream_deserializer_eof() {
let slice = b"\x01\x66foob" ;
let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
assert_eq!(Value::Integer(1 ), it.next().unwrap().unwrap());
assert!(it.next().unwrap().unwrap_err().is_eof());
}
#[ test]
fn stream_deserializer_eof_in_indefinite() {
let slice = b"\x7f\x65Mary \x64Had \x62a \x60\x67Little \x60\x64Lamb\xff" ;
let indices: &[usize] = &[
2 , // announcement but no data
10 , // mid-buffer EOF
12 , // neither new element nor end marker
];
for end_of_slice in indices {
let mut it = Deserializer::from_slice(&slice[..*end_of_slice]).into_iter::<Value>();
assert!(it.next().unwrap().unwrap_err().is_eof());
let mut mutcopy = slice[..*end_of_slice].to_vec();
let mut it = Deserializer::from_mut_slice(mutcopy.as_mut()).into_iter::<Value>();
assert!(it.next().unwrap().unwrap_err().is_eof());
let mut buf = [0 u8; 64 ];
let mut it = Deserializer::from_slice_with_scratch(&slice[..*end_of_slice], &mut buf)
.into_iter::<Value>();
assert!(it.next().unwrap().unwrap_err().is_eof());
}
}
#[ test]
fn crash() {
let file = include_bytes!("crash.cbor" );
let value_result: error::Result<Value> = de::from_slice(file);
assert_eq!(
value_result.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
}
fn from_slice_stream<'a, T>(slice: &' a [u8]) -> error::Result<(&>'a [u8], T)>
where
T: serde_de::Deserialize<'a>,
{
let mut deserializer = Deserializer::from_slice(slice);
let value = serde_de::Deserialize::deserialize(&mut deserializer)?;
let rest = &slice[deserializer.byte_offset()..];
Ok((rest, value))
}
#[ test]
fn test_slice_offset() {
let v: Vec<u8> = vec![
0 x66, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72, 0 x66, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72,
];
let (rest, value): (&[u8], String) = from_slice_stream(&v[..]).unwrap();
assert_eq!(value, "foobar" );
assert_eq!(rest, &[0 x66, 0 x66, 0 x6f, 0 x6f, 0 x62, 0 x61, 0 x72]);
let (rest, value): (&[u8], String) = from_slice_stream(rest).unwrap();
assert_eq!(value, "foobar" );
assert_eq!(rest, &[]);
}
#[ derive(Debug, Copy, Clone)]
struct Options {
standard: bool,
legacy: bool,
packed: bool,
named: bool,
}
impl Default for Options {
fn default() -> Self {
Options {
standard: true ,
legacy: true ,
packed: true ,
named: true ,
}
}
}
impl Options {
fn no_standard(self ) -> Self {
Options {
standard: false ,
..self
}
}
fn no_legacy(self ) -> Self {
Options {
legacy: false ,
..self
}
}
fn no_packed(self ) -> Self {
Options {
packed: false ,
..self
}
}
fn no_named(self ) -> Self {
Options {
named: false ,
..self
}
}
}
fn from_slice_stream_options<'a, T>(
slice: &'a [u8],
options: Options,
) -> error::Result<(&'a [u8], T)>
where
T: serde_de::Deserialize<'a>,
{
let deserializer = Deserializer::from_slice(slice);
let deserializer = if !options.packed {
deserializer.disable_packed_format()
} else {
deserializer
};
let deserializer = if !options.named {
deserializer.disable_named_format()
} else {
deserializer
};
let deserializer = if !options.standard {
deserializer.disable_standard_enums()
} else {
deserializer
};
let mut deserializer = if !options.legacy {
deserializer.disable_legacy_enums()
} else {
deserializer
};
let value = serde_de::Deserialize::deserialize(&mut deserializer)?;
let rest = &slice[deserializer.byte_offset()..];
Ok((rest, value))
}
#[ test]
fn test_deserializer_enums() {
#[ derive(Debug, PartialEq, Deserialize)]
enum Enum {
Unit,
NewType(i32),
Tuple(String, bool),
Struct { x: i32, y: i32 },
}
// This is the format used in serde >= 0.10
//
// Serialization of Enum::NewType(10)
let v: Vec<u8> = vec![
0 xa1, // map 1pair
0 x67, 0 x4e, 0 x65, 0 x77, 0 x54, 0 x79, 0 x70, 0 x65, // utf8 string: NewType
0 x1a, // u32
0 x00, 0 x00, 0 x00, 0 x0a, // 10 (dec)
];
let (_rest, value): (&[u8], Enum ) = from_slice_stream(&v[..]).unwrap();
assert_eq!(value, Enum ::NewType(10 ));
let (_rest, value): (&[u8], Enum ) =
from_slice_stream_options(&v[..], Options::default().no_legacy()).unwrap();
assert_eq!(value, Enum ::NewType(10 ));
let value: error::Result<(&[u8], Enum )> =
from_slice_stream_options(&v[..], Options::default().no_standard());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
let value: error::Result<(&[u8], Enum )> =
from_slice_stream_options(&v[..], Options::default().no_standard().no_legacy());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
// Serialization of Enum::Unit
let v: Vec<u8> = vec![
0 x64, 0 x55, 0 x6e, 0 x69, 0 x74, // utf8 string: Unit
];
let (_rest, value): (&[u8], Enum ) = from_slice_stream(&v[..]).unwrap();
assert_eq!(value, Enum ::Unit);
let (_rest, value): (&[u8], Enum ) =
from_slice_stream_options(&v[..], Options::default().no_legacy()).unwrap();
assert_eq!(value, Enum ::Unit);
let (_rest, value): (&[u8], Enum ) =
from_slice_stream_options(&v[..], Options::default().no_standard()).unwrap();
assert_eq!(value, Enum ::Unit);
let value: error::Result<(&[u8], Enum )> =
from_slice_stream_options(&v[..], Options::default().no_legacy().no_standard());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
// This is the format used in serde <= 0.9
let v: Vec<u8> = vec![
0 x82, // array 2 items
0 x67, 0 x4e, 0 x65, 0 x77, 0 x54, 0 x79, 0 x70, 0 x65, // utf8 string: NewType
0 x1a, // u32
0 x00, 0 x00, 0 x00, 0 x0a, // 10 (dec)
];
let (_rest, value): (&[u8], Enum ) = from_slice_stream(&v[..]).unwrap();
assert_eq!(value, Enum ::NewType(10 ));
let value: error::Result<(&[u8], Enum )> =
from_slice_stream_options(&v[..], Options::default().no_legacy());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
let value: error::Result<(&[u8], Enum )> =
from_slice_stream_options(&v[..], Options::default().no_standard());
assert_eq!(value.unwrap().1 , Enum ::NewType(10 ));
let value: error::Result<(&[u8], Enum )> =
from_slice_stream_options(&v[..], Options::default().no_standard().no_legacy());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
}
#[ test]
fn test_packed_deserialization() {
#[ derive(Debug, PartialEq, Deserialize)]
struct User {
user_id: u32,
password_hash: [u8; 4 ],
}
// unpacked
let v: Vec<u8> = vec![
0 xa2, // map 2pair
0 x67, 0 x75, 0 x73, 0 x65, 0 x72, 0 x5f, 0 x69, 0 x64, // utf8 string: user_id
0 x0a, // integer: 10
// utf8 string: password_hash
0 x6d, 0 x70, 0 x61, 0 x73, 0 x73, 0 x77, 0 x6f, 0 x72, 0 x64, 0 x5f, 0 x68, 0 x61, 0 x73, 0 x68,
0 x84, 0 x01, 0 x02, 0 x03, 0 x04, // 4 byte array [1, 2, 3, 4]
];
let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let (_rest, value): (&[u8], User) =
from_slice_stream_options(&v[..], Options::default().no_packed()).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let value: error::Result<(&[u8], User)> =
from_slice_stream_options(&v[..], Options::default().no_named());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
// unpacked - indefinite length
let v: Vec<u8> = vec![
0 xbf, // map to be followed by a break
0 x67, 0 x75, 0 x73, 0 x65, 0 x72, 0 x5f, 0 x69, 0 x64, // utf8 string: user_id
0 x0a, // integer: 10
// utf8 string: password_hash
0 x6d, 0 x70, 0 x61, 0 x73, 0 x73, 0 x77, 0 x6f, 0 x72, 0 x64, 0 x5f, 0 x68, 0 x61, 0 x73, 0 x68,
0 x84, 0 x01, 0 x02, 0 x03, 0 x04, // 4 byte array [1, 2, 3, 4]
0 xff, // break
];
let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let (_rest, value): (&[u8], User) =
from_slice_stream_options(&v[..], Options::default().no_packed()).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let value: error::Result<(&[u8], User)> =
from_slice_stream_options(&v[..], Options::default().no_named());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
// packed
let v: Vec<u8> = vec![
0 xa2, // map 2pair
0 x00, // index 0
0 x0a, // integer: 10
0 x01, // index 1
0 x84, 0 x01, 0 x02, 0 x03, 0 x04, // 4 byte array [1, 2, 3, 4]
];
let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let (_rest, value): (&[u8], User) =
from_slice_stream_options(&v[..], Options::default().no_named()).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let value: error::Result<(&[u8], User)> =
from_slice_stream_options(&v[..], Options::default().no_packed());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
// packed - indefinite length
let v: Vec<u8> = vec![
0 xbf, // map, to be followed by a break
0 x00, // index 0
0 x0a, // integer: 10
0 x01, // index 1
0 x84, 0 x01, 0 x02, 0 x03, 0 x04, // 4 byte array [1, 2, 3, 4]
0 xff, // break
];
let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let (_rest, value): (&[u8], User) =
from_slice_stream_options(&v[..], Options::default().no_named()).unwrap();
assert_eq!(
value,
User {
user_id: 10 ,
password_hash: [1 , 2 , 3 , 4 ],
}
);
let value: error::Result<(&[u8], User)> =
from_slice_stream_options(&v[..], Options::default().no_packed());
assert_eq!(
value.unwrap_err().classify(),
serde_cbor::error::Category::Syntax
);
}
use serde_cbor::{de::from_slice, ser::to_vec_packed};
use std::net::{IpAddr, Ipv4Addr};
#[ test]
fn test_ipaddr_deserialization() {
let ip = IpAddr::V4(Ipv4Addr::new(127 , 0 , 0 , 1 ));
let buf = to_vec_packed(&ip).unwrap();
let deserialized_ip = from_slice::<IpAddr>(&buf).unwrap();
assert_eq!(ip, deserialized_ip);
let buf = to_vec(&ip).unwrap();
let deserialized_ip = from_slice::<IpAddr>(&buf).unwrap();
assert_eq!(ip, deserialized_ip);
}
#[ test]
fn attempt_stack_overflow() {
// Create a tag 17, followed by 999 more tag 17:
// 17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(...
// This causes deep recursion in the decoder and may
// exhaust the stack and therfore result in a stack overflow.
let input = vec![0 xd1; 1000 ];
let err = serde_cbor::from_slice::<serde_cbor::Value>(&input).expect_err("recursion limit" );
assert!(err.is_syntax());
}
}
Messung V0.5 in Prozent C=94 H=100 G=96
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-06-17)
¤
*© Formatika GbR, Deutschland