diff --git a/Cargo.toml b/Cargo.toml index a6a0ccc6ea..4095cd4dfa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bitcoin" -version = "0.9.0" +version = "0.9.1" authors = ["Andrew Poelstra "] license = "CC0-1.0" homepage = "https://github.com/apoelstra/rust-bitcoin/" diff --git a/src/network/encodable.rs b/src/network/encodable.rs index 3453bef645..8f1c4df4a8 100644 --- a/src/network/encodable.rs +++ b/src/network/encodable.rs @@ -31,11 +31,14 @@ use std::collections::HashMap; use std::hash::Hash; -use std::u32; +use std::{mem, u32}; use util::hash::Sha256dHash; use network::serialize::{SimpleDecoder, SimpleEncoder}; +/// Maximum size, in bytes, of a vector we are allowed to decode +pub const MAX_VEC_SIZE: usize = 32 * 1024 * 1024; + /// Data which can be encoded in a consensus-consistent way pub trait ConsensusEncodable { /// Encode an object with a well-defined format @@ -185,6 +188,10 @@ impl> ConsensusDecodable for Vec Result, D::Error> { let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); + let byte_size = len as usize * mem::size_of::(); + if byte_size > MAX_VEC_SIZE { + return Err(d.error(format!("tried to allocate vec of size {} (max {})", byte_size, MAX_VEC_SIZE))); + } let mut ret = Vec::with_capacity(len as usize); for _ in 0..len { ret.push(try!(ConsensusDecodable::consensus_decode(d))); } Ok(ret)