From a4c738a9f326c9177aa1b7f12e1c5c1505ecc6ba Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sun, 19 Feb 2017 14:29:41 +0100 Subject: [PATCH 1/2] Clamp hints coming from untrusted input to 4096 --- serde/src/bytes.rs | 3 ++- serde/src/de/content.rs | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/serde/src/bytes.rs b/serde/src/bytes.rs index 8f914839..e885d3ef 100644 --- a/serde/src/bytes.rs +++ b/serde/src/bytes.rs @@ -114,6 +114,7 @@ impl<'a> ser::Serialize for Bytes<'a> { #[cfg(any(feature = "std", feature = "collections"))] mod bytebuf { + use core::cmp; use core::ops; use core::fmt; use core::fmt::Write; @@ -252,7 +253,7 @@ mod bytebuf { fn visit_seq(self, mut visitor: V) -> Result where V: de::SeqVisitor, { - let (len, _) = visitor.size_hint(); + let len = cmp::min(visitor.size_hint().0, 4096); let mut values = Vec::with_capacity(len); while let Some(value) = try!(visitor.visit()) { diff --git a/serde/src/de/content.rs b/serde/src/de/content.rs index fa8875c8..706bd495 100644 --- a/serde/src/de/content.rs +++ b/serde/src/de/content.rs @@ -10,6 +10,7 @@ #![doc(hidden)] +use core::cmp; use core::fmt; use core::marker::PhantomData; @@ -215,7 +216,7 @@ impl Visitor for ContentVisitor { fn visit_seq(self, mut visitor: V) -> Result where V: SeqVisitor { - let mut vec = Vec::with_capacity(visitor.size_hint().0); + let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(e) = try!(visitor.visit()) { vec.push(e); } @@ -225,7 +226,7 @@ impl Visitor for ContentVisitor { fn visit_map(self, mut visitor: V) -> Result where V: MapVisitor { - let mut vec = Vec::with_capacity(visitor.size_hint().0); + let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(kv) = try!(visitor.visit()) { vec.push(kv); } @@ -489,7 +490,7 @@ impl Visitor for TaggedContentVisitor where V: MapVisitor { let mut tag = None; - let mut vec = Vec::with_capacity(visitor.size_hint().0); + let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(k) = try!(visitor.visit_key_seed(TagOrContentVisitor::new(self.tag_name))) { match k { TagOrContent::Tag => { From 792a5f7502b7dc6d2546fbd860ea2a7c74b46108 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 19 Feb 2017 13:45:23 -0800 Subject: [PATCH 2/2] Also clamp the collection impls --- serde/src/de/impls.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index fa3cd214..c50574de 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -30,6 +30,8 @@ use std::collections::{ #[cfg(feature = "collections")] use collections::borrow::ToOwned; +#[cfg(any(feature = "std", feature = "collections"))] +use core::cmp; use core::fmt; #[cfg(feature = "std")] use core::hash::{Hash, BuildHasher}; @@ -467,7 +469,7 @@ seq_impl!( BinaryHeapVisitor, visitor, BinaryHeap::new(), - BinaryHeap::with_capacity(visitor.size_hint().0), + BinaryHeap::with_capacity(cmp::min(visitor.size_hint().0, 4096)), BinaryHeap::push); #[cfg(any(feature = "std", feature = "collections"))] @@ -495,7 +497,7 @@ seq_impl!( S: BuildHasher + Default>, visitor, HashSet::with_hasher(S::default()), - HashSet::with_capacity_and_hasher(visitor.size_hint().0, S::default()), + HashSet::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default()), HashSet::insert); #[cfg(any(feature = "std", feature = "collections"))] @@ -504,7 +506,7 @@ seq_impl!( VecVisitor, visitor, Vec::new(), - Vec::with_capacity(visitor.size_hint().0), + Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)), Vec::push); #[cfg(any(feature = "std", feature = "collections"))] @@ -513,7 +515,7 @@ seq_impl!( VecDequeVisitor, visitor, VecDeque::new(), - VecDeque::with_capacity(visitor.size_hint().0), + VecDeque::with_capacity(cmp::min(visitor.size_hint().0, 4096)), VecDeque::push_back); /////////////////////////////////////////////////////////////////////////////// @@ -791,7 +793,7 @@ map_impl!( S: BuildHasher + Default>, visitor, HashMap::with_hasher(S::default()), - HashMap::with_capacity_and_hasher(visitor.size_hint().0, S::default())); + HashMap::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default())); ///////////////////////////////////////////////////////////////////////////////