diff --git a/core/src/ser.rs b/core/src/ser.rs index a9cd8c404..4a4648f09 100644 --- a/core/src/ser.rs +++ b/core/src/ser.rs @@ -184,10 +184,8 @@ pub trait Reader { fn read_i32(&mut self) -> Result<i32, Error>; /// Read a i64 from the underlying Read fn read_i64(&mut self) -> Result<i64, Error>; - /// first before the data bytes. - fn read_vec(&mut self) -> Result<Vec<u8>, Error>; - /// first before the data bytes limited to max bytes. - fn read_limited_vec(&mut self, max: usize) -> Result<Vec<u8>, Error>; + /// Read a u64 len prefix followed by that number of exact bytes. + fn read_bytes_len_prefix(&mut self) -> Result<Vec<u8>, Error>; /// Read a fixed number of bytes from the underlying reader. fn read_fixed_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error>; /// Consumes a byte from the reader, producing an error if it doesn't have @@ -281,16 +279,11 @@ impl<'a> Reader for BinReader<'a> { self.source.read_i64::<BigEndian>().map_err(map_io_err) } /// Read a variable size vector from the underlying Read. Expects a usize - fn read_vec(&mut self) -> Result<Vec<u8>, Error> { + fn read_bytes_len_prefix(&mut self) -> Result<Vec<u8>, Error> { let len = self.read_u64()?; self.read_fixed_bytes(len as usize) } - /// Read limited variable size vector from the underlying Read. Expects a - /// usize - fn read_limited_vec(&mut self, max: usize) -> Result<Vec<u8>, Error> { - let len = cmp::min(max, self.read_u64()? as usize); - self.read_fixed_bytes(len as usize) - } + /// Read a fixed number of bytes. fn read_fixed_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error> { // not reading more than 100k in a single read if length > 100000 { @@ -369,27 +362,30 @@ impl Writeable for RangeProof { impl Readable for RangeProof { fn read(reader: &mut Reader) -> Result<RangeProof, Error> { - let p = reader.read_limited_vec(MAX_PROOF_SIZE)?; - let mut a = [0; MAX_PROOF_SIZE]; - a[..p.len()].clone_from_slice(&p[..]); + let len = reader.read_u64()?; + let max_len = cmp::min(len as usize, MAX_PROOF_SIZE); + let p = reader.read_fixed_bytes(max_len)?; + let mut proof = [0; MAX_PROOF_SIZE]; + proof[..p.len()].clone_from_slice(&p[..]); Ok(RangeProof { - proof: a, - plen: p.len(), + plen: proof.len(), + proof, }) } } impl FixedLength for RangeProof { - const LEN: usize = MAX_PROOF_SIZE + 8; + const LEN: usize = 8 // length prefix + + MAX_PROOF_SIZE; } impl PMMRable for RangeProof {} impl Readable for Signature { fn read(reader: &mut Reader) -> Result<Signature, Error> { - let a = reader.read_fixed_bytes(AGG_SIGNATURE_SIZE)?; - let mut c = [0; AGG_SIGNATURE_SIZE]; - c[..AGG_SIGNATURE_SIZE].clone_from_slice(&a[..AGG_SIGNATURE_SIZE]); + let a = reader.read_fixed_bytes(Signature::LEN)?; + let mut c = [0; Signature::LEN]; + c[..Signature::LEN].clone_from_slice(&a[..Signature::LEN]); Ok(Signature::from_raw_data(&c).unwrap()) } } @@ -400,6 +396,10 @@ impl Writeable for Signature { } } +impl FixedLength for Signature { + const LEN: usize = AGG_SIGNATURE_SIZE; +} + /// Utility wrapper for an underlying byte Writer. Defines higher level methods /// to write numbers, byte vectors, hashes, etc. pub struct BinWriter<'a> { diff --git a/p2p/src/msg.rs b/p2p/src/msg.rs index 7f3ee86e3..7da0ef263 100644 --- a/p2p/src/msg.rs +++ b/p2p/src/msg.rs @@ -362,7 +362,7 @@ impl Readable for Hand { let total_diff = Difficulty::read(reader)?; let sender_addr = SockAddr::read(reader)?; let receiver_addr = SockAddr::read(reader)?; - let ua = reader.read_vec()?; + let ua = reader.read_bytes_len_prefix()?; let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?; let genesis = Hash::read(reader)?; Ok(Hand { @@ -413,7 +413,7 @@ impl Readable for Shake { let (version, capab) = ser_multiread!(reader, read_u32, read_u32); let capabilities = Capabilities::from_bits_truncate(capab); let total_diff = Difficulty::read(reader)?; - let ua = reader.read_vec()?; + let ua = reader.read_bytes_len_prefix()?; let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?; let genesis = Hash::read(reader)?; Ok(Shake { @@ -498,7 +498,8 @@ impl Writeable for PeerError { impl Readable for PeerError { fn read(reader: &mut Reader) -> Result<PeerError, ser::Error> { - let (code, msg) = ser_multiread!(reader, read_u32, read_vec); + let code = reader.read_u32()?; + let msg = reader.read_bytes_len_prefix()?; let message = String::from_utf8(msg).map_err(|_| ser::Error::CorruptedData)?; Ok(PeerError { code: code, diff --git a/p2p/src/store.rs b/p2p/src/store.rs index 6d0d305bd..30016378f 100644 --- a/p2p/src/store.rs +++ b/p2p/src/store.rs @@ -80,8 +80,10 @@ impl Writeable for PeerData { impl Readable for PeerData { fn read(reader: &mut Reader) -> Result<PeerData, ser::Error> { let addr = SockAddr::read(reader)?; - let (capab, ua, fl, lb, br) = - ser_multiread!(reader, read_u32, read_vec, read_u8, read_i64, read_i32); + let capab = reader.read_u32()?; + let ua = reader.read_bytes_len_prefix()?; + let (fl, lb, br) = ser_multiread!(reader, read_u8, read_i64, read_i32); + let lc = reader.read_i64(); // this only works because each PeerData is read in its own vector and this // is the last data element @@ -90,6 +92,7 @@ impl Readable for PeerData { } else { lc.unwrap() }; + let user_agent = String::from_utf8(ua).map_err(|_| ser::Error::CorruptedData)?; let capabilities = Capabilities::from_bits_truncate(capab); let ban_reason = ReasonForBan::from_i32(br).ok_or(ser::Error::CorruptedData)?; diff --git a/wallet/src/libwallet/types.rs b/wallet/src/libwallet/types.rs index 3203fc86c..e00026656 100644 --- a/wallet/src/libwallet/types.rs +++ b/wallet/src/libwallet/types.rs @@ -262,7 +262,7 @@ impl ser::Writeable for OutputData { impl ser::Readable for OutputData { fn read(reader: &mut ser::Reader) -> Result<OutputData, ser::Error> { - let data = reader.read_vec()?; + let data = reader.read_bytes_len_prefix()?; serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) } } @@ -431,7 +431,7 @@ impl ser::Writeable for Context { impl ser::Readable for Context { fn read(reader: &mut ser::Reader) -> Result<Context, ser::Error> { - let data = reader.read_vec()?; + let data = reader.read_bytes_len_prefix()?; serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) } } @@ -615,7 +615,7 @@ impl ser::Writeable for TxLogEntry { impl ser::Readable for TxLogEntry { fn read(reader: &mut ser::Reader) -> Result<TxLogEntry, ser::Error> { - let data = reader.read_vec()?; + let data = reader.read_bytes_len_prefix()?; serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) } } @@ -663,7 +663,7 @@ impl ser::Writeable for AcctPathMapping { impl ser::Readable for AcctPathMapping { fn read(reader: &mut ser::Reader) -> Result<AcctPathMapping, ser::Error> { - let data = reader.read_vec()?; + let data = reader.read_bytes_len_prefix()?; serde_json::from_slice(&data[..]).map_err(|_| ser::Error::CorruptedData) } }