Skip to content

Commit f177481

Browse files
Fix deserialization of u64
1 parent 538a6f1 commit f177481

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/de.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,51 @@ impl<'de> Deserializer<'de> {
156156
_ => Err(Error::DeserializeBadU32),
157157
}
158158
}
159+
fn raw_deserialize_u64(&mut self, major: u8) -> Result<u64> {
160+
let additional = self.expect_major(major)?;
161+
162+
match additional {
163+
byte @ 0..=23 => Ok(byte as u64),
164+
24 => match self.try_take_n(1)?[0] {
165+
0..=23 => Err(Error::DeserializeNonMinimal),
166+
byte => Ok(byte as u64),
167+
},
168+
25 => {
169+
let unsigned = u16::from_be_bytes(
170+
self.try_take_n(2)?
171+
.try_into()
172+
.map_err(|_| Error::InexistentSliceToArrayError)?,
173+
);
174+
match unsigned {
175+
0..=255 => Err(Error::DeserializeNonMinimal),
176+
unsigned => Ok(unsigned as u64),
177+
}
178+
}
179+
26 => {
180+
let unsigned = u32::from_be_bytes(
181+
self.try_take_n(4)?
182+
.try_into()
183+
.map_err(|_| Error::InexistentSliceToArrayError)?,
184+
);
185+
match unsigned {
186+
0..=65535 => Err(Error::DeserializeNonMinimal),
187+
unsigned => Ok(unsigned as u64),
188+
}
189+
}
190+
27 => {
191+
let unsigned = u64::from_be_bytes(
192+
self.try_take_n(8)?
193+
.try_into()
194+
.map_err(|_| Error::InexistentSliceToArrayError)?,
195+
);
196+
match unsigned {
197+
0..=0xFFFFFFFF => Err(Error::DeserializeNonMinimal),
198+
unsigned => Ok(unsigned),
199+
}
200+
}
201+
_ => Err(Error::DeserializeBadU64),
202+
}
203+
}
159204

160205
// fn try_take_varint(&mut self) -> Result<usize> {
161206
// for i in 0..VarintUsize::varint_usize_max() {
@@ -425,7 +470,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
425470
where
426471
V: Visitor<'de>,
427472
{
428-
let raw = self.raw_deserialize_u32(MAJOR_POSINT)?;
473+
let raw = self.raw_deserialize_u64(MAJOR_POSINT)?;
429474
visitor.visit_u64(raw as u64)
430475
}
431476

@@ -831,6 +876,31 @@ mod tests {
831876
}
832877
}
833878

879+
#[test]
880+
fn de_u64() {
881+
let mut buf = [0u8; 64];
882+
883+
let numbers = [
884+
0,
885+
1,
886+
2,
887+
3,
888+
u16::MAX as u64,
889+
u16::MAX as u64 + 1,
890+
u32::MAX as u64,
891+
u32::MAX as u64 + 1,
892+
u64::MAX - 1,
893+
u64::MAX,
894+
];
895+
896+
for number in numbers {
897+
println!("testing {}", number);
898+
let _n = cbor_serialize(&number, &mut buf).unwrap();
899+
let de: u64 = from_bytes(&buf).unwrap();
900+
assert_eq!(de, number);
901+
}
902+
}
903+
834904
#[test]
835905
fn de_i32() {
836906
let mut buf = [0u8; 64];

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ pub enum Error {
4848
DeserializeBadU16,
4949
/// Expected a u32
5050
DeserializeBadU32,
51+
/// Expected a u64
52+
DeserializeBadU64,
5153
/// Expected a NULL marker
5254
DeserializeExpectedNull,
5355
/// Inexistent slice-to-array cast error. Used here to avoid calling unwrap.
@@ -93,6 +95,7 @@ impl Display for Error {
9395
DeserializeBadU8 => "Expected a u8",
9496
DeserializeBadU16 => "Expected a u16",
9597
DeserializeBadU32 => "Expected a u32",
98+
DeserializeBadU64 => "Expected a u64",
9699
DeserializeExpectedNull => "Expected 0xf6",
97100
InexistentSliceToArrayError => "",
98101
DeserializeNonMinimal => "Value may be valid, but not encoded in minimal way",

0 commit comments

Comments
 (0)