From e0ac75e81ff0c7882bce333aa8d52ecfc38ddeb7 Mon Sep 17 00:00:00 2001 From: Matt Bilker Date: Sun, 8 Jul 2018 18:42:49 -0400 Subject: [PATCH] ser(tuple): check types of sub-elements to only permit single sub-type tuples --- src/ser/tuple.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/ser/tuple.rs b/src/ser/tuple.rs index 223a9be..4daf92f 100644 --- a/src/ser/tuple.rs +++ b/src/ser/tuple.rs @@ -12,7 +12,7 @@ pub struct Tuple<'a> { ser: &'a mut Serializer, size_index: u64, - node_type: StandardType, + node_type: Option, len: usize, } @@ -22,23 +22,21 @@ impl<'a> Tuple<'a> { ser.write_mode = WriteMode::Array; - let size_index = ser.data_buf.position(); - // Estimate u32 for the total size of the tuple - debug!("big endian length: {:02x?}", u32::to_bytes(u32::to_be(len as u32))); + let size_index = ser.data_buf.position(); ser.data_buf.write_u32::(len as u32).expect("Unable to write size placeholder"); Self { ser, size_index, - node_type: StandardType::String, + node_type: None, len, } } fn find_standard_type(&self) -> StandardType { debug!("find_standard_type => len: {}", self.len); - self.node_type + self.node_type.unwrap_or(StandardType::String) } } @@ -53,7 +51,15 @@ impl<'a> SerializeTuple for Tuple<'a> { let hint = value.serialize(&mut *self.ser)?.ok_or(KbinErrorKind::MissingTypeHint)?; debug!("SerializeTuple: serialize_element, hint: {:?}", hint); - self.node_type = hint.node_type; + // Rust tuple types can have different types per element, this is not + // permitted by kbin + if let Some(node_type) = self.node_type { + if node_type != hint.node_type { + return Err(KbinErrorKind::TypeMismatch(*node_type, *hint.node_type).into()); + } + } else { + self.node_type = Some(hint.node_type); + } Ok(()) } @@ -71,15 +77,12 @@ impl<'a> SerializeTuple for Tuple<'a> { if size as usize != self.len { debug!("SerializeTuple: end, size correction: {}", size); - let old_pos = self.ser.data_buf.position(); + let current_pos = self.ser.data_buf.position(); self.ser.data_buf.seek(SeekFrom::Start(self.size_index)).context(KbinErrorKind::Seek)?; self.ser.data_buf.write_u32::(size).context(KbinErrorKind::DataWrite("node size"))?; - self.ser.data_buf.seek(SeekFrom::Start(old_pos)).context(KbinErrorKind::Seek)?; + self.ser.data_buf.seek(SeekFrom::Start(current_pos)).context(KbinErrorKind::Seek)?; } - // Taken care of by `SerializerStruct` - //self.ser.node_buf.write_u8(StandardType::NodeEnd.id | ARRAY_MASK).context(KbinErrorKind::DataWrite("node end"))?; - Ok(Some(TypeHint { node_type, is_array: true, count: self.len })) } }