protocol: Fix panic when serializing large frames
In 3c5668edd2 I mistakenly moved the check
the length of an encoded `wire::Message` from its `impl wire::Encode` to
the `fn serialize`, so that it would not apply only to messages (as
originally intended), but to *any* argument of `serialize`.
This is not a problem for gossip messages, but catastrophic for Git
streams, which tend to send a lot of data.
The fix is simple: Move the check back into `impl Encode for Message`.
This commit is contained in:
parent
c5b99db101
commit
a8426dfdac
|
|
@ -103,14 +103,10 @@ pub trait Decode: Sized {
|
|||
}
|
||||
|
||||
/// Encode an object into a byte vector.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If the encoded object exceeds [`Size::MAX`].
|
||||
pub fn serialize<E: Encode + ?Sized>(data: &E) -> Vec<u8> {
|
||||
let mut buffer = Vec::new().limit(Size::MAX as usize);
|
||||
let mut buffer = Vec::new();
|
||||
data.encode(&mut buffer);
|
||||
buffer.into_inner()
|
||||
buffer
|
||||
}
|
||||
|
||||
/// Decode an object from a slice.
|
||||
|
|
|
|||
|
|
@ -390,4 +390,25 @@ mod test {
|
|||
assert_eq!(StreamId::control(Link::Inbound), StreamId(VarInt(0b001)));
|
||||
assert_eq!(StreamId::gossip(Link::Inbound), StreamId(VarInt(0b011)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_git_large() {
|
||||
let size = u16::MAX as usize * 3;
|
||||
assert!(
|
||||
size > (wire::Size::MAX as usize * 2),
|
||||
"we want to test sizes that are way larger than any gossip message"
|
||||
);
|
||||
|
||||
let a_lot_of_data = vec![0u8; size];
|
||||
|
||||
let frame: Frame<Message> = Frame::git(StreamId(0u8.into()), a_lot_of_data);
|
||||
|
||||
// In previous versions since 3c5668e this would panic.
|
||||
let bytes = wire::serialize(&frame);
|
||||
|
||||
assert!(
|
||||
bytes.len() > wire::Size::MAX as usize * 2,
|
||||
"just making sure that whatever was encoded is still quite large"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ impl wire::Decode for Info {
|
|||
|
||||
impl wire::Encode for Message {
|
||||
fn encode(&self, buf: &mut impl BufMut) {
|
||||
let buf = &mut buf.limit(wire::Size::MAX as usize);
|
||||
|
||||
self.type_id().encode(buf);
|
||||
|
||||
match self {
|
||||
|
|
|
|||
Loading…
Reference in New Issue