fix(rdp): clipboard only on explicit paste, size check before allocation, bounded device I/O

- The local clipboard was offered to the RDP server every time the
  desktop gained focus, so any server could read the last thing copied
  (a password, a token) without a paste. It now goes only on Ctrl/Cmd+V
  or Paste Clipboard.
- The server-chosen desktop size is checked before DecodedImage
  allocates it (65535x65535 is 16 GiB, and allocation failure aborts the
  whole app), at connect and on reactivation.
- Drive reads are clamped to 8 MiB per request (the native backend
  allocated the server's u32 length up front).
- Print jobs get unique files created exclusively (same-second jobs used
  to truncate each other) and at most 4 may be open at once.
This commit is contained in:
Andy Dixon
2026-10-13 06:49:13 +01:00
parent 7f3704e890
commit eb8f08a182
4 changed files with 37 additions and 16 deletions
+4 -2
View File
@@ -259,8 +259,10 @@ impl Client {
fn run(&self, mut framed: Framed<Tls>, result: ConnectionResult, rx: Receiver<Input>) -> Result<()> {
framed.get_inner_mut().0.sock.set_read_timeout(Some(POLL))?;
let size = result.desktop_size;
let mut image = DecodedImage::new(PixelFormat::RgbA32, size.width, size.height);
// Check the server-chosen size before DecodedImage allocates it (65535² is 16 GiB, and
// an allocation failure aborts the whole app rather than failing this session).
*self.fb.lock() = Framebuffer::new_checked(size.width, size.height)?;
let mut image = DecodedImage::new(PixelFormat::RgbA32, size.width, size.height);
let factory = result.activation_factory;
let mut stage = ActiveStageBuilder {
static_channels: result.static_channels,
@@ -349,8 +351,8 @@ impl Client {
if let ConnectionActivationState::Finalized { desktop_size, share_id, enable_server_pointer, pointer_software_rendering } =
seq.connection_activation_state()
{
image = DecodedImage::new(PixelFormat::RgbA32, desktop_size.width, desktop_size.height);
*self.fb.lock() = Framebuffer::new_checked(desktop_size.width, desktop_size.height)?;
image = DecodedImage::new(PixelFormat::RgbA32, desktop_size.width, desktop_size.height);
stage.set_fastpath_processor(
fast_path::ProcessorBuilder {
io_channel_id: seq.io_channel_id(),