From 94dc663361a330f0da3ea7ca0cc748da5e5166ce Mon Sep 17 00:00:00 2001 From: Austin Schey Date: Sun, 15 Dec 2024 11:48:41 -0800 Subject: [PATCH] fix: prevent infinite loop when event read hangs --- src/cursor/sys/unix.rs | 12 ++++++++++-- src/terminal/sys/unix.rs | 15 ++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/cursor/sys/unix.rs b/src/cursor/sys/unix.rs index 473421207..8290e9550 100644 --- a/src/cursor/sys/unix.rs +++ b/src/cursor/sys/unix.rs @@ -1,6 +1,6 @@ use std::{ io::{self, Error, ErrorKind, Write}, - time::Duration, + time::{Duration, Instant}, }; use crate::{ @@ -35,8 +35,10 @@ fn read_position_raw() -> io::Result<(u16, u16)> { stdout.write_all(b"\x1B[6n")?; stdout.flush()?; + let poll_timeout = Duration::from_millis(2000); + let poll_start = Instant::now(); loop { - match poll_internal(Some(Duration::from_millis(2000)), &CursorPositionFilter) { + match poll_internal(Some(poll_timeout), &CursorPositionFilter) { Ok(true) => { if let Ok(InternalEvent::CursorPosition(x, y)) = read_internal(&CursorPositionFilter) @@ -50,6 +52,12 @@ fn read_position_raw() -> io::Result<(u16, u16)> { "The cursor position could not be read within a normal duration", )); } + Err(e) if Instant::now() - poll_start > poll_timeout => { + return Err(io::Error::new( + e.kind(), + format!("Error reading cursor position: {e:?}"), + )); + } Err(_) => {} } } diff --git a/src/terminal/sys/unix.rs b/src/terminal/sys/unix.rs index 7129730a6..61017e613 100644 --- a/src/terminal/sys/unix.rs +++ b/src/terminal/sys/unix.rs @@ -205,8 +205,8 @@ fn read_supports_keyboard_enhancement_raw() -> io::Result { filter::{KeyboardEnhancementFlagsFilter, PrimaryDeviceAttributesFilter}, poll_internal, read_internal, InternalEvent, }; - use std::io::Write; use std::time::Duration; + use std::{io::Write, time::Instant}; // This is the recommended method for testing support for the keyboard enhancement protocol. // We send a query for the flags supported by the terminal and then the primary device attributes @@ -229,11 +229,10 @@ fn read_supports_keyboard_enhancement_raw() -> io::Result { stdout.flush()?; } + let poll_timeout = Duration::from_millis(2000); + let poll_start = Instant::now(); loop { - match poll_internal( - Some(Duration::from_millis(2000)), - &KeyboardEnhancementFlagsFilter, - ) { + match poll_internal(Some(poll_timeout), &KeyboardEnhancementFlagsFilter) { Ok(true) => { match read_internal(&KeyboardEnhancementFlagsFilter) { Ok(InternalEvent::KeyboardEnhancementFlags(_current_flags)) => { @@ -250,6 +249,12 @@ fn read_supports_keyboard_enhancement_raw() -> io::Result { "The keyboard enhancement status could not be read within a normal duration", )); } + Err(e) if Instant::now() - poll_start > poll_timeout => { + return Err(io::Error::new( + e.kind(), + format!("Error reading keyboard enhancement status: {e:?}"), + )); + } Err(_) => {} } }