From 2dce288aa4d071ddb4cf6e0772281055834342ae Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 19 Jun 2020 15:36:58 +0200 Subject: [PATCH] Add early length checks to TryParse implementations Most TryParse implementations that we have contain a series of calls to other try_parse() implementations. Most of these are for primitive types, e.g. u32. Thus, some rough sketch of the code is this: let (a, remaining) = u32::try_parse(remaining)?; let (b, remaining) = u32::try_parse(remaining)?; let (c, remaining) = u32::try_parse(remaining)?; let (d, remaining) = u32::try_parse(remaining)?; This is relatively readable code. We do not have to mess round with byte offsets or something like that. However, every single call to u32::try_parse() checks if there are another 32 bit of data available. This leads to lots of repetitions in the assembly code, because these length checks are not merged. This commit changes the code generator to compute the minimum size that some object can have on the wire. This minimum size is the sum of all fixed-size data. Basically, this means that lists are assumed to be empty. Then, the generated code checks if at least the minimum number of bytes is available. If not, an early returns is done. This early length check allows the compiler (in release mode) to optimise away most later length checks, thus resulting in less assembly code. The effect of this commit was measured in two ways. 1. "cargo rustc --release -- --Copt-level=s --emit asm" allows to get an assembly file for the library. Before this commit, this assembly file has 159662 lines. Afterwards, it has 157796 lines. This is a reduction of about 1.2 %. 2. "cargo build --release --example xclock_utc" and calling "strip" on the resulting binary previously produced a file with 503 KiB. After this commit, the file has only 499 KiB. Thus, about 4 KiB or 1 % is saved. Related-to: https://github.com/psychon/x11rb/issues/488 Signed-off-by: Uli Schlachter --- generator/src/generator/namespace.rs | 16 + src/protocol/bigreq.rs | 5 + src/protocol/composite.rs | 10 + src/protocol/damage.rs | 15 + src/protocol/dpms.rs | 20 + src/protocol/dri2.rs | 75 +++ src/protocol/dri3.rs | 30 ++ src/protocol/ge.rs | 5 + src/protocol/glx.rs | 350 ++++++++++++ src/protocol/present.rs | 40 ++ src/protocol/randr.rs | 215 ++++++++ src/protocol/record.rs | 45 ++ src/protocol/render.rs | 125 +++++ src/protocol/res.rs | 65 +++ src/protocol/screensaver.rs | 15 + src/protocol/shape.rs | 25 + src/protocol/shm.rs | 20 + src/protocol/sync.rs | 70 +++ src/protocol/xc_misc.rs | 15 + src/protocol/xevie.rs | 30 ++ src/protocol/xf86dri.rs | 50 ++ src/protocol/xf86vidmode.rs | 95 ++++ src/protocol/xfixes.rs | 40 ++ src/protocol/xinerama.rs | 35 ++ src/protocol/xinput.rs | 765 +++++++++++++++++++++++++++ src/protocol/xkb.rs | 470 ++++++++++++++++ src/protocol/xprint.rs | 85 +++ src/protocol/xproto.rs | 455 ++++++++++++++++ src/protocol/xselinux.rs | 85 +++ src/protocol/xtest.rs | 10 + src/protocol/xv.rs | 105 ++++ src/protocol/xvmc.rs | 35 ++ 32 files changed, 3421 insertions(+) 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)?;