Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/ironrdp-ainput/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ impl<'de> Decode<'de> for ServerPdu {
fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
ensure_fixed_part_size!(in: src);

let pdu_type =
ServerPduType::from_u16(src.read_u16()).ok_or_else(|| invalid_field_err!("pduType", "invalid pdu type"))?;
let pdu_type = ServerPduType::from_u16(src.read_u16())
.ok_or_else(|| invalid_field_err!("pduType", "invalid pdu type", in: src))?;

let server_pdu = match pdu_type {
ServerPduType::Version => ServerPdu::Version(VersionPdu::decode(src)?),
Expand Down Expand Up @@ -256,8 +256,8 @@ impl<'de> Decode<'de> for ClientPdu {
fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
ensure_fixed_part_size!(in: src);

let pdu_type =
ClientPduType::from_u16(src.read_u16()).ok_or_else(|| invalid_field_err!("pduType", "invalid pdu type"))?;
let pdu_type = ClientPduType::from_u16(src.read_u16())
.ok_or_else(|| invalid_field_err!("pduType", "invalid pdu type", in: src))?;

let client_pdu = match pdu_type {
ClientPduType::Mouse => ClientPdu::Mouse(MousePdu::decode(src)?),
Expand Down
21 changes: 11 additions & 10 deletions crates/ironrdp-cliprdr-format/src/bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,19 +243,20 @@ impl BitmapInfoHeader {

let width = src.read_i32();
check_invariant(width != i32::MIN && width.abs() <= 10_000)
.ok_or_else(|| invalid_field_err!("biWidth", "width is too big"))?;
.ok_or_else(|| invalid_field_err!("biWidth", "width is too big", in: src))?;

let height = src.read_i32();
check_invariant(height != i32::MIN && height.abs() <= 10_000)
.ok_or_else(|| invalid_field_err!("biHeight", "height is too big"))?;
.ok_or_else(|| invalid_field_err!("biHeight", "height is too big", in: src))?;

let planes = src.read_u16();
if planes != 1 {
return Err(invalid_field_err!("biPlanes", "invalid planes count"));
return Err(invalid_field_err!("biPlanes", "invalid planes count", in: src));
}

let bit_count = src.read_u16();
check_invariant(bit_count <= 32).ok_or_else(|| invalid_field_err!("biBitCount", "invalid bit count"))?;
check_invariant(bit_count <= 32)
.ok_or_else(|| invalid_field_err!("biBitCount", "invalid bit count", in: src))?;

let compression = BitmapCompression(src.read_u32());
let size_image = src.read_u32();
Expand Down Expand Up @@ -301,7 +302,7 @@ impl BitmapInfoHeader {

impl Encode for BitmapInfoHeader {
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
let size = cast_int!("biSize", Self::FIXED_PART_SIZE)?;
let size = cast_int!("biSize", Self::FIXED_PART_SIZE, in: dst)?;
self.encode_with_size(dst, size)
}

Expand All @@ -317,10 +318,10 @@ impl Encode for BitmapInfoHeader {
impl<'a> Decode<'a> for BitmapInfoHeader {
fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
let (header, size) = Self::decode_with_size(src)?;
let size: usize = cast_int!("biSize", size)?;
let size: usize = cast_int!("biSize", size, in: src)?;

if size != Self::FIXED_PART_SIZE {
return Err(invalid_field_err!("biSize", "invalid V1 bitmap info header size"));
return Err(invalid_field_err!("biSize", "invalid V1 bitmap info header size", in: src));
}

Ok(header)
Expand Down Expand Up @@ -369,7 +370,7 @@ impl Encode for BitmapV5Header {
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
ensure_fixed_part_size!(in: dst);

let size = cast_int!("biSize", Self::FIXED_PART_SIZE)?;
let size = cast_int!("biSize", Self::FIXED_PART_SIZE, in: dst)?;
self.v1.encode_with_size(dst, size)?;

dst.write_u32(self.red_mask);
Expand Down Expand Up @@ -403,10 +404,10 @@ impl<'a> Decode<'a> for BitmapV5Header {
ensure_fixed_part_size!(in: src);

let (header_v1, size) = BitmapInfoHeader::decode_with_size(src)?;
let size: usize = cast_int!("biSize", size)?;
let size: usize = cast_int!("biSize", size, in: src)?;

if size != Self::FIXED_PART_SIZE {
return Err(invalid_field_err!("biSize", "invalid V5 bitmap info header size"));
return Err(invalid_field_err!("biSize", "invalid V5 bitmap info header size", in: src));
}

let red_mask = src.read_u32();
Expand Down
12 changes: 5 additions & 7 deletions crates/ironrdp-cliprdr/src/pdu/capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ impl Capabilities {

impl Encode for Capabilities {
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
let header = PartialHeader::new(cast_int!("dataLen", self.inner_size())?);
let header = PartialHeader::new(cast_int!("dataLen", self.inner_size(), in: dst)?);
header.encode(dst)?;

ensure_size!(in: dst, size: self.inner_size());

dst.write_u16(cast_length!(Self::NAME, "cCapabilitiesSets", self.capabilities.len())?);
dst.write_u16(cast_length!(Self::NAME, "cCapabilitiesSets", self.capabilities.len(), in: dst)?);
write_padding!(dst, 2);

for capability in &self.capabilities {
Expand Down Expand Up @@ -141,7 +141,7 @@ impl Encode for CapabilitySet {

ensure_size!(in: dst, size: length);
dst.write_u16(Self::CAPSTYPE_GENERAL);
dst.write_u16(cast_int!("lengthCapability", length)?);
dst.write_u16(cast_int!("lengthCapability", length, in: dst)?);
caps.encode(dst)
}

Expand Down Expand Up @@ -170,10 +170,8 @@ impl<'de> Decode<'de> for CapabilitySet {
let general = GeneralCapabilitySet::decode(src)?;
Ok(Self::General(general))
}
_ => Err(invalid_field_err!(
"capabilitySetType",
"invalid clipboard capability set type"
)),
_ => Err(invalid_field_err!( "capabilitySetType",
"invalid clipboard capability set type", in: src)),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/ironrdp-cliprdr/src/pdu/client_temporary_directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ impl ClientTemporaryDirectory<'_> {
let mut cursor = ReadCursor::new(&self.path_buffer);

read_string_from_cursor(&mut cursor, CharacterSet::Unicode, true)
.map_err(|_| invalid_field_err!("wszTempDir", "failed to decode temp dir path"))
.map_err(|_| invalid_field_err!("wszTempDir", "failed to decode temp dir path", at: 0))
}
}

impl Encode for ClientTemporaryDirectory<'_> {
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
let header = PartialHeader::new(cast_int!("dataLen", Self::INNER_SIZE)?);
let header = PartialHeader::new(cast_int!("dataLen", Self::INNER_SIZE, in: dst)?);
header.encode(dst)?;

ensure_size!(in: dst, size: Self::INNER_SIZE);
Expand Down
43 changes: 18 additions & 25 deletions crates/ironrdp-cliprdr/src/pdu/file_contents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,15 @@ impl<'a> FileContentsResponse<'a> {
/// Should not panic - the try_into conversion is guaranteed to succeed after length validation.
pub fn data_as_size(&self) -> DecodeResult<u64> {
if self.data.len() != 8 {
return Err(invalid_field_err!(
"requestedFileContentsData",
"SIZE response must be exactly 8 bytes per MS-RDPECLIP 2.2.5.4"
));
return Err(invalid_field_err!( "requestedFileContentsData",
"SIZE response must be exactly 8 bytes per MS-RDPECLIP 2.2.5.4", at: 0));
}

// Per length check above, this conversion is infallible.
let chunk: [u8; 8] = self
.data
.as_ref()
.try_into()
.map_err(|_| invalid_field_err!("requestedFileContentsData", "SIZE response data is not 8 bytes"))?;
let chunk: [u8; 8] =
self.data.as_ref().try_into().map_err(
|_| invalid_field_err!("requestedFileContentsData", "SIZE response data is not 8 bytes", at: 0),
)?;
Ok(u64::from_le_bytes(chunk))
}
}
Expand All @@ -153,7 +150,7 @@ impl Encode for FileContentsResponse<'_> {
ClipboardPduFlags::RESPONSE_OK
};

let header = PartialHeader::new_with_flags(cast_int!("dataLen", self.inner_size())?, flags);
let header = PartialHeader::new_with_flags(cast_int!("dataLen", self.inner_size(), in: dst)?, flags);
header.encode(dst)?;

ensure_size!(in: dst, size: self.inner_size());
Expand Down Expand Up @@ -182,7 +179,7 @@ impl<'de> Decode<'de> for FileContentsResponse<'de> {
ensure_size!(in: src, size: header.data_length());

if header.data_length() < Self::FIXED_PART_SIZE {
return Err(invalid_field_err!("requestedFileContentsData", "invalid data size"));
return Err(invalid_field_err!("requestedFileContentsData", "invalid data size", in: src));
};

let data_size = header.data_length() - Self::FIXED_PART_SIZE;
Expand Down Expand Up @@ -233,7 +230,7 @@ impl Encode for FileContentsRequest {
/// Callers that build these PDUs are responsible for setting fields correctly;
/// use [`FileContentsFlags::validate`] to check flag consistency.
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
let header = PartialHeader::new(cast_int!("dataLen", self.inner_size())?);
let header = PartialHeader::new(cast_int!("dataLen", self.inner_size(), in: dst)?);
header.encode(dst)?;

ensure_size!(in: dst, size: self.inner_size());
Expand Down Expand Up @@ -287,28 +284,24 @@ impl<'de> Decode<'de> for FileContentsRequest {

// [MS-RDPECLIP] 2.2.5.3 - Validate lindex is non-negative
if index < 0 {
return Err(invalid_field_err!(
"lindex",
"file index must be non-negative per MS-RDPECLIP 2.2.5.3"
));
return Err(invalid_field_err!( "lindex",
"file index must be non-negative per MS-RDPECLIP 2.2.5.3", in: src));
}

// [MS-RDPECLIP] 2.2.5.3 - Validate flags are spec-compliant
flags.validate().map_err(|e| invalid_field_err!("dwFlags", e))?;
flags
.validate()
.map_err(|e| invalid_field_err!("dwFlags", e, in: src))?;

// [MS-RDPECLIP] 2.2.5.3 - Validate SIZE request constraints
if flags.contains(FileContentsFlags::SIZE) {
if requested_size != 8 {
return Err(invalid_field_err!(
"cbRequested",
"SIZE request must have cbRequested=8 per MS-RDPECLIP 2.2.5.3"
));
return Err(invalid_field_err!( "cbRequested",
"SIZE request must have cbRequested=8 per MS-RDPECLIP 2.2.5.3", in: src));
}
if position != 0 {
return Err(invalid_field_err!(
"position",
"SIZE request must have position=0 per MS-RDPECLIP 2.2.5.3"
));
return Err(invalid_field_err!( "position",
"SIZE request must have position=0 per MS-RDPECLIP 2.2.5.3", in: src));
}
}

Expand Down
19 changes: 7 additions & 12 deletions crates/ironrdp-cliprdr/src/pdu/format_data/file_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,11 @@ impl Encode for FileDescriptor {
// UTF-16 encoding: each code unit is 2 bytes, plus 2 bytes for null terminator.
let encoded_len = wire_name.encode_utf16().count() * 2 + 2;
if NAME_LENGTH < encoded_len {
return Err(ironrdp_core::invalid_field_err!(
"cFileName",
"encoded wire name exceeds NAME_LENGTH (520 bytes)"
));
return Err(ironrdp_core::invalid_field_err!( "cFileName",
"encoded wire name exceeds NAME_LENGTH (520 bytes)", in: dst));
}

let written = encode_string(dst.remaining_mut(), &wire_name, CharacterSet::Unicode, true)?;
dst.advance(written);
let written = encode_string(dst, &wire_name, CharacterSet::Unicode, true)?;

// Pad with zeroes, overriding any previously written data
write_padding!(dst, NAME_LENGTH - written);
Expand Down Expand Up @@ -280,7 +277,7 @@ impl Encode for PackedFileList {
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
ensure_fixed_part_size!(in: dst);

dst.write_u32(cast_length!(Self::NAME, "cItems", self.files.len())?);
dst.write_u32(cast_length!(Self::NAME, "cItems", self.files.len(), in: dst)?);

for file in &self.files {
file.encode(dst)?;
Expand All @@ -301,13 +298,11 @@ impl Encode for PackedFileList {
impl<'de> Decode<'de> for PackedFileList {
fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
ensure_fixed_part_size!(in: src);
let file_count: usize = cast_length!(Self::NAME, "cItems", src.read_u32())?;
let file_count: usize = cast_length!(Self::NAME, "cItems", src.read_u32(), in: src)?;

if MAX_FILE_COUNT < file_count {
return Err(ironrdp_core::invalid_field_err!(
"cItems",
"file count exceeds maximum of 100000"
));
return Err(ironrdp_core::invalid_field_err!( "cItems",
"file count exceeds maximum of 100000", in: src));
}

// Cap pre-allocation against remaining bytes to prevent OOM from
Expand Down
4 changes: 2 additions & 2 deletions crates/ironrdp-cliprdr/src/pdu/format_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl Encode for FormatDataResponse<'_> {
ClipboardPduFlags::RESPONSE_OK
};

let header = PartialHeader::new_with_flags(cast_int!("dataLen", self.data.len())?, flags);
let header = PartialHeader::new_with_flags(cast_int!("dataLen", self.data.len(), in: dst)?, flags);
header.encode(dst)?;

ensure_size!(in: dst, size: self.data.len());
Expand Down Expand Up @@ -228,7 +228,7 @@ impl FormatDataRequest {

impl Encode for FormatDataRequest {
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
let header = PartialHeader::new(cast_int!("dataLen", Self::FIXED_PART_SIZE)?);
let header = PartialHeader::new(cast_int!("dataLen", Self::FIXED_PART_SIZE, in: dst)?);
header.encode(dst)?;

ensure_fixed_part_size!(in: dst);
Expand Down
5 changes: 3 additions & 2 deletions crates/ironrdp-cliprdr/src/pdu/format_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ impl Encode for FormatList<'_> {
ClipboardPduFlags::empty()
};

let header = PartialHeader::new_with_flags(cast_int!("dataLen", self.encoded_formats.len())?, header_flags);
let header =
PartialHeader::new_with_flags(cast_int!("dataLen", self.encoded_formats.len(), in: dst)?, header_flags);
header.encode(dst)?;

ensure_size!(in: dst, size: self.encoded_formats.len());
Expand Down Expand Up @@ -457,7 +458,7 @@ impl<'de> Decode<'de> for FormatListResponse {
match header.message_flags {
ClipboardPduFlags::RESPONSE_OK => Ok(FormatListResponse::Ok),
ClipboardPduFlags::RESPONSE_FAIL => Ok(FormatListResponse::Fail),
_ => Err(invalid_field_err!("msgFlags", "invalid format list message flags")),
_ => Err(invalid_field_err!("msgFlags", "invalid format list message flags", in: src)),
}
}
}
2 changes: 1 addition & 1 deletion crates/ironrdp-cliprdr/src/pdu/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl LockDataId {

impl Encode for LockDataId {
fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
let header = PartialHeader::new(cast_int!("dataLen", Self::FIXED_PART_SIZE)?);
let header = PartialHeader::new(cast_int!("dataLen", Self::FIXED_PART_SIZE, in: dst)?);
header.encode(dst)?;

ensure_fixed_part_size!(in: dst);
Expand Down
2 changes: 1 addition & 1 deletion crates/ironrdp-cliprdr/src/pdu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl<'de> Decode<'de> for ClipboardPdu<'de> {
MSG_TYPE_FILE_CONTENTS_RESPONSE => ClipboardPdu::FileContentsResponse(FileContentsResponse::decode(src)?),
MSG_TYPE_LOCK_CLIPDATA => ClipboardPdu::LockData(LockDataId::decode(src)?),
MSG_TYPE_UNLOCK_CLIPDATA => ClipboardPdu::UnlockData(LockDataId::decode(src)?),
_ => return Err(invalid_field_err!("msgType", "unknown clipboard PDU type")),
_ => return Err(invalid_field_err!("msgType", "unknown clipboard PDU type", in: src)),
};

Ok(pdu)
Expand Down
Loading
Loading