From 4543a256393bcf721e7b08c632eb46d5b13cb014 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 29 Jun 2022 18:58:00 -0300 Subject: [PATCH] fix(network messages): add limits to rejection message and reason (#4687) * add limits to rejection message and reason * truncate bytes instead of characters * change `MAX_REJECT_REASON_LENGTH` to match zcashd * clippy * avoid panix in the slice * Escape and truncate error messages Co-authored-by: teor --- .../src/protocol/external/message.rs | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/zebra-network/src/protocol/external/message.rs b/zebra-network/src/protocol/external/message.rs index 743212b4194..a4681cfddfa 100644 --- a/zebra-network/src/protocol/external/message.rs +++ b/zebra-network/src/protocol/external/message.rs @@ -340,25 +340,47 @@ pub enum Message { FilterClear, } +/// The maximum size of the rejection message. +/// +/// This is equivalent to `COMMAND_SIZE` in zcashd. +const MAX_REJECT_MESSAGE_LENGTH: usize = 12; + +/// The maximum size of the rejection reason. +/// +/// This is equivalent to `MAX_REJECT_MESSAGE_LENGTH` in zcashd. +const MAX_REJECT_REASON_LENGTH: usize = 111; + +// TODO: add tests for Error conversion and Reject message serialization (#4633) +// (Zebra does not currently send reject messages, and it ignores received reject messages.) impl From for Message where E: Error, { fn from(e: E) -> Self { + let message = e + .to_string() + .escape_default() + .take(MAX_REJECT_MESSAGE_LENGTH) + .collect(); + let reason = e + .source() + .map(ToString::to_string) + .unwrap_or_default() + .escape_default() + .take(MAX_REJECT_REASON_LENGTH) + .collect(); + Message::Reject { - message: e.to_string(), + message, // The generic case, impls for specific error types should // use specific varieties of `RejectReason`. ccode: RejectReason::Other, - reason: if let Some(reason) = e.source() { - reason.to_string() - } else { - String::from("") - }, + reason, - // Allow this to be overridden but not populated by default, methinks. + // The hash of the rejected block or transaction. + // We don't have that data here, so the caller needs to fill it in later. data: None, } }