Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Count bytes read in encoding #594

Merged
merged 1 commit into from May 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/blockdata/transaction.rs
Expand Up @@ -34,6 +34,7 @@ use blockdata::constants::WITNESS_SCALE_FACTOR;
#[cfg(feature="bitcoinconsensus")] use blockdata::script;
use blockdata::script::Script;
use consensus::{encode, Decodable, Encodable};
use consensus::encode::MAX_VEC_SIZE;
use hash_types::{SigHash, Txid, Wtxid};
use VarInt;

Expand Down Expand Up @@ -566,7 +567,8 @@ impl Encodable for Transaction {
}

impl Decodable for Transaction {
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
let mut d = d.take(MAX_VEC_SIZE as u64);
let version = i32::consensus_decode(&mut d)?;
let input = Vec::<TxIn>::consensus_decode(&mut d)?;
// segwit
Expand Down
10 changes: 10 additions & 0 deletions src/consensus/encode.rs
Expand Up @@ -575,6 +575,7 @@ macro_rules! impl_vec {
return Err(self::Error::OversizedVectorAllocation { requested: byte_size, max: MAX_VEC_SIZE })
}
let mut ret = Vec::with_capacity(len as usize);
let mut d = d.take(MAX_VEC_SIZE as u64);
for _ in 0..len {
ret.push(Decodable::consensus_decode(&mut d)?);
}
Expand Down Expand Up @@ -997,6 +998,15 @@ mod tests {
assert_eq!(cd.ok(), Some(CheckedData(vec![1u8, 2, 3, 4, 5])));
}

#[test]
fn limit_read_test() {
let witness = vec![vec![0u8; 3_999_999]; 2];
let ser = serialize(&witness);
let mut reader = io::Cursor::new(ser);
let err = Vec::<Vec<u8>>::consensus_decode(&mut reader);
assert!(err.is_err());
}

#[test]
fn serialization_round_trips() {
macro_rules! round_trip {
Expand Down
3 changes: 2 additions & 1 deletion src/internal_macros.rs
Expand Up @@ -33,8 +33,9 @@ macro_rules! impl_consensus_encoding {
impl $crate::consensus::Decodable for $thing {
#[inline]
fn consensus_decode<D: ::std::io::Read>(
mut d: D,
d: D,
) -> Result<$thing, $crate::consensus::encode::Error> {
let mut d = d.take($crate::consensus::encode::MAX_VEC_SIZE as u64);
Ok($thing {
$($field: $crate::consensus::Decodable::consensus_decode(&mut d)?),+
})
Expand Down
3 changes: 1 addition & 2 deletions src/network/message.rs
Expand Up @@ -29,9 +29,8 @@ use network::address::{Address, AddrV2Message};
use network::message_network;
use network::message_blockdata;
use network::message_filter;
use consensus::encode::{CheckedData, Decodable, Encodable, VarInt};
use consensus::encode::{CheckedData, Decodable, Encodable, VarInt, MAX_VEC_SIZE};
use consensus::{encode, serialize};
use consensus::encode::MAX_VEC_SIZE;

/// The maximum number of [Inventory] items in an `inv` message.
///
Expand Down
5 changes: 3 additions & 2 deletions src/util/psbt/map/global.rs
Expand Up @@ -19,6 +19,7 @@ use std::cmp;

use blockdata::transaction::Transaction;
use consensus::{encode, Encodable, Decodable};
use consensus::encode::MAX_VEC_SIZE;
use util::psbt::map::Map;
use util::psbt::raw;
use util::psbt;
Expand Down Expand Up @@ -228,8 +229,8 @@ impl Map for Global {
impl_psbtmap_consensus_encoding!(Global);

impl Decodable for Global {
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {

fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
let mut d = d.take(MAX_VEC_SIZE as u64);
let mut tx: Option<Transaction> = None;
let mut version: Option<u32> = None;
let mut unknowns: BTreeMap<raw::Key, Vec<u8>> = Default::default();
Expand Down
4 changes: 3 additions & 1 deletion src/util/psbt/mod.rs
Expand Up @@ -21,6 +21,7 @@
use blockdata::script::Script;
use blockdata::transaction::Transaction;
use consensus::{encode, Encodable, Decodable};
use consensus::encode::MAX_VEC_SIZE;

use std::io;

Expand Down Expand Up @@ -162,7 +163,8 @@ impl Encodable for PartiallySignedTransaction {
}

impl Decodable for PartiallySignedTransaction {
fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
let mut d = d.take(MAX_VEC_SIZE as u64);
let magic: [u8; 4] = Decodable::consensus_decode(&mut d)?;

if *b"psbt" != magic {
Expand Down