mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-16 09:21:01 +03:00
Validate and decode cursor packets at the Rust receive boundary
This commit is contained in:
@@ -1508,7 +1508,11 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
_ => {}
|
||||
},
|
||||
Some(message::Union::CursorData(cd)) => {
|
||||
self.handler.set_cursor_data(cd);
|
||||
let id = cd.id;
|
||||
match decode_cursor_data(cd) {
|
||||
Ok(cd) => self.handler.set_cursor_data(cd),
|
||||
Err(err) => log::warn!("Rejected cursor {id}: {err}"),
|
||||
}
|
||||
}
|
||||
Some(message::Union::CursorId(id)) => {
|
||||
self.handler.set_cursor_id(id.to_string());
|
||||
@@ -2542,6 +2546,37 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// Both UI handlers receive validated, uncompressed RGBA from the receive loop.
|
||||
fn decode_cursor_data(data: CursorData) -> hbb_common::ResultType<CursorData> {
|
||||
use hbb_common::{anyhow::anyhow, bail};
|
||||
|
||||
const MAX_CURSOR_SIZE: i32 = 4096;
|
||||
const RGBA_CHANNELS: usize = 4;
|
||||
|
||||
let mut cd = data;
|
||||
// Sciter keeps the legacy outer image; Flutter uses the physical variant.
|
||||
#[cfg(feature = "flutter")]
|
||||
if let Some(physical) = cd.high_resolution.take() {
|
||||
cd = physical;
|
||||
}
|
||||
if !(1..=MAX_CURSOR_SIZE).contains(&cd.width) || !(1..=MAX_CURSOR_SIZE).contains(&cd.height) {
|
||||
bail!("invalid source size {}x{}", cd.width, cd.height);
|
||||
}
|
||||
let expected = (cd.width as usize)
|
||||
.checked_mul(cd.height as usize)
|
||||
.and_then(|pixels| pixels.checked_mul(RGBA_CHANNELS))
|
||||
.ok_or_else(|| anyhow!("cursor RGBA size overflow"))?;
|
||||
let colors = zstd::bulk::decompress(&cd.colors, expected)?;
|
||||
if colors.len() != expected {
|
||||
bail!(
|
||||
"invalid RGBA length: expected {expected}, got {}",
|
||||
colors.len()
|
||||
);
|
||||
}
|
||||
cd.colors = colors.into();
|
||||
Ok(cd)
|
||||
}
|
||||
|
||||
struct RemoveJob {
|
||||
files: Vec<FileEntry>,
|
||||
path: String,
|
||||
|
||||
@@ -642,8 +642,7 @@ impl FlutterHandler {
|
||||
|
||||
impl InvokeUiSession for FlutterHandler {
|
||||
fn set_cursor_data(&self, cd: CursorData) {
|
||||
let cd = cd.high_resolution.as_ref().unwrap_or(&cd);
|
||||
let colors = hbb_common::compress::decompress(&cd.colors);
|
||||
let colors = &cd.colors;
|
||||
self.push_event(
|
||||
"cursor_data",
|
||||
&[
|
||||
|
||||
@@ -122,7 +122,7 @@ impl SciterHandler {
|
||||
|
||||
impl InvokeUiSession for SciterHandler {
|
||||
fn set_cursor_data(&self, cd: CursorData) {
|
||||
let mut colors = hbb_common::compress::decompress(&cd.colors);
|
||||
let mut colors: Vec<u8> = cd.colors.into();
|
||||
if colors.iter().filter(|x| **x != 0).next().is_none() {
|
||||
log::info!("Fix transparent");
|
||||
// somehow all 0 images shows black rect, here is a workaround
|
||||
|
||||
Reference in New Issue
Block a user