From 46cd0e4a9f8add9119299b3b8b6a4fa009919a8e Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 5 Aug 2021 16:57:17 +0100 Subject: [PATCH] from_buffer(): Implemented. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for rsh's current commit: Great blessing − 大吉 --- src/message/binary.rs | 70 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/src/message/binary.rs b/src/message/binary.rs index 7b5ea05..5ab9137 100644 --- a/src/message/binary.rs +++ b/src/message/binary.rs @@ -73,9 +73,75 @@ impl SerializedMessage /// /// # Panics /// If `bytes` does not contain enough data to read. - pub fn from_buffer(bytes: impl Buf) -> eyre::Result + pub fn from_buffer(mut bytes: impl Buf) -> eyre::Result { - todo!() + macro_rules! read { + ($bref:expr) => { + { + let by: &mut [u8] = ($bref).as_mut(); + bytes.copy_to_slice(by); + } + }; + (? $odef:expr) => { + { + let by = bytes.get_u8(); + match by { + 0 => None, + 1 => { + let mut def = $odef; + read!(&mut def); + Some(def) + }, + x => { + return Err(eyre!("Invalid optional-set bit: {}", x)); + } + } + } + }; + (: $ser:ty) => { + { + let len = usize::try_from(bytes.get_u64())?; + if len > MAX_ALLOC_SIZE { + return Err(eyre!("Invalid length read: {}", len) + .with_section(|| format!("Max length read: {}", MAX_ALLOC_SIZE))) + } + alloc_local_bytes(len, |de| { + read!(&mut de[..]); + serde_cbor::from_slice::<$ser>(&de[..]).wrap_err(eyre!("Failed to deserialise {} from reader", std::any::type_name::<$ser>())) + })? + + } + }; + ($into:expr, $num:expr) => { + { + let num = $num; + let reader = (&mut bytes).reader(); + copy_buffer($into, reader, num).wrap_err(eyre!("Failed to read {} bytes from reader", num))? + } + } + } + + let header = read!(: SerHeader); + let data_len = usize::try_from(bytes.get_u64())?; + let mut data = Vec::with_capacity(std::cmp::min(data_len, MAX_ALLOC_SIZE)); //XXX: Redesign so we don't allocate OR try to read massive buffers by accident on corrupted/malformed messages + read!(&mut data, data_len); + if data.len()!=data_len { + return Err(eyre!("Failed to read {} bytes from buffer (got {})", data_len, data.len())); + } + let mut hash = sha256::Sha256Hash::default(); + read!(&mut hash); + let enc_key: Option<[u8; RSA_BLOCK_SIZE]> = read!(? [0u8; RSA_BLOCK_SIZE]); + let sig: Option = read!(? rsa::Signature::default()); + + Ok(Self { + header, + data, + hash, + enc_key, + sig, + + _phantom: PhantomData, + }) } /// Create from a slice of bytes