Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
node: Test that message encoding doesn't panic
cloudhead committed 2 years ago
commit bea86871de949712d12ae14d993a76e56403ad14
parent e71f07e592823faf289a3c13c4b6143d13146de3
2 files changed +62 -4
modified radicle-node/src/wire.rs
@@ -82,12 +82,17 @@ pub trait Decode: Sized {
    fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, Error>;
}

-
/// Encode an object into a vector.
+
/// Encode an object into a byte vector.
+
///
+
/// # Panics
+
///
+
/// If the encoded object exceeds [`Size::MAX`].
pub fn serialize<T: Encode + ?Sized>(data: &T) -> Vec<u8> {
    let mut buffer = Vec::new();
-
    let len = data
-
        .encode(&mut buffer)
-
        .expect("in-memory writes don't error");
+
    // SAFETY: We expect this to panic if the user passes
+
    // in data that exceeds the maximum allowed size.
+
    #[allow(clippy::unwrap_used)]
+
    let len = data.encode(&mut buffer).unwrap();

    debug_assert_eq!(len, buffer.len());

modified radicle-node/src/wire/message.rs
@@ -371,11 +371,64 @@ impl wire::Decode for ZeroBytes {
mod tests {
    use super::*;
    use qcheck_macros::quickcheck;
+
    use radicle::storage::refs::RefsAt;
+
    use radicle_crypto::test::signer::MockSigner;

    use crate::deserializer::Deserializer;
+
    use crate::test::arbitrary;
    use crate::wire::{self, Encode};

    #[test]
+
    fn test_refs_ann_max_size() {
+
        let signer = MockSigner::default();
+
        let refs: [RefsAt; REF_REMOTE_LIMIT] = arbitrary::gen(1);
+
        let ann = AnnouncementMessage::Refs(RefsAnnouncement {
+
            rid: arbitrary::gen(1),
+
            refs: BoundedVec::collect_from(&mut refs.into_iter()),
+
            timestamp: arbitrary::gen(1),
+
        });
+
        let ann = ann.signed(&signer);
+
        let msg = Message::Announcement(ann);
+
        let data = wire::serialize(&msg);
+

+
        assert!(data.len() < wire::Size::MAX as usize);
+
    }
+

+
    #[test]
+
    fn test_inv_ann_max_size() {
+
        let signer = MockSigner::default();
+
        let inv: [Id; INVENTORY_LIMIT] = arbitrary::gen(1);
+
        let ann = AnnouncementMessage::Inventory(InventoryAnnouncement {
+
            inventory: BoundedVec::collect_from(&mut inv.into_iter()),
+
            timestamp: arbitrary::gen(1),
+
        });
+
        let ann = ann.signed(&signer);
+
        let msg = Message::Announcement(ann);
+
        let data = wire::serialize(&msg);
+

+
        assert!(data.len() < wire::Size::MAX as usize);
+
    }
+

+
    #[test]
+
    fn test_node_ann_max_size() {
+
        let signer = MockSigner::default();
+
        let addrs: [Address; ADDRESS_LIMIT] = arbitrary::gen(1);
+
        let alias = ['@'; radicle::node::MAX_ALIAS_LENGTH];
+
        let ann = AnnouncementMessage::Node(NodeAnnouncement {
+
            features: Default::default(),
+
            alias: radicle::node::Alias::new(String::from_iter(alias)),
+
            addresses: BoundedVec::collect_from(&mut addrs.into_iter()),
+
            timestamp: arbitrary::gen(1),
+
            nonce: u64::MAX,
+
        });
+
        let ann = ann.signed(&signer);
+
        let msg = Message::Announcement(ann);
+
        let data = wire::serialize(&msg);
+

+
        assert!(data.len() < wire::Size::MAX as usize);
+
    }
+

+
    #[test]
    fn test_pingpong_encode_max_size() {
        let mut buf = Vec::new();