Reimplement decode_len() with ShortU16 vistor helper

This commit is contained in:
Trent Nelson 2020-08-13 22:20:22 -06:00 committed by Trent Nelson
parent 6222fbcc66
commit 30dbe257cf
2 changed files with 18 additions and 7 deletions

View File

@ -131,7 +131,8 @@ fn do_get_packet_offsets(
} }
// read the length of Transaction.signatures (serialized with short_vec) // read the length of Transaction.signatures (serialized with short_vec)
let (sig_len_untrusted, sig_size) = decode_len(&packet.data)?; let (sig_len_untrusted, sig_size) =
decode_len(&packet.data).map_err(|_| PacketError::InvalidShortVec)?;
// Using msg_start_offset which is based on sig_len_untrusted introduces uncertainty. // Using msg_start_offset which is based on sig_len_untrusted introduces uncertainty.
// Ultimately, the actual sigverify will determine the uncertainty. // Ultimately, the actual sigverify will determine the uncertainty.
@ -156,8 +157,8 @@ fn do_get_packet_offsets(
} }
// read the length of Message.account_keys (serialized with short_vec) // read the length of Message.account_keys (serialized with short_vec)
let (pubkey_len, pubkey_len_size) = let (pubkey_len, pubkey_len_size) = decode_len(&packet.data[message_account_keys_len_offset..])
decode_len(&packet.data[message_account_keys_len_offset..])?; .map_err(|_| PacketError::InvalidShortVec)?;
if (message_account_keys_len_offset + pubkey_len * size_of::<Pubkey>() + pubkey_len_size) if (message_account_keys_len_offset + pubkey_len * size_of::<Pubkey>() + pubkey_len_size)
> packet.meta.size > packet.meta.size

View File

@ -199,10 +199,20 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for ShortVec<T> {
} }
/// Return the decoded value and how many bytes it consumed. /// Return the decoded value and how many bytes it consumed.
pub fn decode_len(bytes: &[u8]) -> Result<(usize, usize), Box<bincode::ErrorKind>> { pub fn decode_len(bytes: &[u8]) -> Result<(usize, usize), ()> {
let short_len: ShortU16 = bincode::deserialize(bytes)?; let mut len = 0;
let num_bytes = bincode::serialized_size(&short_len)?; let mut size = 0;
Ok((short_len.0 as usize, num_bytes as usize)) for byte in bytes.iter() {
match visit_byte(*byte, len, size) {
VisitResult::More(l, s) => {
len = l;
size = s;
}
VisitResult::Done(len, size) => return Ok((len, size)),
VisitResult::Err => return Err(()),
}
}
Err(())
} }
#[cfg(test)] #[cfg(test)]