From 02e6c04e9fd3ac58d972cfa32d4534bec87a492c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 2 Feb 2017 22:12:07 -0800 Subject: [PATCH] Check for sequence end --- serde/src/de/content.rs | 20 ++++++++++++++++---- serde/src/de/value.rs | 28 ++++++++++++++++------------ test_suite/tests/test_macros.rs | 18 ++++++++++++++++++ 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/serde/src/de/content.rs b/serde/src/de/content.rs index 637c41957..292d6a442 100644 --- a/serde/src/de/content.rs +++ b/serde/src/de/content.rs @@ -537,11 +537,17 @@ impl Deserializer for Content Content::Newtype(v) => visitor.visit_newtype_struct(*v), Content::Seq(v) => { let seq = v.into_iter(); - visitor.visit_seq(de::value::SeqDeserializer::new(seq)) + let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let value = try!(visitor.visit_seq(&mut seq_visitor)); + try!(seq_visitor.end()); + Ok(value) }, Content::Map(v) => { let map = v.into_iter(); - visitor.visit_map(de::value::MapDeserializer::new(map)) + let mut map_visitor = de::value::MapDeserializer::new(map); + let value = try!(visitor.visit_map(&mut map_visitor)); + try!(map_visitor.end()); + Ok(value) }, Content::Bytes(v) => visitor.visit_byte_buf(v), } @@ -611,11 +617,17 @@ impl<'a, E> Deserializer for &'a Content Content::Newtype(ref v) => visitor.visit_newtype_struct(&**v), Content::Seq(ref v) => { let seq = v.into_iter(); - visitor.visit_seq(de::value::SeqDeserializer::new(seq)) + let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let value = try!(visitor.visit_seq(&mut seq_visitor)); + try!(seq_visitor.end()); + Ok(value) }, Content::Map(ref v) => { let map = v.into_iter().map(|&(ref k, ref v)| (k, v)); - visitor.visit_map(de::value::MapDeserializer::new(map)) + let mut map_visitor = de::value::MapDeserializer::new(map); + let value = try!(visitor.visit_map(&mut map_visitor)); + try!(map_visitor.end()); + Ok(value) }, Content::Bytes(ref v) => visitor.visit_bytes(v), } diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 32b69d5ff..85d152678 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -428,7 +428,9 @@ impl SeqDeserializer } } - fn end(&mut self) -> Result<(), E> { + /// Check for remaining elements after passing a `SeqDeserializer` to + /// `Visitor::visit_seq`. + pub fn end(mut self) -> Result<(), E> { let mut remaining = 0; while self.iter.next().is_some() { remaining += 1; @@ -610,17 +612,9 @@ impl MapDeserializer } } - fn next_pair(&mut self) -> Option<(::First, ::Second)> { - match self.iter.next() { - Some(kv) => { - self.count += 1; - Some(private::Pair::split(kv)) - } - None => None, - } - } - - fn end(&mut self) -> Result<(), E> { + /// Check for remaining elements after passing a `MapDeserializer` to + /// `Visitor::visit_map`. + pub fn end(mut self) -> Result<(), E> { let mut remaining = 0; while self.iter.next().is_some() { remaining += 1; @@ -633,6 +627,16 @@ impl MapDeserializer Err(de::Error::invalid_length(self.count + remaining, &ExpectedInMap(self.count))) } } + + fn next_pair(&mut self) -> Option<(::First, ::Second)> { + match self.iter.next() { + Some(kv) => { + self.count += 1; + Some(private::Pair::split(kv)) + } + None => None, + } + } } impl de::Deserializer for MapDeserializer diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index c78f4534c..21185412b 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -725,6 +725,24 @@ fn test_untagged_enum() { ], Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), ); + + assert_de_tokens_error::( + &[ + Token::TupleStart(3), + + Token::TupleSep, + Token::U8(1), + + Token::TupleSep, + Token::U8(2), + + Token::TupleSep, + Token::U8(3), + + Token::TupleEnd, + ], + Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), + ); } #[test]