diff --git a/generator/src/generator/namespace.rs b/generator/src/generator/namespace.rs index c54f9966..b74cbbaf 100644 --- a/generator/src/generator/namespace.rs +++ b/generator/src/generator/namespace.rs @@ -2560,6 +2560,22 @@ impl<'ns, 'c> NamespaceGenerator<'ns, 'c> { if parse_size_constraint != StructSizeConstraint::None { outln!(out, "let remaining = initial_value;"); } + // Get the minimum size that this struct can have + let mut minimum_size: u32 = fields.iter() + .map(|field| field.size().unwrap_or(0)) + .sum(); + if let Some(size) = match parse_size_constraint { + StructSizeConstraint::None => None, + StructSizeConstraint::Fixed(size) => Some(size), + StructSizeConstraint::EmbeddedLength { minimum } => Some(minimum), + } { + minimum_size = minimum_size.max(size.into()); + } + outln!(out, "// Check that enough bytes for the minimum possible size is available."); + outln!(out, "// This allows the compiler to optimise away some length checks."); + outln!(out, "if remaining.len() < {} {{", minimum_size); + outln!(out.indent(), "return Err(ParseError::ParseError);"); + outln!(out, "}}"); Self::emit_let_value_for_dynamic_align(fields, out); for field in fields.iter() { self.emit_field_parse( diff --git a/src/protocol/bigreq.rs b/src/protocol/bigreq.rs index 6a5d0db2..6beb37fe 100644 --- a/src/protocol/bigreq.rs +++ b/src/protocol/bigreq.rs @@ -91,6 +91,11 @@ pub struct EnableReply { impl TryParse for EnableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/composite.rs b/src/protocol/composite.rs index 4f5edd0d..6a67fbaa 100644 --- a/src/protocol/composite.rs +++ b/src/protocol/composite.rs @@ -184,6 +184,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -692,6 +697,11 @@ pub struct GetOverlayWindowReply { impl TryParse for GetOverlayWindowReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/damage.rs b/src/protocol/damage.rs index 147b8ab3..95578043 100644 --- a/src/protocol/damage.rs +++ b/src/protocol/damage.rs @@ -116,6 +116,11 @@ pub struct BadDamageError { impl TryParse for BadDamageError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -261,6 +266,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -588,6 +598,11 @@ pub struct NotifyEvent { impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (level, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/dpms.rs b/src/protocol/dpms.rs index 145a0183..13c86a85 100644 --- a/src/protocol/dpms.rs +++ b/src/protocol/dpms.rs @@ -108,6 +108,11 @@ pub struct GetVersionReply { impl TryParse for GetVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -188,6 +193,11 @@ pub struct CapableReply { impl TryParse for CapableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -270,6 +280,11 @@ pub struct GetTimeoutsReply { impl TryParse for GetTimeoutsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -650,6 +665,11 @@ pub struct InfoReply { impl TryParse for InfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/dri2.rs b/src/protocol/dri2.rs index cf4dff24..6745fdb0 100644 --- a/src/protocol/dri2.rs +++ b/src/protocol/dri2.rs @@ -270,6 +270,11 @@ pub struct DRI2Buffer { } impl TryParse for DRI2Buffer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 20 { + return Err(ParseError::ParseError); + } let (attachment, remaining) = u32::try_parse(remaining)?; let (name, remaining) = u32::try_parse(remaining)?; let (pitch, remaining) = u32::try_parse(remaining)?; @@ -334,6 +339,11 @@ pub struct AttachFormat { } impl TryParse for AttachFormat { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (attachment, remaining) = u32::try_parse(remaining)?; let (format, remaining) = u32::try_parse(remaining)?; let attachment = attachment.try_into()?; @@ -448,6 +458,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -551,6 +566,11 @@ pub struct ConnectReply { impl TryParse for ConnectReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -686,6 +706,11 @@ pub struct AuthenticateReply { impl TryParse for AuthenticateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -928,6 +953,11 @@ pub struct GetBuffersReply { impl TryParse for GetBuffersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1063,6 +1093,11 @@ pub struct CopyRegionReply { impl TryParse for CopyRegionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1186,6 +1221,11 @@ pub struct GetBuffersWithFormatReply { impl TryParse for GetBuffersWithFormatReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1350,6 +1390,11 @@ pub struct SwapBuffersReply { impl TryParse for SwapBuffersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1446,6 +1491,11 @@ pub struct GetMSCReply { impl TryParse for GetMSCReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1600,6 +1650,11 @@ pub struct WaitMSCReply { impl TryParse for WaitMSCReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1718,6 +1773,11 @@ pub struct WaitSBCReply { impl TryParse for WaitSBCReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1892,6 +1952,11 @@ pub struct GetParamReply { impl TryParse for GetParamReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (is_param_recognized, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1932,6 +1997,11 @@ pub struct BufferSwapCompleteEvent { impl TryParse for BufferSwapCompleteEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2021,6 +2091,11 @@ pub struct InvalidateBuffersEvent { impl TryParse for InvalidateBuffersEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/dri3.rs b/src/protocol/dri3.rs index 01a9a37f..becefaf1 100644 --- a/src/protocol/dri3.rs +++ b/src/protocol/dri3.rs @@ -113,6 +113,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -214,6 +219,11 @@ pub struct OpenReply { impl TryParseFd for OpenReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -431,6 +441,11 @@ pub struct BufferFromPixmapReply { impl TryParseFd for BufferFromPixmapReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -625,6 +640,11 @@ pub struct FDFromFenceReply { impl TryParseFd for FDFromFenceReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -734,6 +754,11 @@ pub struct GetSupportedModifiersReply { impl TryParse for GetSupportedModifiersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1060,6 +1085,11 @@ pub struct BuffersFromPixmapReply { impl TryParseFd for BuffersFromPixmapReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/ge.rs b/src/protocol/ge.rs index dfb65bd2..59ece9a0 100644 --- a/src/protocol/ge.rs +++ b/src/protocol/ge.rs @@ -108,6 +108,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/glx.rs b/src/protocol/glx.rs index 7e7b9198..51ffe111 100644 --- a/src/protocol/glx.rs +++ b/src/protocol/glx.rs @@ -66,6 +66,11 @@ pub struct GenericError { impl TryParse for GenericError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -215,6 +220,11 @@ pub struct PbufferClobberEvent { impl TryParse for PbufferClobberEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -315,6 +325,11 @@ pub struct BufferSwapCompleteEvent { impl TryParse for BufferSwapCompleteEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -894,6 +909,11 @@ pub struct MakeCurrentReply { impl TryParse for MakeCurrentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -985,6 +1005,11 @@ pub struct IsDirectReply { impl TryParse for IsDirectReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1086,6 +1111,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1720,6 +1750,11 @@ pub struct GetVisualConfigsReply { impl TryParse for GetVisualConfigsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1995,6 +2030,11 @@ pub struct VendorPrivateWithReplyReply { impl TryParse for VendorPrivateWithReplyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2105,6 +2145,11 @@ pub struct QueryExtensionsStringReply { impl TryParse for QueryExtensionsStringReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2206,6 +2251,11 @@ pub struct QueryServerStringReply { impl TryParse for QueryServerStringReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2406,6 +2456,11 @@ pub struct GetFBConfigsReply { impl TryParse for GetFBConfigsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2790,6 +2845,11 @@ pub struct QueryContextReply { impl TryParse for QueryContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2925,6 +2985,11 @@ pub struct MakeContextCurrentReply { impl TryParse for MakeContextCurrentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3177,6 +3242,11 @@ pub struct GetDrawableAttributesReply { impl TryParse for GetDrawableAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4119,6 +4189,11 @@ pub struct GenListsReply { impl TryParse for GenListsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4365,6 +4440,11 @@ pub struct RenderModeReply { impl TryParse for RenderModeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4523,6 +4603,11 @@ pub struct FinishReply { impl TryParse for FinishReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4833,6 +4918,11 @@ pub struct ReadPixelsReply { impl TryParse for ReadPixelsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4951,6 +5041,11 @@ pub struct GetBooleanvReply { impl TryParse for GetBooleanvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5068,6 +5163,11 @@ pub struct GetClipPlaneReply { impl TryParse for GetClipPlaneReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5185,6 +5285,11 @@ pub struct GetDoublevReply { impl TryParse for GetDoublevReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5294,6 +5399,11 @@ pub struct GetErrorReply { impl TryParse for GetErrorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5394,6 +5504,11 @@ pub struct GetFloatvReply { impl TryParse for GetFloatvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5513,6 +5628,11 @@ pub struct GetIntegervReply { impl TryParse for GetIntegervReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5641,6 +5761,11 @@ pub struct GetLightfvReply { impl TryParse for GetLightfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5769,6 +5894,11 @@ pub struct GetLightivReply { impl TryParse for GetLightivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5897,6 +6027,11 @@ pub struct GetMapdvReply { impl TryParse for GetMapdvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6025,6 +6160,11 @@ pub struct GetMapfvReply { impl TryParse for GetMapfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6153,6 +6293,11 @@ pub struct GetMapivReply { impl TryParse for GetMapivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6281,6 +6426,11 @@ pub struct GetMaterialfvReply { impl TryParse for GetMaterialfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6409,6 +6559,11 @@ pub struct GetMaterialivReply { impl TryParse for GetMaterialivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6528,6 +6683,11 @@ pub struct GetPixelMapfvReply { impl TryParse for GetPixelMapfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6647,6 +6807,11 @@ pub struct GetPixelMapuivReply { impl TryParse for GetPixelMapuivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6766,6 +6931,11 @@ pub struct GetPixelMapusvReply { impl TryParse for GetPixelMapusvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 34 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6883,6 +7053,11 @@ pub struct GetPolygonStippleReply { impl TryParse for GetPolygonStippleReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7000,6 +7175,11 @@ pub struct GetStringReply { impl TryParse for GetStringReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7128,6 +7308,11 @@ pub struct GetTexEnvfvReply { impl TryParse for GetTexEnvfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7256,6 +7441,11 @@ pub struct GetTexEnvivReply { impl TryParse for GetTexEnvivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7384,6 +7574,11 @@ pub struct GetTexGendvReply { impl TryParse for GetTexGendvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7512,6 +7707,11 @@ pub struct GetTexGenfvReply { impl TryParse for GetTexGenfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7640,6 +7840,11 @@ pub struct GetTexGenivReply { impl TryParse for GetTexGenivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7796,6 +8001,11 @@ pub struct GetTexImageReply { impl TryParse for GetTexImageReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7927,6 +8137,11 @@ pub struct GetTexParameterfvReply { impl TryParse for GetTexParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8055,6 +8270,11 @@ pub struct GetTexParameterivReply { impl TryParse for GetTexParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8192,6 +8412,11 @@ pub struct GetTexLevelParameterfvReply { impl TryParse for GetTexLevelParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8329,6 +8554,11 @@ pub struct GetTexLevelParameterivReply { impl TryParse for GetTexLevelParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8447,6 +8677,11 @@ pub struct IsEnabledReply { impl TryParse for IsEnabledReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8546,6 +8781,11 @@ pub struct IsListReply { impl TryParse for IsListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8717,6 +8957,11 @@ pub struct AreTexturesResidentReply { impl TryParse for AreTexturesResidentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8914,6 +9159,11 @@ pub struct GenTexturesReply { impl TryParse for GenTexturesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9029,6 +9279,11 @@ pub struct IsTextureReply { impl TryParse for IsTextureReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9155,6 +9410,11 @@ pub struct GetColorTableReply { impl TryParse for GetColorTableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9284,6 +9544,11 @@ pub struct GetColorTableParameterfvReply { impl TryParse for GetColorTableParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9412,6 +9677,11 @@ pub struct GetColorTableParameterivReply { impl TryParse for GetColorTableParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9558,6 +9828,11 @@ pub struct GetConvolutionFilterReply { impl TryParse for GetConvolutionFilterReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9688,6 +9963,11 @@ pub struct GetConvolutionParameterfvReply { impl TryParse for GetConvolutionParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9816,6 +10096,11 @@ pub struct GetConvolutionParameterivReply { impl TryParse for GetConvolutionParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9962,6 +10247,11 @@ pub struct GetSeparableFilterReply { impl TryParse for GetSeparableFilterReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10114,6 +10404,11 @@ pub struct GetHistogramReply { impl TryParse for GetHistogramReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10243,6 +10538,11 @@ pub struct GetHistogramParameterfvReply { impl TryParse for GetHistogramParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10371,6 +10671,11 @@ pub struct GetHistogramParameterivReply { impl TryParse for GetHistogramParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10520,6 +10825,11 @@ pub struct GetMinmaxReply { impl TryParse for GetMinmaxReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10647,6 +10957,11 @@ pub struct GetMinmaxParameterfvReply { impl TryParse for GetMinmaxParameterfvReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10775,6 +11090,11 @@ pub struct GetMinmaxParameterivReply { impl TryParse for GetMinmaxParameterivReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10902,6 +11222,11 @@ pub struct GetCompressedTexImageARBReply { impl TryParse for GetCompressedTexImageARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11101,6 +11426,11 @@ pub struct GenQueriesARBReply { impl TryParse for GenQueriesARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11216,6 +11546,11 @@ pub struct IsQueryARBReply { impl TryParse for IsQueryARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11325,6 +11660,11 @@ pub struct GetQueryivARBReply { impl TryParse for GetQueryivARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11453,6 +11793,11 @@ pub struct GetQueryObjectivARBReply { impl TryParse for GetQueryObjectivARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11581,6 +11926,11 @@ pub struct GetQueryObjectuivARBReply { impl TryParse for GetQueryObjectuivARBReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/present.rs b/src/protocol/present.rs index a2453b70..c0ab8771 100644 --- a/src/protocol/present.rs +++ b/src/protocol/present.rs @@ -466,6 +466,11 @@ pub struct Notify { } impl TryParse for Notify { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (window, remaining) = xproto::Window::try_parse(remaining)?; let (serial, remaining) = u32::try_parse(remaining)?; let result = Notify { window, serial }; @@ -579,6 +584,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1087,6 +1097,11 @@ pub struct QueryCapabilitiesReply { impl TryParse for QueryCapabilitiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1123,6 +1138,11 @@ pub struct GenericEvent { impl TryParse for GenericEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1218,6 +1238,11 @@ pub struct ConfigureNotifyEvent { impl TryParse for ConfigureNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1269,6 +1294,11 @@ pub struct CompleteNotifyEvent { impl TryParse for CompleteNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1315,6 +1345,11 @@ pub struct IdleNotifyEvent { impl TryParse for IdleNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1373,6 +1408,11 @@ pub struct RedirectNotifyEvent { impl TryParse for RedirectNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 104 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/randr.rs b/src/protocol/randr.rs index c595a72f..26b7a946 100644 --- a/src/protocol/randr.rs +++ b/src/protocol/randr.rs @@ -56,6 +56,11 @@ pub struct BadOutputError { impl TryParse for BadOutputError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -133,6 +138,11 @@ pub struct BadCrtcError { impl TryParse for BadCrtcError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -210,6 +220,11 @@ pub struct BadModeError { impl TryParse for BadModeError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -287,6 +302,11 @@ pub struct BadProviderError { impl TryParse for BadProviderError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -438,6 +458,11 @@ pub struct ScreenSize { } impl TryParse for ScreenSize { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (mwidth, remaining) = u16::try_parse(remaining)?; @@ -485,6 +510,11 @@ pub struct RefreshRates { } impl TryParse for RefreshRates { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (n_rates, remaining) = u16::try_parse(remaining)?; let (rates, remaining) = crate::x11_utils::parse_list::(remaining, n_rates.try_into().or(Err(ParseError::ParseError))?)?; let result = RefreshRates { rates }; @@ -604,6 +634,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -812,6 +847,11 @@ pub struct SetScreenConfigReply { impl TryParse for SetScreenConfigReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1069,6 +1109,11 @@ pub struct GetScreenInfoReply { impl TryParse for GetScreenInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (rotations, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1187,6 +1232,11 @@ pub struct GetScreenSizeRangeReply { impl TryParse for GetScreenSizeRangeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1405,6 +1455,11 @@ pub struct ModeInfo { } impl TryParse for ModeInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (id, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; @@ -1570,6 +1625,11 @@ pub struct GetScreenResourcesReply { impl TryParse for GetScreenResourcesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1810,6 +1870,11 @@ pub struct GetOutputInfoReply { impl TryParse for GetOutputInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1972,6 +2037,11 @@ pub struct ListOutputPropertiesReply { impl TryParse for ListOutputPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2090,6 +2160,11 @@ pub struct QueryOutputPropertyReply { impl TryParse for QueryOutputPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2554,6 +2629,11 @@ pub struct GetOutputPropertyReply { impl TryParse for GetOutputPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2701,6 +2781,11 @@ pub struct CreateModeReply { impl TryParse for CreateModeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3006,6 +3091,11 @@ pub struct GetCrtcInfoReply { impl TryParse for GetCrtcInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3218,6 +3308,11 @@ pub struct SetCrtcConfigReply { impl TryParse for SetCrtcConfigReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3310,6 +3405,11 @@ pub struct GetCrtcGammaSizeReply { impl TryParse for GetCrtcGammaSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3403,6 +3503,11 @@ pub struct GetCrtcGammaReply { impl TryParse for GetCrtcGammaReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3615,6 +3720,11 @@ pub struct GetScreenResourcesCurrentReply { impl TryParse for GetScreenResourcesCurrentReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3988,6 +4098,11 @@ pub struct GetCrtcTransformReply { impl TryParse for GetCrtcTransformReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 96 { + return Err(ParseError::ParseError); + } let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -4168,6 +4283,11 @@ pub struct GetPanningReply { impl TryParse for GetPanningReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4365,6 +4485,11 @@ pub struct SetPanningReply { impl TryParse for SetPanningReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4524,6 +4649,11 @@ pub struct GetOutputPrimaryReply { impl TryParse for GetOutputPrimaryReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4615,6 +4745,11 @@ pub struct GetProvidersReply { impl TryParse for GetProvidersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4808,6 +4943,11 @@ pub struct GetProviderInfoReply { impl TryParse for GetProviderInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5118,6 +5258,11 @@ pub struct ListProviderPropertiesReply { impl TryParse for ListProviderPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5236,6 +5381,11 @@ pub struct QueryProviderPropertyReply { impl TryParse for QueryProviderPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5697,6 +5847,11 @@ pub struct GetProviderPropertyReply { impl TryParse for GetProviderPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5745,6 +5900,11 @@ pub struct ScreenChangeNotifyEvent { impl TryParse for ScreenChangeNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (rotation, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5920,6 +6080,11 @@ pub struct CrtcChange { } impl TryParse for CrtcChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (crtc, remaining) = Crtc::try_parse(remaining)?; @@ -6012,6 +6177,11 @@ pub struct OutputChange { } impl TryParse for OutputChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (config_timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; @@ -6100,6 +6270,11 @@ pub struct OutputProperty { } impl TryParse for OutputProperty { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (window, remaining) = xproto::Window::try_parse(remaining)?; let (output, remaining) = Output::try_parse(remaining)?; let (atom, remaining) = xproto::Atom::try_parse(remaining)?; @@ -6175,6 +6350,11 @@ pub struct ProviderChange { } impl TryParse for ProviderChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (provider, remaining) = Provider::try_parse(remaining)?; @@ -6245,6 +6425,11 @@ pub struct ProviderProperty { } impl TryParse for ProviderProperty { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (window, remaining) = xproto::Window::try_parse(remaining)?; let (provider, remaining) = Provider::try_parse(remaining)?; let (atom, remaining) = xproto::Atom::try_parse(remaining)?; @@ -6318,6 +6503,11 @@ pub struct ResourceChange { } impl TryParse for ResourceChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let remaining = remaining.get(20..).ok_or(ParseError::ParseError)?; @@ -6390,6 +6580,11 @@ pub struct MonitorInfo { } impl TryParse for MonitorInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (primary, remaining) = bool::try_parse(remaining)?; let (automatic, remaining) = bool::try_parse(remaining)?; @@ -6529,6 +6724,11 @@ pub struct GetMonitorsReply { impl TryParse for GetMonitorsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6816,6 +7016,11 @@ pub struct CreateLeaseReply { impl TryParseFd for CreateLeaseReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6918,6 +7123,11 @@ pub struct LeaseNotify { } impl TryParse for LeaseNotify { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (timestamp, remaining) = xproto::Timestamp::try_parse(remaining)?; let (window, remaining) = xproto::Window::try_parse(remaining)?; let (lease, remaining) = Lease::try_parse(remaining)?; @@ -7115,6 +7325,11 @@ pub struct NotifyEvent { impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (sub_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/record.rs b/src/protocol/record.rs index dc3f8f24..4c9937e1 100644 --- a/src/protocol/record.rs +++ b/src/protocol/record.rs @@ -43,6 +43,11 @@ pub struct Range8 { } impl TryParse for Range8 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (first, remaining) = u8::try_parse(remaining)?; let (last, remaining) = u8::try_parse(remaining)?; let result = Range8 { first, last }; @@ -79,6 +84,11 @@ pub struct Range16 { } impl TryParse for Range16 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (first, remaining) = u16::try_parse(remaining)?; let (last, remaining) = u16::try_parse(remaining)?; let result = Range16 { first, last }; @@ -117,6 +127,11 @@ pub struct ExtRange { } impl TryParse for ExtRange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 6 { + return Err(ParseError::ParseError); + } let (major, remaining) = Range8::try_parse(remaining)?; let (minor, remaining) = Range16::try_parse(remaining)?; let result = ExtRange { major, minor }; @@ -164,6 +179,11 @@ pub struct Range { } impl TryParse for Range { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (core_requests, remaining) = Range8::try_parse(remaining)?; let (core_replies, remaining) = Range8::try_parse(remaining)?; let (ext_requests, remaining) = ExtRange::try_parse(remaining)?; @@ -378,6 +398,11 @@ pub struct ClientInfo { } impl TryParse for ClientInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (client_resource, remaining) = ClientSpec::try_parse(remaining)?; let (num_ranges, remaining) = u32::try_parse(remaining)?; let (ranges, remaining) = crate::x11_utils::parse_list::(remaining, num_ranges.try_into().or(Err(ParseError::ParseError))?)?; @@ -433,6 +458,11 @@ pub struct BadContextError { impl TryParse for BadContextError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -576,6 +606,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -962,6 +997,11 @@ pub struct GetContextReply { impl TryParse for GetContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (enabled, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1076,6 +1116,11 @@ pub struct EnableContextReply { impl TryParse for EnableContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (category, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/render.rs b/src/protocol/render.rs index 13e006c2..39d84368 100644 --- a/src/protocol/render.rs +++ b/src/protocol/render.rs @@ -761,6 +761,11 @@ pub struct PictFormatError { impl TryParse for PictFormatError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -838,6 +843,11 @@ pub struct PictureError { impl TryParse for PictureError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -915,6 +925,11 @@ pub struct PictOpError { impl TryParse for PictOpError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -992,6 +1007,11 @@ pub struct GlyphSetError { impl TryParse for GlyphSetError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1069,6 +1089,11 @@ pub struct GlyphError { impl TryParse for GlyphError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1149,6 +1174,11 @@ pub struct Directformat { } impl TryParse for Directformat { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let (red_shift, remaining) = u16::try_parse(remaining)?; let (red_mask, remaining) = u16::try_parse(remaining)?; let (green_shift, remaining) = u16::try_parse(remaining)?; @@ -1220,6 +1250,11 @@ pub struct Pictforminfo { } impl TryParse for Pictforminfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (id, remaining) = Pictformat::try_parse(remaining)?; let (type_, remaining) = u8::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; @@ -1294,6 +1329,11 @@ pub struct Pictvisual { } impl TryParse for Pictvisual { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (format, remaining) = Pictformat::try_parse(remaining)?; let result = Pictvisual { visual, format }; @@ -1336,6 +1376,11 @@ pub struct Pictdepth { } impl TryParse for Pictdepth { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (num_visuals, remaining) = u16::try_parse(remaining)?; @@ -1391,6 +1436,11 @@ pub struct Pictscreen { } impl TryParse for Pictscreen { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (num_depths, remaining) = u32::try_parse(remaining)?; let (fallback, remaining) = Pictformat::try_parse(remaining)?; let (depths, remaining) = crate::x11_utils::parse_list::(remaining, num_depths.try_into().or(Err(ParseError::ParseError))?)?; @@ -1445,6 +1495,11 @@ pub struct Indexvalue { } impl TryParse for Indexvalue { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (pixel, remaining) = u32::try_parse(remaining)?; let (red, remaining) = u16::try_parse(remaining)?; let (green, remaining) = u16::try_parse(remaining)?; @@ -1502,6 +1557,11 @@ pub struct Color { } impl TryParse for Color { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (red, remaining) = u16::try_parse(remaining)?; let (green, remaining) = u16::try_parse(remaining)?; let (blue, remaining) = u16::try_parse(remaining)?; @@ -1550,6 +1610,11 @@ pub struct Pointfix { } impl TryParse for Pointfix { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (x, remaining) = Fixed::try_parse(remaining)?; let (y, remaining) = Fixed::try_parse(remaining)?; let result = Pointfix { x, y }; @@ -1592,6 +1657,11 @@ pub struct Linefix { } impl TryParse for Linefix { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let (p1, remaining) = Pointfix::try_parse(remaining)?; let (p2, remaining) = Pointfix::try_parse(remaining)?; let result = Linefix { p1, p2 }; @@ -1643,6 +1713,11 @@ pub struct Triangle { } impl TryParse for Triangle { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (p1, remaining) = Pointfix::try_parse(remaining)?; let (p2, remaining) = Pointfix::try_parse(remaining)?; let (p3, remaining) = Pointfix::try_parse(remaining)?; @@ -1706,6 +1781,11 @@ pub struct Trapezoid { } impl TryParse for Trapezoid { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (top, remaining) = Fixed::try_parse(remaining)?; let (bottom, remaining) = Fixed::try_parse(remaining)?; let (left, remaining) = Linefix::try_parse(remaining)?; @@ -1790,6 +1870,11 @@ pub struct Glyphinfo { } impl TryParse for Glyphinfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; @@ -1919,6 +2004,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2004,6 +2094,11 @@ pub struct QueryPictFormatsReply { impl TryParse for QueryPictFormatsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2151,6 +2246,11 @@ pub struct QueryPictIndexValuesReply { impl TryParse for QueryPictIndexValuesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4757,6 +4857,11 @@ pub struct Transform { } impl TryParse for Transform { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (matrix11, remaining) = Fixed::try_parse(remaining)?; let (matrix12, remaining) = Fixed::try_parse(remaining)?; let (matrix13, remaining) = Fixed::try_parse(remaining)?; @@ -5010,6 +5115,11 @@ pub struct QueryFiltersReply { impl TryParse for QueryFiltersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5172,6 +5282,11 @@ pub struct Animcursorelt { } impl TryParse for Animcursorelt { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (cursor, remaining) = xproto::Cursor::try_parse(remaining)?; let (delay, remaining) = u32::try_parse(remaining)?; let result = Animcursorelt { cursor, delay }; @@ -5296,6 +5411,11 @@ pub struct Spanfix { } impl TryParse for Spanfix { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (l, remaining) = Fixed::try_parse(remaining)?; let (r, remaining) = Fixed::try_parse(remaining)?; let (y, remaining) = Fixed::try_parse(remaining)?; @@ -5345,6 +5465,11 @@ pub struct Trap { } impl TryParse for Trap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (top, remaining) = Spanfix::try_parse(remaining)?; let (bot, remaining) = Spanfix::try_parse(remaining)?; let result = Trap { top, bot }; diff --git a/src/protocol/res.rs b/src/protocol/res.rs index 65695702..e636dafa 100644 --- a/src/protocol/res.rs +++ b/src/protocol/res.rs @@ -42,6 +42,11 @@ pub struct Client { } impl TryParse for Client { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (resource_base, remaining) = u32::try_parse(remaining)?; let (resource_mask, remaining) = u32::try_parse(remaining)?; let result = Client { resource_base, resource_mask }; @@ -84,6 +89,11 @@ pub struct Type { } impl TryParse for Type { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (resource_type, remaining) = xproto::Atom::try_parse(remaining)?; let (count, remaining) = u32::try_parse(remaining)?; let result = Type { resource_type, count }; @@ -189,6 +199,11 @@ pub struct ClientIdSpec { } impl TryParse for ClientIdSpec { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (client, remaining) = u32::try_parse(remaining)?; let (mask, remaining) = u32::try_parse(remaining)?; let result = ClientIdSpec { client, mask }; @@ -231,6 +246,11 @@ pub struct ClientIdValue { } impl TryParse for ClientIdValue { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (spec, remaining) = ClientIdSpec::try_parse(remaining)?; let (length, remaining) = u32::try_parse(remaining)?; let (value, remaining) = crate::x11_utils::parse_list::(remaining, length.checked_div(4u32).ok_or(ParseError::ParseError)?.try_into().or(Err(ParseError::ParseError))?)?; @@ -283,6 +303,11 @@ pub struct ResourceIdSpec { } impl TryParse for ResourceIdSpec { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (resource, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u32::try_parse(remaining)?; let result = ResourceIdSpec { resource, type_ }; @@ -327,6 +352,11 @@ pub struct ResourceSizeSpec { } impl TryParse for ResourceSizeSpec { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 20 { + return Err(ParseError::ParseError); + } let (spec, remaining) = ResourceIdSpec::try_parse(remaining)?; let (bytes, remaining) = u32::try_parse(remaining)?; let (ref_count, remaining) = u32::try_parse(remaining)?; @@ -387,6 +417,11 @@ pub struct ResourceSizeValue { } impl TryParse for ResourceSizeValue { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (size, remaining) = ResourceSizeSpec::try_parse(remaining)?; let (num_cross_references, remaining) = u32::try_parse(remaining)?; let (cross_references, remaining) = crate::x11_utils::parse_list::(remaining, num_cross_references.try_into().or(Err(ParseError::ParseError))?)?; @@ -505,6 +540,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -585,6 +625,11 @@ pub struct QueryClientsReply { impl TryParse for QueryClientsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -692,6 +737,11 @@ pub struct QueryClientResourcesReply { impl TryParse for QueryClientResourcesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -800,6 +850,11 @@ pub struct QueryClientPixmapBytesReply { impl TryParse for QueryClientPixmapBytesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -903,6 +958,11 @@ pub struct QueryClientIdsReply { impl TryParse for QueryClientIdsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1032,6 +1092,11 @@ pub struct QueryResourceBytesReply { impl TryParse for QueryResourceBytesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/screensaver.rs b/src/protocol/screensaver.rs index 1954bd2b..c894e1aa 100644 --- a/src/protocol/screensaver.rs +++ b/src/protocol/screensaver.rs @@ -306,6 +306,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -403,6 +408,11 @@ pub struct QueryInfoReply { impl TryParse for QueryInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1120,6 +1130,11 @@ pub struct NotifyEvent { impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/shape.rs b/src/protocol/shape.rs index ea112d93..ecb7057b 100644 --- a/src/protocol/shape.rs +++ b/src/protocol/shape.rs @@ -193,6 +193,11 @@ pub struct NotifyEvent { impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (shape_kind, remaining) = Kind::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -330,6 +335,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -843,6 +853,11 @@ pub struct QueryExtentsReply { impl TryParse for QueryExtentsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1012,6 +1027,11 @@ pub struct InputSelectedReply { impl TryParse for InputSelectedReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (enabled, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1113,6 +1133,11 @@ pub struct GetRectanglesReply { impl TryParse for GetRectanglesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (ordering, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/shm.rs b/src/protocol/shm.rs index c17822f8..42b50465 100644 --- a/src/protocol/shm.rs +++ b/src/protocol/shm.rs @@ -52,6 +52,11 @@ pub struct CompletionEvent { impl TryParse for CompletionEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -192,6 +197,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (shared_pixmaps, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -653,6 +663,11 @@ pub struct GetImageReply { impl TryParse for GetImageReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -950,6 +965,11 @@ pub struct CreateSegmentReply { impl TryParseFd for CreateSegmentReply { fn try_parse_fd<'a>(initial_value: &'a [u8], fds: &mut Vec) -> Result<(Self, &'a [u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (nfd, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/sync.rs b/src/protocol/sync.rs index f795f605..fa572893 100644 --- a/src/protocol/sync.rs +++ b/src/protocol/sync.rs @@ -326,6 +326,11 @@ pub struct Int64 { } impl TryParse for Int64 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (hi, remaining) = i32::try_parse(remaining)?; let (lo, remaining) = u32::try_parse(remaining)?; let result = Int64 { hi, lo }; @@ -369,6 +374,11 @@ pub struct Systemcounter { } impl TryParse for Systemcounter { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 14 { + return Err(ParseError::ParseError); + } let value = remaining; let (counter, remaining) = Counter::try_parse(remaining)?; let (resolution, remaining) = Int64::try_parse(remaining)?; @@ -431,6 +441,11 @@ pub struct Trigger { } impl TryParse for Trigger { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 20 { + return Err(ParseError::ParseError); + } let (counter, remaining) = Counter::try_parse(remaining)?; let (wait_type, remaining) = u32::try_parse(remaining)?; let (wait_value, remaining) = Int64::try_parse(remaining)?; @@ -493,6 +508,11 @@ pub struct Waitcondition { } impl TryParse for Waitcondition { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (trigger, remaining) = Trigger::try_parse(remaining)?; let (event_threshold, remaining) = Int64::try_parse(remaining)?; let result = Waitcondition { trigger, event_threshold }; @@ -561,6 +581,11 @@ pub struct CounterError { impl TryParse for CounterError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -647,6 +672,11 @@ pub struct AlarmError { impl TryParse for AlarmError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -794,6 +824,11 @@ pub struct InitializeReply { impl TryParse for InitializeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -875,6 +910,11 @@ pub struct ListSystemCountersReply { impl TryParse for ListSystemCountersReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1113,6 +1153,11 @@ pub struct QueryCounterReply { impl TryParse for QueryCounterReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1958,6 +2003,11 @@ pub struct QueryAlarmReply { impl TryParse for QueryAlarmReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2121,6 +2171,11 @@ pub struct GetPriorityReply { impl TryParse for GetPriorityReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2465,6 +2520,11 @@ pub struct QueryFenceReply { impl TryParse for QueryFenceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2576,6 +2636,11 @@ pub struct CounterNotifyEvent { impl TryParse for CounterNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (kind, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2668,6 +2733,11 @@ pub struct AlarmNotifyEvent { impl TryParse for AlarmNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (kind, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xc_misc.rs b/src/protocol/xc_misc.rs index e8e07a1c..27667f3a 100644 --- a/src/protocol/xc_misc.rs +++ b/src/protocol/xc_misc.rs @@ -108,6 +108,11 @@ pub struct GetVersionReply { impl TryParse for GetVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -189,6 +194,11 @@ pub struct GetXIDRangeReply { impl TryParse for GetXIDRangeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -280,6 +290,11 @@ pub struct GetXIDListReply { impl TryParse for GetXIDListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xevie.rs b/src/protocol/xevie.rs index 3773a17e..1e53b992 100644 --- a/src/protocol/xevie.rs +++ b/src/protocol/xevie.rs @@ -108,6 +108,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -199,6 +204,11 @@ pub struct StartReply { impl TryParse for StartReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -288,6 +298,11 @@ pub struct EndReply { impl TryParse for EndReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -385,6 +400,11 @@ pub struct Event { } impl TryParse for Event { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let remaining = remaining.get(32..).ok_or(ParseError::ParseError)?; let result = Event { }; Ok((result, remaining)) @@ -609,6 +629,11 @@ pub struct SendReply { impl TryParse for SendReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -698,6 +723,11 @@ pub struct SelectInputReply { impl TryParse for SelectInputReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xf86dri.rs b/src/protocol/xf86dri.rs index b861671f..eb754b97 100644 --- a/src/protocol/xf86dri.rs +++ b/src/protocol/xf86dri.rs @@ -43,6 +43,11 @@ pub struct DrmClipRect { } impl TryParse for DrmClipRect { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (x1, remaining) = i16::try_parse(remaining)?; let (y1, remaining) = i16::try_parse(remaining)?; let (x2, remaining) = i16::try_parse(remaining)?; @@ -143,6 +148,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -235,6 +245,11 @@ pub struct QueryDirectRenderingCapableReply { impl TryParse for QueryDirectRenderingCapableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -327,6 +342,11 @@ pub struct OpenConnectionReply { impl TryParse for OpenConnectionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -499,6 +519,11 @@ pub struct GetClientDriverNameReply { impl TryParse for GetClientDriverNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -628,6 +653,11 @@ pub struct CreateContextReply { impl TryParse for CreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -795,6 +825,11 @@ pub struct CreateDrawableReply { impl TryParse for CreateDrawableReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -971,6 +1006,11 @@ pub struct GetDrawableInfoReply { impl TryParse for GetDrawableInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1105,6 +1145,11 @@ pub struct GetDeviceInfoReply { impl TryParse for GetDeviceInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1225,6 +1270,11 @@ pub struct AuthConnectionReply { impl TryParse for AuthConnectionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xf86vidmode.rs b/src/protocol/xf86vidmode.rs index 1bf02ce7..c585d7fb 100644 --- a/src/protocol/xf86vidmode.rs +++ b/src/protocol/xf86vidmode.rs @@ -258,6 +258,11 @@ pub struct ModeInfo { } impl TryParse for ModeInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 48 { + return Err(ParseError::ParseError); + } let (dotclock, remaining) = Dotclock::try_parse(remaining)?; let (hdisplay, remaining) = u16::try_parse(remaining)?; let (hsyncstart, remaining) = u16::try_parse(remaining)?; @@ -425,6 +430,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -528,6 +538,11 @@ pub struct GetModeLineReply { impl TryParse for GetModeLineReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 52 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -897,6 +912,11 @@ pub struct GetMonitorReply { impl TryParse for GetMonitorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1118,6 +1138,11 @@ pub struct GetAllModeLinesReply { impl TryParse for GetAllModeLinesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1846,6 +1871,11 @@ pub struct ValidateModeLineReply { impl TryParse for ValidateModeLineReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2129,6 +2159,11 @@ pub struct GetViewPortReply { impl TryParse for GetViewPortReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2303,6 +2338,11 @@ pub struct GetDotClocksReply { impl TryParse for GetDotClocksReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2588,6 +2628,11 @@ pub struct GetGammaReply { impl TryParse for GetGammaReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2689,6 +2734,11 @@ pub struct GetGammaRampReply { impl TryParse for GetGammaRampReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2881,6 +2931,11 @@ pub struct GetGammaRampSizeReply { impl TryParse for GetGammaRampSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2973,6 +3028,11 @@ pub struct GetPermissionsReply { impl TryParse for GetPermissionsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3006,6 +3066,11 @@ pub struct BadClockError { impl TryParse for BadClockError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3083,6 +3148,11 @@ pub struct BadHTimingsError { impl TryParse for BadHTimingsError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3160,6 +3230,11 @@ pub struct BadVTimingsError { impl TryParse for BadVTimingsError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3237,6 +3312,11 @@ pub struct ModeUnsuitableError { impl TryParse for ModeUnsuitableError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3314,6 +3394,11 @@ pub struct ExtensionDisabledError { impl TryParse for ExtensionDisabledError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3391,6 +3476,11 @@ pub struct ClientNotLocalError { impl TryParse for ClientNotLocalError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3468,6 +3558,11 @@ pub struct ZoomLockedError { impl TryParse for ZoomLockedError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xfixes.rs b/src/protocol/xfixes.rs index c1de4713..646032c6 100644 --- a/src/protocol/xfixes.rs +++ b/src/protocol/xfixes.rs @@ -115,6 +115,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -578,6 +583,11 @@ pub struct SelectionNotifyEvent { impl TryParse for SelectionNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (subtype, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -866,6 +876,11 @@ pub struct CursorNotifyEvent { impl TryParse for CursorNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (subtype, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1073,6 +1088,11 @@ pub struct GetCursorImageReply { impl TryParse for GetCursorImageReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1115,6 +1135,11 @@ pub struct BadRegionError { impl TryParse for BadRegionError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2334,6 +2359,11 @@ pub struct FetchRegionReply { impl TryParse for FetchRegionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2787,6 +2817,11 @@ pub struct GetCursorNameReply { impl TryParse for GetCursorNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2894,6 +2929,11 @@ pub struct GetCursorImageAndNameReply { impl TryParse for GetCursorImageAndNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xinerama.rs b/src/protocol/xinerama.rs index fa38b884..1a4e36e8 100644 --- a/src/protocol/xinerama.rs +++ b/src/protocol/xinerama.rs @@ -44,6 +44,11 @@ pub struct ScreenInfo { } impl TryParse for ScreenInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (x_org, remaining) = i16::try_parse(remaining)?; let (y_org, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; @@ -159,6 +164,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -251,6 +261,11 @@ pub struct GetStateReply { impl TryParse for GetStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -342,6 +357,11 @@ pub struct GetScreenCountReply { impl TryParse for GetScreenCountReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (screen_count, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -444,6 +464,11 @@ pub struct GetScreenSizeReply { impl TryParse for GetScreenSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -526,6 +551,11 @@ pub struct IsActiveReply { impl TryParse for IsActiveReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -605,6 +635,11 @@ pub struct QueryScreensReply { impl TryParse for QueryScreensReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xinput.rs b/src/protocol/xinput.rs index 90f24c9d..cc47be60 100644 --- a/src/protocol/xinput.rs +++ b/src/protocol/xinput.rs @@ -51,6 +51,11 @@ pub struct Fp3232 { } impl TryParse for Fp3232 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (integral, remaining) = i32::try_parse(remaining)?; let (frac, remaining) = u32::try_parse(remaining)?; let result = Fp3232 { integral, frac }; @@ -169,6 +174,11 @@ pub struct GetExtensionVersionReply { impl TryParse for GetExtensionVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -421,6 +431,11 @@ pub struct DeviceInfo { } impl TryParse for DeviceInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (device_type, remaining) = xproto::Atom::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (num_class_info, remaining) = u8::try_parse(remaining)?; @@ -475,6 +490,11 @@ pub struct KeyInfo { } impl TryParse for KeyInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (min_keycode, remaining) = KeyCode::try_parse(remaining)?; @@ -530,6 +550,11 @@ pub struct ButtonInfo { } impl TryParse for ButtonInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_buttons, remaining) = u16::try_parse(remaining)?; @@ -573,6 +598,11 @@ pub struct AxisInfo { } impl TryParse for AxisInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (resolution, remaining) = u32::try_parse(remaining)?; let (minimum, remaining) = i32::try_parse(remaining)?; let (maximum, remaining) = i32::try_parse(remaining)?; @@ -625,6 +655,11 @@ pub struct ValuatorInfo { } impl TryParse for ValuatorInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (axes_len, remaining) = u8::try_parse(remaining)?; @@ -685,6 +720,11 @@ pub struct InputInfoInfoKey { } impl TryParse for InputInfoInfoKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 6 { + return Err(ParseError::ParseError); + } let (min_keycode, remaining) = KeyCode::try_parse(remaining)?; let (max_keycode, remaining) = KeyCode::try_parse(remaining)?; let (num_keys, remaining) = u16::try_parse(remaining)?; @@ -728,6 +768,11 @@ pub struct InputInfoInfoButton { } impl TryParse for InputInfoInfoButton { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (num_buttons, remaining) = u16::try_parse(remaining)?; let result = InputInfoInfoButton { num_buttons }; Ok((result, remaining)) @@ -761,6 +806,11 @@ pub struct InputInfoInfoValuator { } impl TryParse for InputInfoInfoValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 6 { + return Err(ParseError::ParseError); + } let (axes_len, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (motion_size, remaining) = u32::try_parse(remaining)?; @@ -895,6 +945,11 @@ pub struct InputInfo { } impl TryParse for InputInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (info, remaining) = InputInfoInfo::try_parse(remaining, class_id)?; @@ -930,6 +985,11 @@ pub struct DeviceName { } impl TryParse for DeviceName { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 1 { + return Err(ParseError::ParseError); + } let (len, remaining) = u8::try_parse(remaining)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, len.try_into().or(Err(ParseError::ParseError))?)?; let string = string.to_vec(); @@ -1033,6 +1093,11 @@ pub struct ListInputDevicesReply { impl TryParse for ListInputDevicesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; @@ -1088,6 +1153,11 @@ pub struct InputClassInfo { } impl TryParse for InputClassInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (event_type_base, remaining) = EventTypeBase::try_parse(remaining)?; let class_id = class_id.try_into()?; @@ -1188,6 +1258,11 @@ pub struct OpenDeviceReply { impl TryParse for OpenDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; @@ -1368,6 +1443,11 @@ pub struct SetDeviceModeReply { impl TryParse for SetDeviceModeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1544,6 +1624,11 @@ pub struct GetSelectedExtensionEventsReply { impl TryParse for GetSelectedExtensionEventsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1826,6 +1911,11 @@ pub struct GetDeviceDontPropagateListReply { impl TryParse for GetDeviceDontPropagateListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1872,6 +1962,11 @@ pub struct DeviceTimeCoord { } impl DeviceTimeCoord { pub fn try_parse(remaining: &[u8], num_axes: u8) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (time, remaining) = xproto::Timestamp::try_parse(remaining)?; let (axisvalues, remaining) = crate::x11_utils::parse_list::(remaining, num_axes.try_into().or(Err(ParseError::ParseError))?)?; let result = DeviceTimeCoord { time, axisvalues }; @@ -1985,6 +2080,11 @@ pub struct GetDeviceMotionEventsReply { impl TryParse for GetDeviceMotionEventsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2104,6 +2204,11 @@ pub struct ChangeKeyboardDeviceReply { impl TryParse for ChangeKeyboardDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2208,6 +2313,11 @@ pub struct ChangePointerDeviceReply { impl TryParse for ChangePointerDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2366,6 +2476,11 @@ pub struct GrabDeviceReply { impl TryParse for GrabDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3210,6 +3325,11 @@ pub struct GetDeviceFocusReply { impl TryParse for GetDeviceFocusReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3414,6 +3534,11 @@ pub struct KbdFeedbackState { } impl TryParse for KbdFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 52 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -3534,6 +3659,11 @@ pub struct PtrFeedbackState { } impl TryParse for PtrFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -3599,6 +3729,11 @@ pub struct IntegerFeedbackState { } impl TryParse for IntegerFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -3665,6 +3800,11 @@ pub struct StringFeedbackState { } impl TryParse for StringFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -3727,6 +3867,11 @@ pub struct BellFeedbackState { } impl TryParse for BellFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -3791,6 +3936,11 @@ pub struct LedFeedbackState { } impl TryParse for LedFeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -3853,6 +4003,11 @@ pub struct FeedbackStateDataKeyboard { } impl TryParse for FeedbackStateDataKeyboard { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 48 { + return Err(ParseError::ParseError); + } let (pitch, remaining) = u16::try_parse(remaining)?; let (duration, remaining) = u16::try_parse(remaining)?; let (led_mask, remaining) = u32::try_parse(remaining)?; @@ -3955,6 +4110,11 @@ pub struct FeedbackStateDataPointer { } impl TryParse for FeedbackStateDataPointer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; let (accel_num, remaining) = u16::try_parse(remaining)?; let (accel_denom, remaining) = u16::try_parse(remaining)?; @@ -4001,6 +4161,11 @@ pub struct FeedbackStateDataString { } impl TryParse for FeedbackStateDataString { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (max_symbols, remaining) = u16::try_parse(remaining)?; let (num_keysyms, remaining) = u16::try_parse(remaining)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, num_keysyms.try_into().or(Err(ParseError::ParseError))?)?; @@ -4052,6 +4217,11 @@ pub struct FeedbackStateDataInteger { } impl TryParse for FeedbackStateDataInteger { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (resolution, remaining) = u32::try_parse(remaining)?; let (min_value, remaining) = i32::try_parse(remaining)?; let (max_value, remaining) = i32::try_parse(remaining)?; @@ -4100,6 +4270,11 @@ pub struct FeedbackStateDataLed { } impl TryParse for FeedbackStateDataLed { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let result = FeedbackStateDataLed { led_mask, led_values }; @@ -4142,6 +4317,11 @@ pub struct FeedbackStateDataBell { } impl TryParse for FeedbackStateDataBell { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (percent, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::ParseError)?; let (pitch, remaining) = u16::try_parse(remaining)?; @@ -4315,6 +4495,11 @@ pub struct FeedbackState { } impl TryParse for FeedbackState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -4416,6 +4601,11 @@ pub struct GetFeedbackControlReply { impl TryParse for GetFeedbackControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4471,6 +4661,11 @@ pub struct KbdFeedbackCtl { } impl TryParse for KbdFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 20 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -4557,6 +4752,11 @@ pub struct PtrFeedbackCtl { } impl TryParse for PtrFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -4620,6 +4820,11 @@ pub struct IntegerFeedbackCtl { } impl TryParse for IntegerFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -4671,6 +4876,11 @@ pub struct StringFeedbackCtl { } impl TryParse for StringFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -4733,6 +4943,11 @@ pub struct BellFeedbackCtl { } impl TryParse for BellFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -4797,6 +5012,11 @@ pub struct LedFeedbackCtl { } impl TryParse for LedFeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -4859,6 +5079,11 @@ pub struct FeedbackCtlDataKeyboard { } impl TryParse for FeedbackCtlDataKeyboard { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let (key, remaining) = KeyCode::try_parse(remaining)?; let (auto_repeat_mode, remaining) = u8::try_parse(remaining)?; let (key_click_percent, remaining) = i8::try_parse(remaining)?; @@ -4927,6 +5152,11 @@ pub struct FeedbackCtlDataPointer { } impl TryParse for FeedbackCtlDataPointer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; let (num, remaining) = i16::try_parse(remaining)?; let (denom, remaining) = i16::try_parse(remaining)?; @@ -4972,6 +5202,11 @@ pub struct FeedbackCtlDataString { } impl TryParse for FeedbackCtlDataString { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; let (num_keysyms, remaining) = u16::try_parse(remaining)?; let (keysyms, remaining) = crate::x11_utils::parse_list::(remaining, num_keysyms.try_into().or(Err(ParseError::ParseError))?)?; @@ -5021,6 +5256,11 @@ pub struct FeedbackCtlDataInteger { } impl TryParse for FeedbackCtlDataInteger { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (int_to_display, remaining) = i32::try_parse(remaining)?; let result = FeedbackCtlDataInteger { int_to_display }; Ok((result, remaining)) @@ -5055,6 +5295,11 @@ pub struct FeedbackCtlDataLed { } impl TryParse for FeedbackCtlDataLed { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (led_mask, remaining) = u32::try_parse(remaining)?; let (led_values, remaining) = u32::try_parse(remaining)?; let result = FeedbackCtlDataLed { led_mask, led_values }; @@ -5097,6 +5342,11 @@ pub struct FeedbackCtlDataBell { } impl TryParse for FeedbackCtlDataBell { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (percent, remaining) = i8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::ParseError)?; let (pitch, remaining) = i16::try_parse(remaining)?; @@ -5270,6 +5520,11 @@ pub struct FeedbackCtl { } impl TryParse for FeedbackCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (feedback_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -5527,6 +5782,11 @@ pub struct GetDeviceKeyMappingReply { impl TryParse for GetDeviceKeyMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5729,6 +5989,11 @@ pub struct GetDeviceModifierMappingReply { impl TryParse for GetDeviceModifierMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5858,6 +6123,11 @@ pub struct SetDeviceModifierMappingReply { impl TryParse for SetDeviceModifierMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5952,6 +6222,11 @@ pub struct GetDeviceButtonMappingReply { impl TryParse for GetDeviceButtonMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; @@ -6084,6 +6359,11 @@ pub struct SetDeviceButtonMappingReply { impl TryParse for SetDeviceButtonMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6117,6 +6397,11 @@ pub struct KeyState { } impl TryParse for KeyState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_keys, remaining) = u8::try_parse(remaining)?; @@ -6198,6 +6483,11 @@ pub struct ButtonState { } impl TryParse for ButtonState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_buttons, remaining) = u8::try_parse(remaining)?; @@ -6342,6 +6632,11 @@ pub struct ValuatorState { } impl TryParse for ValuatorState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; @@ -6398,6 +6693,11 @@ pub struct InputStateDataKey { } impl TryParse for InputStateDataKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 34 { + return Err(ParseError::ParseError); + } let (num_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (keys, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; @@ -6467,6 +6767,11 @@ pub struct InputStateDataButton { } impl TryParse for InputStateDataButton { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 34 { + return Err(ParseError::ParseError); + } let (num_buttons, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (buttons, remaining) = crate::x11_utils::parse_u8_list(remaining, 32)?; @@ -6536,6 +6841,11 @@ pub struct InputStateDataValuator { } impl TryParse for InputStateDataValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (num_valuators, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (valuators, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_into().or(Err(ParseError::ParseError))?)?; @@ -6667,6 +6977,11 @@ pub struct InputState { } impl TryParse for InputState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (class_id, remaining) = u8::try_parse(remaining)?; let (len, remaining) = u8::try_parse(remaining)?; let (data, remaining) = InputStateData::try_parse(remaining, class_id)?; @@ -6766,6 +7081,11 @@ pub struct QueryDeviceStateReply { impl TryParse for QueryDeviceStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6973,6 +7293,11 @@ pub struct SetDeviceValuatorsReply { impl TryParse for SetDeviceValuatorsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7078,6 +7403,11 @@ pub struct DeviceResolutionState { } impl TryParse for DeviceResolutionState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (num_valuators, remaining) = u32::try_parse(remaining)?; @@ -7146,6 +7476,11 @@ pub struct DeviceAbsCalibState { } impl TryParse for DeviceAbsCalibState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (min_x, remaining) = i32::try_parse(remaining)?; @@ -7247,6 +7582,11 @@ pub struct DeviceAbsAreaState { } impl TryParse for DeviceAbsAreaState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (offset_x, remaining) = u32::try_parse(remaining)?; @@ -7330,6 +7670,11 @@ pub struct DeviceCoreState { } impl TryParse for DeviceCoreState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; @@ -7382,6 +7727,11 @@ pub struct DeviceEnableState { } impl TryParse for DeviceEnableState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (enable, remaining) = u8::try_parse(remaining)?; @@ -7431,6 +7781,11 @@ pub struct DeviceStateDataResolution { } impl TryParse for DeviceStateDataResolution { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (num_valuators, remaining) = u32::try_parse(remaining)?; let (resolution_values, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_into().or(Err(ParseError::ParseError))?)?; let (resolution_min, remaining) = crate::x11_utils::parse_list::(remaining, num_valuators.try_into().or(Err(ParseError::ParseError))?)?; @@ -7490,6 +7845,11 @@ pub struct DeviceStateDataAbsCalib { } impl TryParse for DeviceStateDataAbsCalib { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (min_x, remaining) = i32::try_parse(remaining)?; let (max_x, remaining) = i32::try_parse(remaining)?; let (min_y, remaining) = i32::try_parse(remaining)?; @@ -7573,6 +7933,11 @@ pub struct DeviceStateDataCore { } impl TryParse for DeviceStateDataCore { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (status, remaining) = u8::try_parse(remaining)?; let (iscore, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; @@ -7616,6 +7981,11 @@ pub struct DeviceStateDataAbsArea { } impl TryParse for DeviceStateDataAbsArea { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (offset_x, remaining) = u32::try_parse(remaining)?; let (offset_y, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u32::try_parse(remaining)?; @@ -7802,6 +8172,11 @@ pub struct DeviceState { } impl TryParse for DeviceState { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = DeviceStateData::try_parse(remaining, control_id)?; @@ -7908,6 +8283,11 @@ pub struct GetDeviceControlReply { impl TryParse for GetDeviceControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7941,6 +8321,11 @@ pub struct DeviceResolutionCtl { } impl TryParse for DeviceResolutionCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (first_valuator, remaining) = u8::try_parse(remaining)?; @@ -8007,6 +8392,11 @@ pub struct DeviceAbsCalibCtl { } impl TryParse for DeviceAbsCalibCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (min_x, remaining) = i32::try_parse(remaining)?; @@ -8108,6 +8498,11 @@ pub struct DeviceAbsAreaCtrl { } impl TryParse for DeviceAbsAreaCtrl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 28 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (offset_x, remaining) = u32::try_parse(remaining)?; @@ -8190,6 +8585,11 @@ pub struct DeviceCoreCtrl { } impl TryParse for DeviceCoreCtrl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; @@ -8239,6 +8639,11 @@ pub struct DeviceEnableCtrl { } impl TryParse for DeviceEnableCtrl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (enable, remaining) = u8::try_parse(remaining)?; @@ -8287,6 +8692,11 @@ pub struct DeviceCtlDataResolution { } impl TryParse for DeviceCtlDataResolution { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (first_valuator, remaining) = u8::try_parse(remaining)?; let (num_valuators, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; @@ -8345,6 +8755,11 @@ pub struct DeviceCtlDataAbsCalib { } impl TryParse for DeviceCtlDataAbsCalib { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (min_x, remaining) = i32::try_parse(remaining)?; let (max_x, remaining) = i32::try_parse(remaining)?; let (min_y, remaining) = i32::try_parse(remaining)?; @@ -8427,6 +8842,11 @@ pub struct DeviceCtlDataCore { } impl TryParse for DeviceCtlDataCore { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::ParseError)?; let result = DeviceCtlDataCore { status }; @@ -8467,6 +8887,11 @@ pub struct DeviceCtlDataAbsArea { } impl TryParse for DeviceCtlDataAbsArea { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (offset_x, remaining) = u32::try_parse(remaining)?; let (offset_y, remaining) = u32::try_parse(remaining)?; let (width, remaining) = i32::try_parse(remaining)?; @@ -8653,6 +9078,11 @@ pub struct DeviceCtl { } impl TryParse for DeviceCtl { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (control_id, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = DeviceCtlData::try_parse(remaining, control_id)?; @@ -8766,6 +9196,11 @@ pub struct ChangeDeviceControlReply { impl TryParse for ChangeDeviceControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8859,6 +9294,11 @@ pub struct ListDevicePropertiesReply { impl TryParse for ListDevicePropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9438,6 +9878,11 @@ pub struct GetDevicePropertyReply { impl TryParse for GetDevicePropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xi_reply_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9545,6 +9990,11 @@ pub struct GroupInfo { } impl TryParse for GroupInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (base, remaining) = u8::try_parse(remaining)?; let (latched, remaining) = u8::try_parse(remaining)?; let (locked, remaining) = u8::try_parse(remaining)?; @@ -9591,6 +10041,11 @@ pub struct ModifierInfo { } impl TryParse for ModifierInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let (base, remaining) = u32::try_parse(remaining)?; let (latched, remaining) = u32::try_parse(remaining)?; let (locked, remaining) = u32::try_parse(remaining)?; @@ -9729,6 +10184,11 @@ pub struct XIQueryPointerReply { impl TryParse for XIQueryPointerReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 56 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10127,6 +10587,11 @@ pub struct AddMaster { } impl TryParse for AddMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let value = remaining; let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; @@ -10196,6 +10661,11 @@ pub struct RemoveMaster { } impl TryParse for RemoveMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; @@ -10260,6 +10730,11 @@ pub struct AttachSlave { } impl TryParse for AttachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; @@ -10310,6 +10785,11 @@ pub struct DetachSlave { } impl TryParse for DetachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; @@ -10359,6 +10839,11 @@ pub struct HierarchyChangeDataAddMaster { } impl TryParse for HierarchyChangeDataAddMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let value = remaining; let (name_len, remaining) = u16::try_parse(remaining)?; let (send_core, remaining) = bool::try_parse(remaining)?; @@ -10420,6 +10905,11 @@ pub struct HierarchyChangeDataRemoveMaster { } impl TryParse for HierarchyChangeDataRemoveMaster { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (return_mode, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -10470,6 +10960,11 @@ pub struct HierarchyChangeDataAttachSlave { } impl TryParse for HierarchyChangeDataAttachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (master, remaining) = DeviceId::try_parse(remaining)?; let result = HierarchyChangeDataAttachSlave { deviceid, master }; @@ -10506,6 +11001,11 @@ pub struct HierarchyChangeDataDetachSlave { } impl TryParse for HierarchyChangeDataDetachSlave { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; let result = HierarchyChangeDataDetachSlave { deviceid }; @@ -10638,6 +11138,11 @@ pub struct HierarchyChange { } impl TryParse for HierarchyChange { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (data, remaining) = HierarchyChangeData::try_parse(remaining, type_)?; @@ -10879,6 +11384,11 @@ pub struct XIGetClientPointerReply { impl TryParse for XIGetClientPointerReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11014,6 +11524,11 @@ pub struct EventMask { } impl TryParse for EventMask { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (mask_len, remaining) = u16::try_parse(remaining)?; let (mask, remaining) = crate::x11_utils::parse_list::(remaining, mask_len.try_into().or(Err(ParseError::ParseError))?)?; @@ -11214,6 +11729,11 @@ pub struct XIQueryVersionReply { impl TryParse for XIQueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11577,6 +12097,11 @@ pub struct ButtonClass { } impl TryParse for ButtonClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; @@ -11638,6 +12163,11 @@ pub struct KeyClass { } impl TryParse for KeyClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; @@ -11699,6 +12229,11 @@ pub struct ScrollClass { } impl TryParse for ScrollClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; @@ -11779,6 +12314,11 @@ pub struct TouchClass { } impl TryParse for TouchClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; @@ -11840,6 +12380,11 @@ pub struct ValuatorClass { } impl TryParse for ValuatorClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 44 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; @@ -11945,6 +12490,11 @@ pub struct DeviceClassDataKey { } impl TryParse for DeviceClassDataKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (num_keys, remaining) = u16::try_parse(remaining)?; let (keys, remaining) = crate::x11_utils::parse_list::(remaining, num_keys.try_into().or(Err(ParseError::ParseError))?)?; let result = DeviceClassDataKey { keys }; @@ -11992,6 +12542,11 @@ pub struct DeviceClassDataButton { } impl TryParse for DeviceClassDataButton { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (num_buttons, remaining) = u16::try_parse(remaining)?; let (state, remaining) = crate::x11_utils::parse_list::(remaining, u32::from(num_buttons).checked_add(31u32).ok_or(ParseError::ParseError)?.checked_div(32u32).ok_or(ParseError::ParseError)?.try_into().or(Err(ParseError::ParseError))?)?; let (labels, remaining) = crate::x11_utils::parse_list::(remaining, num_buttons.try_into().or(Err(ParseError::ParseError))?)?; @@ -12047,6 +12602,11 @@ pub struct DeviceClassDataValuator { } impl TryParse for DeviceClassDataValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 38 { + return Err(ParseError::ParseError); + } let (number, remaining) = u16::try_parse(remaining)?; let (label, remaining) = xproto::Atom::try_parse(remaining)?; let (min, remaining) = Fp3232::try_parse(remaining)?; @@ -12138,6 +12698,11 @@ pub struct DeviceClassDataScroll { } impl TryParse for DeviceClassDataScroll { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 18 { + return Err(ParseError::ParseError); + } let (number, remaining) = u16::try_parse(remaining)?; let (scroll_type, remaining) = u16::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; @@ -12198,6 +12763,11 @@ pub struct DeviceClassDataTouch { } impl TryParse for DeviceClassDataTouch { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (mode, remaining) = u8::try_parse(remaining)?; let (num_touches, remaining) = u8::try_parse(remaining)?; let mode = mode.try_into()?; @@ -12346,6 +12916,11 @@ pub struct DeviceClass { } impl TryParse for DeviceClass { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 6 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u16::try_parse(remaining)?; let (len, remaining) = u16::try_parse(remaining)?; let (sourceid, remaining) = DeviceId::try_parse(remaining)?; @@ -12388,6 +12963,11 @@ pub struct XIDeviceInfo { } impl TryParse for XIDeviceInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let value = remaining; let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (type_, remaining) = u16::try_parse(remaining)?; @@ -12537,6 +13117,11 @@ pub struct XIQueryDeviceReply { impl TryParse for XIQueryDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12729,6 +13314,11 @@ pub struct XIGetFocusReply { impl TryParse for XIGetFocusReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12968,6 +13558,11 @@ pub struct XIGrabDeviceReply { impl TryParse for XIGrabDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13413,6 +14008,11 @@ pub struct GrabModifierInfo { } impl TryParse for GrabModifierInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (modifiers, remaining) = u32::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::ParseError)?; @@ -13628,6 +14228,11 @@ pub struct XIPassiveGrabDeviceReply { impl TryParse for XIPassiveGrabDeviceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13849,6 +14454,11 @@ pub struct XIListPropertiesReply { impl TryParse for XIListPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14366,6 +14976,11 @@ pub struct XIGetPropertyReply { impl TryParse for XIGetPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14461,6 +15076,11 @@ pub struct XIGetSelectedEventsReply { impl TryParse for XIGetSelectedEventsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14508,6 +15128,11 @@ pub struct BarrierReleasePointerInfo { } impl TryParse for BarrierReleasePointerInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; let (barrier, remaining) = xfixes::Barrier::try_parse(remaining)?; @@ -14638,6 +15263,11 @@ pub struct DeviceValuatorEvent { impl TryParse for DeviceValuatorEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14809,6 +15439,11 @@ pub struct DeviceKeyPressEvent { impl TryParse for DeviceKeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14925,6 +15560,11 @@ pub struct DeviceFocusInEvent { impl TryParse for DeviceFocusInEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15102,6 +15742,11 @@ pub struct DeviceStateNotifyEvent { impl TryParse for DeviceStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15205,6 +15850,11 @@ pub struct DeviceMappingNotifyEvent { impl TryParse for DeviceMappingNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15362,6 +16012,11 @@ pub struct ChangeDeviceNotifyEvent { impl TryParse for ChangeDeviceNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15443,6 +16098,11 @@ pub struct DeviceKeyStateNotifyEvent { impl TryParse for DeviceKeyStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15520,6 +16180,11 @@ pub struct DeviceButtonStateNotifyEvent { impl TryParse for DeviceButtonStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15673,6 +16338,11 @@ pub struct DevicePresenceNotifyEvent { impl TryParse for DevicePresenceNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15759,6 +16429,11 @@ pub struct DevicePropertyNotifyEvent { impl TryParse for DevicePropertyNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (state, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15910,6 +16585,11 @@ pub struct DeviceChangedEvent { impl TryParse for DeviceChangedEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16010,6 +16690,11 @@ pub struct KeyPressEvent { impl TryParse for KeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 80 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16139,6 +16824,11 @@ pub struct ButtonPressEvent { impl TryParse for ButtonPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 80 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16398,6 +17088,11 @@ pub struct EnterEvent { impl TryParse for EnterEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 72 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16555,6 +17250,11 @@ pub struct HierarchyInfo { } impl TryParse for HierarchyInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (deviceid, remaining) = DeviceId::try_parse(remaining)?; let (attachment, remaining) = DeviceId::try_parse(remaining)?; let (type_, remaining) = u8::try_parse(remaining)?; @@ -16623,6 +17323,11 @@ pub struct HierarchyEvent { impl TryParse for HierarchyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16745,6 +17450,11 @@ pub struct PropertyEvent { impl TryParse for PropertyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16791,6 +17501,11 @@ pub struct RawKeyPressEvent { impl TryParse for RawKeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16860,6 +17575,11 @@ pub struct RawButtonPressEvent { impl TryParse for RawButtonPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -16973,6 +17693,11 @@ pub struct TouchBeginEvent { impl TryParse for TouchBeginEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 80 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17128,6 +17853,11 @@ pub struct TouchOwnershipEvent { impl TryParse for TouchOwnershipEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 48 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17179,6 +17909,11 @@ pub struct RawTouchBeginEvent { impl TryParse for RawTouchBeginEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17320,6 +18055,11 @@ pub struct BarrierHitEvent { impl TryParse for BarrierHitEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 68 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17684,6 +18424,11 @@ pub struct DeviceError { impl TryParse for DeviceError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17761,6 +18506,11 @@ pub struct EventError { impl TryParse for EventError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17838,6 +18588,11 @@ pub struct ModeError { impl TryParse for ModeError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17915,6 +18670,11 @@ pub struct DeviceBusyError { impl TryParse for DeviceBusyError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -17992,6 +18752,11 @@ pub struct ClassError { impl TryParse for ClassError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xkb.rs b/src/protocol/xkb.rs index f237fd70..c468525d 100644 --- a/src/protocol/xkb.rs +++ b/src/protocol/xkb.rs @@ -2052,6 +2052,11 @@ pub struct IndicatorMap { } impl TryParse for IndicatorMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (flags, remaining) = u8::try_parse(remaining)?; let (which_groups, remaining) = u8::try_parse(remaining)?; let (groups, remaining) = u8::try_parse(remaining)?; @@ -2492,6 +2497,11 @@ pub struct ModDef { } impl TryParse for ModDef { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (mask, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (vmods, remaining) = u16::try_parse(remaining)?; @@ -2532,6 +2542,11 @@ pub struct KeyName { } impl TryParse for KeyName { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let name = <[u8; 4]>::try_from(name).unwrap(); let result = KeyName { name }; @@ -2567,6 +2582,11 @@ pub struct KeyAlias { } impl TryParse for KeyAlias { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (real, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let real = <[u8; 4]>::try_from(real).unwrap(); let (alias, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; @@ -2609,6 +2629,11 @@ pub struct CountedString16 { } impl TryParse for CountedString16 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (length, remaining) = u16::try_parse(remaining)?; let (string, remaining) = crate::x11_utils::parse_u8_list(remaining, length.try_into().or(Err(ParseError::ParseError))?)?; let string = string.to_vec(); @@ -2665,6 +2690,11 @@ pub struct KTMapEntry { } impl TryParse for KTMapEntry { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (active, remaining) = bool::try_parse(remaining)?; let (mods_mask, remaining) = u8::try_parse(remaining)?; let (level, remaining) = u8::try_parse(remaining)?; @@ -2723,6 +2753,11 @@ pub struct KeyType { } impl TryParse for KeyType { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (mods_mask, remaining) = u8::try_parse(remaining)?; let (mods_mods, remaining) = u8::try_parse(remaining)?; let (mods_vmods, remaining) = u16::try_parse(remaining)?; @@ -2789,6 +2824,11 @@ pub struct KeySymMap { } impl TryParse for KeySymMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (kt_index, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let kt_index = <[u8; 4]>::try_from(kt_index).unwrap(); let (group_info, remaining) = u8::try_parse(remaining)?; @@ -2845,6 +2885,11 @@ pub struct CommonBehavior { } impl TryParse for CommonBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (data, remaining) = u8::try_parse(remaining)?; let result = CommonBehavior { type_, data }; @@ -2880,6 +2925,11 @@ pub struct DefaultBehavior { } impl TryParse for DefaultBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let result = DefaultBehavior { type_ }; @@ -2917,6 +2967,11 @@ pub struct RadioGroupBehavior { } impl TryParse for RadioGroupBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (group, remaining) = u8::try_parse(remaining)?; let result = RadioGroupBehavior { type_, group }; @@ -2953,6 +3008,11 @@ pub struct OverlayBehavior { } impl TryParse for OverlayBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (key, remaining) = xproto::Keycode::try_parse(remaining)?; let result = OverlayBehavior { type_, key }; @@ -3224,6 +3284,11 @@ pub struct SetBehavior { } impl TryParse for SetBehavior { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (behavior, remaining) = Behavior::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -3264,6 +3329,11 @@ pub struct SetExplicit { } impl TryParse for SetExplicit { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (explicit, remaining) = u8::try_parse(remaining)?; let result = SetExplicit { keycode, explicit }; @@ -3300,6 +3370,11 @@ pub struct KeyModMap { } impl TryParse for KeyModMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let result = KeyModMap { keycode, mods }; @@ -3336,6 +3411,11 @@ pub struct KeyVModMap { } impl TryParse for KeyVModMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (keycode, remaining) = xproto::Keycode::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (vmods, remaining) = u16::try_parse(remaining)?; @@ -3377,6 +3457,11 @@ pub struct KTSetMapEntry { } impl TryParse for KTSetMapEntry { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (level, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; @@ -3423,6 +3508,11 @@ pub struct SetKeyType { } impl TryParse for SetKeyType { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (mask, remaining) = u8::try_parse(remaining)?; let (real_mods, remaining) = u8::try_parse(remaining)?; let (virtual_mods, remaining) = u16::try_parse(remaining)?; @@ -3489,6 +3579,11 @@ pub struct Outline { } impl TryParse for Outline { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (n_points, remaining) = u8::try_parse(remaining)?; let (corner_radius, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; @@ -3544,6 +3639,11 @@ pub struct Shape { } impl TryParse for Shape { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (n_outlines, remaining) = u8::try_parse(remaining)?; let (primary_ndx, remaining) = u8::try_parse(remaining)?; @@ -3603,6 +3703,11 @@ pub struct Key { } impl TryParse for Key { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let name = <[u8; 4]>::try_from(name).unwrap(); let (gap, remaining) = i16::try_parse(remaining)?; @@ -3651,6 +3756,11 @@ pub struct OverlayKey { } impl TryParse for OverlayKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (over, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; let over = <[u8; 4]>::try_from(over).unwrap(); let (under, remaining) = crate::x11_utils::parse_u8_list(remaining, 4)?; @@ -3693,6 +3803,11 @@ pub struct OverlayRow { } impl TryParse for OverlayRow { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (row_under, remaining) = u8::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(2..).ok_or(ParseError::ParseError)?; @@ -3746,6 +3861,11 @@ pub struct Overlay { } impl TryParse for Overlay { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (n_rows, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::ParseError)?; @@ -3801,6 +3921,11 @@ pub struct Row { } impl TryParse for Row { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (top, remaining) = i16::try_parse(remaining)?; let (left, remaining) = i16::try_parse(remaining)?; let (n_keys, remaining) = u8::try_parse(remaining)?; @@ -3929,6 +4054,11 @@ pub struct Listing { } impl TryParse for Listing { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let value = remaining; let (flags, remaining) = u16::try_parse(remaining)?; let (length, remaining) = u16::try_parse(remaining)?; @@ -3993,6 +4123,11 @@ pub struct DeviceLedInfo { } impl TryParse for DeviceLedInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 20 { + return Err(ParseError::ParseError); + } let (led_class, remaining) = LedClassSpec::try_parse(remaining)?; let (led_id, remaining) = IDSpec::try_parse(remaining)?; let (names_present, remaining) = u32::try_parse(remaining)?; @@ -4112,6 +4247,11 @@ pub struct KeyboardError { impl TryParse for KeyboardError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4354,6 +4494,11 @@ pub struct SANoAction { } impl TryParse for SANoAction { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(7..).ok_or(ParseError::ParseError)?; let type_ = type_.try_into()?; @@ -4400,6 +4545,11 @@ pub struct SASetMods { } impl TryParse for SASetMods { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (mask, remaining) = u8::try_parse(remaining)?; @@ -4462,6 +4612,11 @@ pub struct SASetGroup { } impl TryParse for SASetGroup { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (group, remaining) = i8::try_parse(remaining)?; @@ -4584,6 +4739,11 @@ pub struct SAMovePtr { } impl TryParse for SAMovePtr { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (x_high, remaining) = i8::try_parse(remaining)?; @@ -4643,6 +4803,11 @@ pub struct SAPtrBtn { } impl TryParse for SAPtrBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (count, remaining) = u8::try_parse(remaining)?; @@ -4695,6 +4860,11 @@ pub struct SALockPtrBtn { } impl TryParse for SALockPtrBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -4810,6 +4980,11 @@ pub struct SASetPtrDflt { } impl TryParse for SASetPtrDflt { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (affect, remaining) = u8::try_parse(remaining)?; @@ -4982,6 +5157,11 @@ pub struct SAIsoLock { } impl TryParse for SAIsoLock { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (mask, remaining) = u8::try_parse(remaining)?; @@ -5042,6 +5222,11 @@ pub struct SATerminate { } impl TryParse for SATerminate { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(7..).ok_or(ParseError::ParseError)?; let type_ = type_.try_into()?; @@ -5148,6 +5333,11 @@ pub struct SASwitchScreen { } impl TryParse for SASwitchScreen { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (new_screen, remaining) = i8::try_parse(remaining)?; @@ -5350,6 +5540,11 @@ pub struct SASetControls { } impl TryParse for SASetControls { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::ParseError)?; let (bool_ctrls_high, remaining) = u8::try_parse(remaining)?; @@ -5469,6 +5664,11 @@ pub struct SAActionMessage { } impl TryParse for SAActionMessage { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (message, remaining) = crate::x11_utils::parse_u8_list(remaining, 6)?; @@ -5521,6 +5721,11 @@ pub struct SARedirectKey { } impl TryParse for SARedirectKey { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (newkey, remaining) = xproto::Keycode::try_parse(remaining)?; let (mask, remaining) = u8::try_parse(remaining)?; @@ -5585,6 +5790,11 @@ pub struct SADeviceBtn { } impl TryParse for SADeviceBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let (count, remaining) = u8::try_parse(remaining)?; @@ -5704,6 +5914,11 @@ pub struct SALockDeviceBtn { } impl TryParse for SALockDeviceBtn { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (flags, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -5837,6 +6052,11 @@ pub struct SADeviceValuator { } impl TryParse for SADeviceValuator { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (device, remaining) = u8::try_parse(remaining)?; let (val1what, remaining) = u8::try_parse(remaining)?; @@ -5900,6 +6120,11 @@ pub struct SIAction { } impl TryParse for SIAction { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (type_, remaining) = u8::try_parse(remaining)?; let (data, remaining) = crate::x11_utils::parse_u8_list(remaining, 7)?; let data = <[u8; 7]>::try_from(data).unwrap(); @@ -5947,6 +6172,11 @@ pub struct SymInterpret { } impl TryParse for SymInterpret { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let (sym, remaining) = xproto::Keysym::try_parse(remaining)?; let (mods, remaining) = u8::try_parse(remaining)?; let (match_, remaining) = u8::try_parse(remaining)?; @@ -6390,6 +6620,11 @@ pub struct UseExtensionReply { impl TryParse for UseExtensionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (supported, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -6421,6 +6656,11 @@ pub struct SelectEventsAuxBitcase1 { } impl TryParse for SelectEventsAuxBitcase1 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (affect_new_keyboard, remaining) = u16::try_parse(remaining)?; let (new_keyboard_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase1 { affect_new_keyboard, new_keyboard_details }; @@ -6458,6 +6698,11 @@ pub struct SelectEventsAuxBitcase2 { } impl TryParse for SelectEventsAuxBitcase2 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (affect_state, remaining) = u16::try_parse(remaining)?; let (state_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase2 { affect_state, state_details }; @@ -6495,6 +6740,11 @@ pub struct SelectEventsAuxBitcase3 { } impl TryParse for SelectEventsAuxBitcase3 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (affect_ctrls, remaining) = u32::try_parse(remaining)?; let (ctrl_details, remaining) = u32::try_parse(remaining)?; let result = SelectEventsAuxBitcase3 { affect_ctrls, ctrl_details }; @@ -6536,6 +6786,11 @@ pub struct SelectEventsAuxBitcase4 { } impl TryParse for SelectEventsAuxBitcase4 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (affect_indicator_state, remaining) = u32::try_parse(remaining)?; let (indicator_state_details, remaining) = u32::try_parse(remaining)?; let result = SelectEventsAuxBitcase4 { affect_indicator_state, indicator_state_details }; @@ -6577,6 +6832,11 @@ pub struct SelectEventsAuxBitcase5 { } impl TryParse for SelectEventsAuxBitcase5 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (affect_indicator_map, remaining) = u32::try_parse(remaining)?; let (indicator_map_details, remaining) = u32::try_parse(remaining)?; let result = SelectEventsAuxBitcase5 { affect_indicator_map, indicator_map_details }; @@ -6618,6 +6878,11 @@ pub struct SelectEventsAuxBitcase6 { } impl TryParse for SelectEventsAuxBitcase6 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (affect_names, remaining) = u16::try_parse(remaining)?; let (names_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase6 { affect_names, names_details }; @@ -6655,6 +6920,11 @@ pub struct SelectEventsAuxBitcase7 { } impl TryParse for SelectEventsAuxBitcase7 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (affect_compat, remaining) = u8::try_parse(remaining)?; let (compat_details, remaining) = u8::try_parse(remaining)?; let result = SelectEventsAuxBitcase7 { affect_compat, compat_details }; @@ -6690,6 +6960,11 @@ pub struct SelectEventsAuxBitcase8 { } impl TryParse for SelectEventsAuxBitcase8 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (affect_bell, remaining) = u8::try_parse(remaining)?; let (bell_details, remaining) = u8::try_parse(remaining)?; let result = SelectEventsAuxBitcase8 { affect_bell, bell_details }; @@ -6725,6 +7000,11 @@ pub struct SelectEventsAuxBitcase9 { } impl TryParse for SelectEventsAuxBitcase9 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (affect_msg_details, remaining) = u8::try_parse(remaining)?; let (msg_details, remaining) = u8::try_parse(remaining)?; let result = SelectEventsAuxBitcase9 { affect_msg_details, msg_details }; @@ -6760,6 +7040,11 @@ pub struct SelectEventsAuxBitcase10 { } impl TryParse for SelectEventsAuxBitcase10 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (affect_access_x, remaining) = u16::try_parse(remaining)?; let (access_x_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase10 { affect_access_x, access_x_details }; @@ -6797,6 +7082,11 @@ pub struct SelectEventsAuxBitcase11 { } impl TryParse for SelectEventsAuxBitcase11 { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (affect_ext_dev, remaining) = u16::try_parse(remaining)?; let (extdev_details, remaining) = u16::try_parse(remaining)?; let result = SelectEventsAuxBitcase11 { affect_ext_dev, extdev_details }; @@ -7398,6 +7688,11 @@ pub struct GetStateReply { impl TryParse for GetStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7643,6 +7938,11 @@ pub struct GetControlsReply { impl TryParse for GetControlsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 92 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8204,6 +8504,11 @@ pub struct GetMapMapBitcase3 { } impl GetMapMapBitcase3 { pub fn try_parse(remaining: &[u8], n_key_actions: u8, total_actions: u16) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 0 { + return Err(ParseError::ParseError); + } let value = remaining; let (acts_rtrn_count, remaining) = crate::x11_utils::parse_u8_list(remaining, n_key_actions.try_into().or(Err(ParseError::ParseError))?)?; let acts_rtrn_count = acts_rtrn_count.to_vec(); @@ -8350,6 +8655,11 @@ pub struct GetMapReply { impl TryParse for GetMapReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8406,6 +8716,11 @@ pub struct SetMapAuxBitcase3 { } impl SetMapAuxBitcase3 { pub fn try_parse(remaining: &[u8], n_key_actions: u8, total_actions: u16) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 0 { + return Err(ParseError::ParseError); + } let value = remaining; let (actions_count, remaining) = crate::x11_utils::parse_u8_list(remaining, n_key_actions.try_into().or(Err(ParseError::ParseError))?)?; let actions_count = actions_count.to_vec(); @@ -8995,6 +9310,11 @@ pub struct GetCompatMapReply { impl TryParse for GetCompatMapReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9230,6 +9550,11 @@ pub struct GetIndicatorStateReply { impl TryParse for GetIndicatorStateReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9335,6 +9660,11 @@ pub struct GetIndicatorMapReply { impl TryParse for GetIndicatorMapReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9556,6 +9886,11 @@ pub struct GetNamedIndicatorReply { impl TryParse for GetNamedIndicatorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9842,6 +10177,11 @@ pub struct GetNamesValueListBitcase8 { } impl GetNamesValueListBitcase8 { pub fn try_parse(remaining: &[u8], n_types: u8) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 0 { + return Err(ParseError::ParseError); + } let value = remaining; let (n_levels_per_type, remaining) = crate::x11_utils::parse_u8_list(remaining, n_types.try_into().or(Err(ParseError::ParseError))?)?; let n_levels_per_type = n_levels_per_type.to_vec(); @@ -10013,6 +10353,11 @@ pub struct GetNamesReply { impl TryParse for GetNamesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10055,6 +10400,11 @@ pub struct SetNamesAuxBitcase8 { } impl SetNamesAuxBitcase8 { pub fn try_parse(remaining: &[u8], n_types: u8) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 0 { + return Err(ParseError::ParseError); + } let value = remaining; let (n_levels_per_type, remaining) = crate::x11_utils::parse_u8_list(remaining, n_types.try_into().or(Err(ParseError::ParseError))?)?; let n_levels_per_type = n_levels_per_type.to_vec(); @@ -10707,6 +11057,11 @@ pub struct PerClientFlagsReply { impl TryParse for PerClientFlagsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10813,6 +11168,11 @@ pub struct ListComponentsReply { impl TryParse for ListComponentsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11018,6 +11378,11 @@ pub struct GetKbdByNameRepliesTypesMapBitcase3 { } impl GetKbdByNameRepliesTypesMapBitcase3 { pub fn try_parse(remaining: &[u8], n_key_actions: u8, total_actions: u16) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 0 { + return Err(ParseError::ParseError); + } let value = remaining; let (acts_rtrn_count, remaining) = crate::x11_utils::parse_u8_list(remaining, n_key_actions.try_into().or(Err(ParseError::ParseError))?)?; let acts_rtrn_count = acts_rtrn_count.to_vec(); @@ -11164,6 +11529,11 @@ pub struct GetKbdByNameRepliesTypes { } impl TryParse for GetKbdByNameRepliesTypes { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (getmap_type, remaining) = u8::try_parse(remaining)?; let (type_device_id, remaining) = u8::try_parse(remaining)?; let (getmap_sequence, remaining) = u16::try_parse(remaining)?; @@ -11220,6 +11590,11 @@ pub struct GetKbdByNameRepliesCompatMap { } impl TryParse for GetKbdByNameRepliesCompatMap { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (compatmap_type, remaining) = u8::try_parse(remaining)?; let (compat_device_id, remaining) = u8::try_parse(remaining)?; let (compatmap_sequence, remaining) = u16::try_parse(remaining)?; @@ -11269,6 +11644,11 @@ pub struct GetKbdByNameRepliesIndicatorMaps { } impl TryParse for GetKbdByNameRepliesIndicatorMaps { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (indicatormap_type, remaining) = u8::try_parse(remaining)?; let (indicator_device_id, remaining) = u8::try_parse(remaining)?; let (indicatormap_sequence, remaining) = u16::try_parse(remaining)?; @@ -11310,6 +11690,11 @@ pub struct GetKbdByNameRepliesKeyNamesValueListBitcase8 { } impl GetKbdByNameRepliesKeyNamesValueListBitcase8 { pub fn try_parse(remaining: &[u8], n_types: u8) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 0 { + return Err(ParseError::ParseError); + } let value = remaining; let (n_levels_per_type, remaining) = crate::x11_utils::parse_u8_list(remaining, n_types.try_into().or(Err(ParseError::ParseError))?)?; let n_levels_per_type = n_levels_per_type.to_vec(); @@ -11481,6 +11866,11 @@ pub struct GetKbdByNameRepliesKeyNames { } impl TryParse for GetKbdByNameRepliesKeyNames { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (keyname_type, remaining) = u8::try_parse(remaining)?; let (key_device_id, remaining) = u8::try_parse(remaining)?; let (keyname_sequence, remaining) = u16::try_parse(remaining)?; @@ -11531,6 +11921,11 @@ pub struct GetKbdByNameRepliesGeometry { } impl TryParse for GetKbdByNameRepliesGeometry { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (geometry_type, remaining) = u8::try_parse(remaining)?; let (geometry_device_id, remaining) = u8::try_parse(remaining)?; let (geometry_sequence, remaining) = u16::try_parse(remaining)?; @@ -11627,6 +12022,11 @@ pub struct GetKbdByNameReply { impl TryParse for GetKbdByNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11782,6 +12182,11 @@ pub struct GetDeviceInfoReply { impl TryParse for GetDeviceInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 34 { + return Err(ParseError::ParseError); + } let value = remaining; let (response_type, remaining) = u8::try_parse(remaining)?; let (device_id, remaining) = u8::try_parse(remaining)?; @@ -12096,6 +12501,11 @@ pub struct SetDebuggingFlagsReply { impl TryParse for SetDebuggingFlagsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12143,6 +12553,11 @@ pub struct NewKeyboardNotifyEvent { impl TryParse for NewKeyboardNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12259,6 +12674,11 @@ pub struct MapNotifyEvent { impl TryParse for MapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12397,6 +12817,11 @@ pub struct StateNotifyEvent { impl TryParse for StateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12525,6 +12950,11 @@ pub struct ControlsNotifyEvent { impl TryParse for ControlsNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12625,6 +13055,11 @@ pub struct IndicatorStateNotifyEvent { impl TryParse for IndicatorStateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12713,6 +13148,11 @@ pub struct IndicatorMapNotifyEvent { impl TryParse for IndicatorMapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12811,6 +13251,11 @@ pub struct NamesNotifyEvent { impl TryParse for NamesNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12922,6 +13367,11 @@ pub struct CompatMapNotifyEvent { impl TryParse for CompatMapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13019,6 +13469,11 @@ pub struct BellNotifyEvent { impl TryParse for BellNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13123,6 +13578,11 @@ pub struct ActionMessageEvent { impl TryParse for ActionMessageEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13221,6 +13681,11 @@ pub struct AccessXNotifyEvent { impl TryParse for AccessXNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13319,6 +13784,11 @@ pub struct ExtensionDeviceNotifyEvent { impl TryParse for ExtensionDeviceNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (xkb_type, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xprint.rs b/src/protocol/xprint.rs index 072060f4..c819af55 100644 --- a/src/protocol/xprint.rs +++ b/src/protocol/xprint.rs @@ -44,6 +44,11 @@ pub struct Printer { } impl TryParse for Printer { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let value = remaining; let (name_len, remaining) = u32::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_into().or(Err(ParseError::ParseError))?)?; @@ -463,6 +468,11 @@ pub struct PrintQueryVersionReply { impl TryParse for PrintQueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -578,6 +588,11 @@ pub struct PrintGetPrinterListReply { impl TryParse for PrintGetPrinterListReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -874,6 +889,11 @@ pub struct PrintGetContextReply { impl TryParse for PrintGetContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1012,6 +1032,11 @@ pub struct PrintGetScreenOfContextReply { impl TryParse for PrintGetScreenOfContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1451,6 +1476,11 @@ pub struct PrintGetDocumentDataReply { impl TryParse for PrintGetDocumentDataReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1749,6 +1779,11 @@ pub struct PrintInputSelectedReply { impl TryParse for PrintInputSelectedReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1850,6 +1885,11 @@ pub struct PrintGetAttributesReply { impl TryParse for PrintGetAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1990,6 +2030,11 @@ pub struct PrintGetOneAttributesReply { impl TryParse for PrintGetOneAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2203,6 +2248,11 @@ pub struct PrintGetPageDimensionsReply { impl TryParse for PrintGetPageDimensionsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2287,6 +2337,11 @@ pub struct PrintQueryScreensReply { impl TryParse for PrintQueryScreensReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2404,6 +2459,11 @@ pub struct PrintSetImageResolutionReply { impl TryParse for PrintSetImageResolutionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2494,6 +2554,11 @@ pub struct PrintGetImageResolutionReply { impl TryParse for PrintGetImageResolutionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2529,6 +2594,11 @@ pub struct NotifyEvent { impl TryParse for NotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2609,6 +2679,11 @@ pub struct AttributNotifyEvent { impl TryParse for AttributNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2685,6 +2760,11 @@ pub struct BadContextError { impl TryParse for BadContextError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2762,6 +2842,11 @@ pub struct BadSequenceError { impl TryParse for BadSequenceError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xproto.rs b/src/protocol/xproto.rs index 06fff3e6..d00aa874 100644 --- a/src/protocol/xproto.rs +++ b/src/protocol/xproto.rs @@ -36,6 +36,11 @@ pub struct Char2b { } impl TryParse for Char2b { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 2 { + return Err(ParseError::ParseError); + } let (byte1, remaining) = u8::try_parse(remaining)?; let (byte2, remaining) = u8::try_parse(remaining)?; let result = Char2b { byte1, byte2 }; @@ -104,6 +109,11 @@ pub struct Point { } impl TryParse for Point { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let result = Point { x, y }; @@ -144,6 +154,11 @@ pub struct Rectangle { } impl TryParse for Rectangle { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; @@ -196,6 +211,11 @@ pub struct Arc { } impl TryParse for Arc { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; @@ -255,6 +275,11 @@ pub struct Format { } impl TryParse for Format { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (depth, remaining) = u8::try_parse(remaining)?; let (bits_per_pixel, remaining) = u8::try_parse(remaining)?; let (scanline_pad, remaining) = u8::try_parse(remaining)?; @@ -381,6 +406,11 @@ pub struct Visualtype { } impl TryParse for Visualtype { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (visual_id, remaining) = Visualid::try_parse(remaining)?; let (class, remaining) = u8::try_parse(remaining)?; let (bits_per_rgb_value, remaining) = u8::try_parse(remaining)?; @@ -457,6 +487,11 @@ pub struct Depth { } impl TryParse for Depth { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (visuals_len, remaining) = u16::try_parse(remaining)?; @@ -694,6 +729,11 @@ pub struct Screen { } impl TryParse for Screen { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (root, remaining) = Window::try_parse(remaining)?; let (default_colormap, remaining) = Colormap::try_parse(remaining)?; let (white_pixel, remaining) = u32::try_parse(remaining)?; @@ -777,6 +817,11 @@ pub struct SetupRequest { } impl TryParse for SetupRequest { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let value = remaining; let (byte_order, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -870,6 +915,11 @@ pub struct SetupFailed { } impl TryParse for SetupFailed { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (status, remaining) = u8::try_parse(remaining)?; let (reason_len, remaining) = u8::try_parse(remaining)?; let (protocol_major_version, remaining) = u16::try_parse(remaining)?; @@ -928,6 +978,11 @@ pub struct SetupAuthenticate { } impl TryParse for SetupAuthenticate { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(5..).ok_or(ParseError::ParseError)?; let (length, remaining) = u16::try_parse(remaining)?; @@ -1070,6 +1125,11 @@ pub struct Setup { } impl TryParse for Setup { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let value = remaining; let (status, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -1443,6 +1503,11 @@ pub struct KeyPressEvent { impl TryParse for KeyPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = Keycode::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1635,6 +1700,11 @@ pub struct ButtonPressEvent { impl TryParse for ButtonPressEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = Button::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1838,6 +1908,11 @@ pub struct MotionNotifyEvent { impl TryParse for MotionNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2108,6 +2183,11 @@ pub struct EnterNotifyEvent { impl TryParse for EnterNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2220,6 +2300,11 @@ pub struct FocusInEvent { impl TryParse for FocusInEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (detail, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2305,6 +2390,11 @@ pub struct KeymapNotifyEvent { impl TryParse for KeymapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (keys, remaining) = crate::x11_utils::parse_u8_list(remaining, 31)?; let keys = <[u8; 31]>::try_from(keys).unwrap(); @@ -2397,6 +2487,11 @@ pub struct ExposeEvent { impl TryParse for ExposeEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2491,6 +2586,11 @@ pub struct GraphicsExposureEvent { impl TryParse for GraphicsExposureEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2584,6 +2684,11 @@ pub struct NoExposureEvent { impl TryParse for NoExposureEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2731,6 +2836,11 @@ pub struct VisibilityNotifyEvent { impl TryParse for VisibilityNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2818,6 +2928,11 @@ pub struct CreateNotifyEvent { impl TryParse for CreateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2921,6 +3036,11 @@ pub struct DestroyNotifyEvent { impl TryParse for DestroyNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3014,6 +3134,11 @@ pub struct UnmapNotifyEvent { impl TryParse for UnmapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3109,6 +3234,11 @@ pub struct MapNotifyEvent { impl TryParse for MapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3201,6 +3331,11 @@ pub struct MapRequestEvent { impl TryParse for MapRequestEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3284,6 +3419,11 @@ pub struct ReparentNotifyEvent { impl TryParse for ReparentNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3401,6 +3541,11 @@ pub struct ConfigureNotifyEvent { impl TryParse for ConfigureNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3503,6 +3648,11 @@ pub struct ConfigureRequestEvent { impl TryParse for ConfigureRequestEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (stack_mode, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3600,6 +3750,11 @@ pub struct GravityNotifyEvent { impl TryParse for GravityNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3684,6 +3839,11 @@ pub struct ResizeRequestEvent { impl TryParse for ResizeRequestEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3852,6 +4012,11 @@ pub struct CirculateNotifyEvent { impl TryParse for CirculateNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4024,6 +4189,11 @@ pub struct PropertyNotifyEvent { impl TryParse for PropertyNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4110,6 +4280,11 @@ pub struct SelectionClearEvent { impl TryParse for SelectionClearEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4430,6 +4605,11 @@ pub struct SelectionRequestEvent { impl TryParse for SelectionRequestEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4520,6 +4700,11 @@ pub struct SelectionNotifyEvent { impl TryParse for SelectionNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -4753,6 +4938,11 @@ pub struct ColormapNotifyEvent { impl TryParse for ColormapNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5012,6 +5202,11 @@ pub struct ClientMessageEvent { impl TryParse for ClientMessageEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5166,6 +5361,11 @@ pub struct MappingNotifyEvent { impl TryParse for MappingNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5257,6 +5457,11 @@ pub struct GeGenericEvent { impl TryParse for GeGenericEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (extension, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5290,6 +5495,11 @@ pub struct RequestError { impl TryParse for RequestError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -5377,6 +5587,11 @@ pub struct ValueError { impl TryParse for ValueError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -7137,6 +7352,11 @@ pub struct GetWindowAttributesReply { impl TryParse for GetWindowAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 44 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (backing_store, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -8870,6 +9090,11 @@ pub struct GetGeometryReply { impl TryParse for GetGeometryReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9049,6 +9274,11 @@ pub struct QueryTreeReply { impl TryParse for QueryTreeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9267,6 +9497,11 @@ pub struct InternAtomReply { impl TryParse for InternAtomReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -9359,6 +9594,11 @@ pub struct GetAtomNameReply { impl TryParse for GetAtomNameReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10252,6 +10492,11 @@ pub struct GetPropertyReply { impl TryParse for GetPropertyReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (format, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10349,6 +10594,11 @@ pub struct ListPropertiesReply { impl TryParse for ListPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -10636,6 +10886,11 @@ pub struct GetSelectionOwnerReply { impl TryParse for GetSelectionOwnerReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -11548,6 +11803,11 @@ pub struct GrabPointerReply { impl TryParse for GrabPointerReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -12413,6 +12673,11 @@ pub struct GrabKeyboardReply { impl TryParse for GrabKeyboardReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13371,6 +13636,11 @@ pub struct QueryPointerReply { impl TryParse for QueryPointerReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13408,6 +13678,11 @@ pub struct Timecoord { } impl TryParse for Timecoord { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (time, remaining) = Timestamp::try_parse(remaining)?; let (x, remaining) = i16::try_parse(remaining)?; let (y, remaining) = i16::try_parse(remaining)?; @@ -13538,6 +13813,11 @@ pub struct GetMotionEventsReply { impl TryParse for GetMotionEventsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -13673,6 +13953,11 @@ pub struct TranslateCoordinatesReply { impl TryParse for TranslateCoordinatesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (same_screen, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14163,6 +14448,11 @@ pub struct GetInputFocusReply { impl TryParse for GetInputFocusReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (revert_to, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14245,6 +14535,11 @@ pub struct QueryKeymapReply { impl TryParse for QueryKeymapReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 40 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14529,6 +14824,11 @@ pub struct Fontprop { } impl TryParse for Fontprop { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (name, remaining) = Atom::try_parse(remaining)?; let (value, remaining) = u32::try_parse(remaining)?; let result = Fontprop { name, value }; @@ -14575,6 +14875,11 @@ pub struct Charinfo { } impl TryParse for Charinfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (left_side_bearing, remaining) = i16::try_parse(remaining)?; let (right_side_bearing, remaining) = i16::try_parse(remaining)?; let (character_width, remaining) = i16::try_parse(remaining)?; @@ -14734,6 +15039,11 @@ pub struct QueryFontReply { impl TryParse for QueryFontReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 60 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -14977,6 +15287,11 @@ pub struct QueryTextExtentsReply { impl TryParse for QueryTextExtentsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (draw_direction, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15012,6 +15327,11 @@ pub struct Str { } impl TryParse for Str { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 1 { + return Err(ParseError::ParseError); + } let (name_len, remaining) = u8::try_parse(remaining)?; let (name, remaining) = crate::x11_utils::parse_u8_list(remaining, name_len.try_into().or(Err(ParseError::ParseError))?)?; let name = name.to_vec(); @@ -15170,6 +15490,11 @@ pub struct ListFontsReply { impl TryParse for ListFontsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15351,6 +15676,11 @@ pub struct ListFontsWithInfoReply { impl TryParse for ListFontsWithInfoReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 60 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (name_len, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -15552,6 +15882,11 @@ pub struct GetFontPathReply { impl TryParse for GetFontPathReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -19076,6 +19411,11 @@ pub struct Segment { } impl TryParse for Segment { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (x1, remaining) = i16::try_parse(remaining)?; let (y1, remaining) = i16::try_parse(remaining)?; let (x2, remaining) = i16::try_parse(remaining)?; @@ -20179,6 +20519,11 @@ pub struct GetImageReply { impl TryParse for GetImageReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -21244,6 +21589,11 @@ pub struct ListInstalledColormapsReply { impl TryParse for ListInstalledColormapsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -21416,6 +21766,11 @@ pub struct AllocColorReply { impl TryParse for AllocColorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -21540,6 +21895,11 @@ pub struct AllocNamedColorReply { impl TryParse for AllocNamedColorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -21657,6 +22017,11 @@ pub struct AllocColorCellsReply { impl TryParse for AllocColorCellsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -21816,6 +22181,11 @@ pub struct AllocColorPlanesReply { impl TryParse for AllocColorPlanesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -22028,6 +22398,11 @@ pub struct Coloritem { } impl TryParse for Coloritem { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let (pixel, remaining) = u32::try_parse(remaining)?; let (red, remaining) = u16::try_parse(remaining)?; let (green, remaining) = u16::try_parse(remaining)?; @@ -22269,6 +22644,11 @@ pub struct Rgb { } impl TryParse for Rgb { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (red, remaining) = u16::try_parse(remaining)?; let (green, remaining) = u16::try_parse(remaining)?; let (blue, remaining) = u16::try_parse(remaining)?; @@ -22401,6 +22781,11 @@ pub struct QueryColorsReply { impl TryParse for QueryColorsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -22537,6 +22922,11 @@ pub struct LookupColorReply { impl TryParse for LookupColorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -23365,6 +23755,11 @@ pub struct QueryBestSizeReply { impl TryParse for QueryBestSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -23523,6 +23918,11 @@ pub struct QueryExtensionReply { impl TryParse for QueryExtensionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -23607,6 +24007,11 @@ pub struct ListExtensionsReply { impl TryParse for ListExtensionsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (names_len, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -23809,6 +24214,11 @@ pub struct GetKeyboardMappingReply { impl TryParse for GetKeyboardMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (keysyms_per_keycode, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -24399,6 +24809,11 @@ pub struct GetKeyboardControlReply { impl TryParse for GetKeyboardControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 52 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (global_auto_repeat, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -24631,6 +25046,11 @@ pub struct GetPointerControlReply { impl TryParse for GetPointerControlReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -24930,6 +25350,11 @@ pub struct GetScreenSaverReply { impl TryParse for GetScreenSaverReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -25192,6 +25617,11 @@ pub struct Host { } impl TryParse for Host { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 4 { + return Err(ParseError::ParseError); + } let value = remaining; let (family, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; @@ -25306,6 +25736,11 @@ pub struct ListHostsReply { impl TryParse for ListHostsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (mode, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -26112,6 +26547,11 @@ pub struct SetPointerMappingReply { impl TryParse for SetPointerMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -26193,6 +26633,11 @@ pub struct GetPointerMappingReply { impl TryParse for GetPointerMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (map_len, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -26389,6 +26834,11 @@ pub struct SetModifierMappingReply { impl TryParse for SetModifierMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (status, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -26470,6 +26920,11 @@ pub struct GetModifierMappingReply { impl TryParse for GetModifierMappingReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (keycodes_per_modifier, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xselinux.rs b/src/protocol/xselinux.rs index ca689735..191c4d70 100644 --- a/src/protocol/xselinux.rs +++ b/src/protocol/xselinux.rs @@ -109,6 +109,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -259,6 +264,11 @@ pub struct GetDeviceCreateContextReply { impl TryParse for GetDeviceCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -447,6 +457,11 @@ pub struct GetDeviceContextReply { impl TryParse for GetDeviceContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -614,6 +629,11 @@ pub struct GetWindowCreateContextReply { impl TryParse for GetWindowCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -722,6 +742,11 @@ pub struct GetWindowContextReply { impl TryParse for GetWindowContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -770,6 +795,11 @@ pub struct ListItem { } impl TryParse for ListItem { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let value = remaining; let (name, remaining) = xproto::Atom::try_parse(remaining)?; let (object_context_len, remaining) = u32::try_parse(remaining)?; @@ -972,6 +1002,11 @@ pub struct GetPropertyCreateContextReply { impl TryParse for GetPropertyCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1139,6 +1174,11 @@ pub struct GetPropertyUseContextReply { impl TryParse for GetPropertyUseContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1256,6 +1296,11 @@ pub struct GetPropertyContextReply { impl TryParse for GetPropertyContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1373,6 +1418,11 @@ pub struct GetPropertyDataContextReply { impl TryParse for GetPropertyDataContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1481,6 +1531,11 @@ pub struct ListPropertiesReply { impl TryParse for ListPropertiesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1647,6 +1702,11 @@ pub struct GetSelectionCreateContextReply { impl TryParse for GetSelectionCreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1814,6 +1874,11 @@ pub struct GetSelectionUseContextReply { impl TryParse for GetSelectionUseContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1922,6 +1987,11 @@ pub struct GetSelectionContextReply { impl TryParse for GetSelectionContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2030,6 +2100,11 @@ pub struct GetSelectionDataContextReply { impl TryParse for GetSelectionDataContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2127,6 +2202,11 @@ pub struct ListSelectionsReply { impl TryParse for ListSelectionsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2234,6 +2314,11 @@ pub struct GetClientContextReply { impl TryParse for GetClientContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xtest.rs b/src/protocol/xtest.rs index f5fba49d..f91d1e91 100644 --- a/src/protocol/xtest.rs +++ b/src/protocol/xtest.rs @@ -110,6 +110,11 @@ pub struct GetVersionReply { impl TryParse for GetVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (major_version, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -279,6 +284,11 @@ pub struct CompareCursorReply { impl TryParse for CompareCursorReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (same, remaining) = bool::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xv.rs b/src/protocol/xv.rs index d39b2aa3..20cb7824 100644 --- a/src/protocol/xv.rs +++ b/src/protocol/xv.rs @@ -538,6 +538,11 @@ pub struct Rational { } impl TryParse for Rational { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (numerator, remaining) = i32::try_parse(remaining)?; let (denominator, remaining) = i32::try_parse(remaining)?; let result = Rational { numerator, denominator }; @@ -580,6 +585,11 @@ pub struct Format { } impl TryParse for Format { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 8 { + return Err(ParseError::ParseError); + } let (visual, remaining) = xproto::Visualid::try_parse(remaining)?; let (depth, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(3..).ok_or(ParseError::ParseError)?; @@ -627,6 +637,11 @@ pub struct AdaptorInfo { } impl TryParse for AdaptorInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 12 { + return Err(ParseError::ParseError); + } let value = remaining; let (base_id, remaining) = Port::try_parse(remaining)?; let (name_size, remaining) = u16::try_parse(remaining)?; @@ -712,6 +727,11 @@ pub struct EncodingInfo { } impl TryParse for EncodingInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 20 { + return Err(ParseError::ParseError); + } let value = remaining; let (encoding, remaining) = Encoding::try_parse(remaining)?; let (name_size, remaining) = u16::try_parse(remaining)?; @@ -782,6 +802,11 @@ pub struct Image { } impl TryParse for Image { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let (id, remaining) = u32::try_parse(remaining)?; let (width, remaining) = u16::try_parse(remaining)?; let (height, remaining) = u16::try_parse(remaining)?; @@ -861,6 +886,11 @@ pub struct AttributeInfo { } impl TryParse for AttributeInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 16 { + return Err(ParseError::ParseError); + } let value = remaining; let (flags, remaining) = u32::try_parse(remaining)?; let (min, remaining) = i32::try_parse(remaining)?; @@ -943,6 +973,11 @@ pub struct ImageFormatInfo { } impl TryParse for ImageFormatInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 128 { + return Err(ParseError::ParseError); + } let (id, remaining) = u32::try_parse(remaining)?; let (type_, remaining) = u8::try_parse(remaining)?; let (byte_order, remaining) = u8::try_parse(remaining)?; @@ -1182,6 +1217,11 @@ pub struct BadPortError { impl TryParse for BadPortError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1259,6 +1299,11 @@ pub struct BadEncodingError { impl TryParse for BadEncodingError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1336,6 +1381,11 @@ pub struct BadControlError { impl TryParse for BadControlError { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (error_code, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1417,6 +1467,11 @@ pub struct VideoNotifyEvent { impl TryParse for VideoNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (reason, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1502,6 +1557,11 @@ pub struct PortNotifyEvent { impl TryParse for PortNotifyEvent { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1631,6 +1691,11 @@ pub struct QueryExtensionReply { impl TryParse for QueryExtensionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1722,6 +1787,11 @@ pub struct QueryAdaptorsReply { impl TryParse for QueryAdaptorsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1829,6 +1899,11 @@ pub struct QueryEncodingsReply { impl TryParse for QueryEncodingsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -1947,6 +2022,11 @@ pub struct GrabPortReply { impl TryParse for GrabPortReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let (result, remaining) = u8::try_parse(remaining)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -2884,6 +2964,11 @@ pub struct QueryBestSizeReply { impl TryParse for QueryBestSizeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3061,6 +3146,11 @@ pub struct GetPortAttributeReply { impl TryParse for GetPortAttributeReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3152,6 +3242,11 @@ pub struct QueryPortAttributesReply { impl TryParse for QueryPortAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3260,6 +3355,11 @@ pub struct ListImageFormatsReply { impl TryParse for ListImageFormatsReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -3394,6 +3494,11 @@ pub struct QueryImageAttributesReply { impl TryParse for QueryImageAttributesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; diff --git a/src/protocol/xvmc.rs b/src/protocol/xvmc.rs index be1d1a1b..c6895373 100644 --- a/src/protocol/xvmc.rs +++ b/src/protocol/xvmc.rs @@ -55,6 +55,11 @@ pub struct SurfaceInfo { } impl TryParse for SurfaceInfo { fn try_parse(remaining: &[u8]) -> Result<(Self, &[u8]), ParseError> { + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 24 { + return Err(ParseError::ParseError); + } let (id, remaining) = Surface::try_parse(remaining)?; let (chroma_format, remaining) = u16::try_parse(remaining)?; let (pad0, remaining) = u16::try_parse(remaining)?; @@ -185,6 +190,11 @@ pub struct QueryVersionReply { impl TryParse for QueryVersionReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -276,6 +286,11 @@ pub struct ListSurfaceTypesReply { impl TryParse for ListSurfaceTypesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -426,6 +441,11 @@ pub struct CreateContextReply { impl TryParse for CreateContextReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 36 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -602,6 +622,11 @@ pub struct CreateSurfaceReply { impl TryParse for CreateSurfaceReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -803,6 +828,11 @@ pub struct CreateSubpictureReply { impl TryParse for CreateSubpictureReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?; @@ -983,6 +1013,11 @@ pub struct ListSubpictureTypesReply { impl TryParse for ListSubpictureTypesReply { fn try_parse(initial_value: &[u8]) -> Result<(Self, &[u8]), ParseError> { let remaining = initial_value; + // Check that enough bytes for the minimum possible size is available. + // This allows the compiler to optimise away some length checks. + if remaining.len() < 32 { + return Err(ParseError::ParseError); + } let (response_type, remaining) = u8::try_parse(remaining)?; let remaining = remaining.get(1..).ok_or(ParseError::ParseError)?; let (sequence, remaining) = u16::try_parse(remaining)?;