From 1e32f5d480ecefa3a1c8fd1c43ac6b4260459266 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Sat, 13 Jan 2024 12:31:42 -0800 Subject: Reject files with invalid utf-8. It's easier to only support files with valid utf-8. --- src/term.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src/term.rs') diff --git a/src/term.rs b/src/term.rs index e390125..831cd43 100644 --- a/src/term.rs +++ b/src/term.rs @@ -1,6 +1,6 @@ use libc::{termios, winsize}; use std::error::Error; -use std::io::{stdout, BufRead, BufReader, Stdin, Write}; +use std::io::{stdout, BufRead, BufReader, Read, Stdin, Write}; const ESC: u8 = 27; @@ -83,7 +83,7 @@ pub enum Key { End, PgDn, PgUp, - Byte(u8), + Char(char), } pub struct Reader { @@ -110,9 +110,21 @@ impl Reader { return Ok(Key::Timeout); } if buf[0] != ESC { - let b = buf[0]; - self.stdin.consume(1); - return Ok(Key::Byte(b)); + let mut n = usize::try_from(buf[0].leading_ones()) + .expect("buf[0] is a u8 so it can only have 8 leading ones"); + if n == 0 { + n = 1; + } + let mut char = [0; 4]; + self.stdin.read_exact(&mut char[..n])?; + let Ok(s) = std::str::from_utf8(&char) else { + continue; + }; + return Ok(Key::Char( + s.chars() + .nth(0) + .expect("s should be exactly one codepoint long"), + )); } if buf.len() < 3 || buf[1] != b'[' { // Unknown escape sequence, eat the escape and one more byte. @@ -173,7 +185,7 @@ impl Reader { } "3~" => { // Backspace - return Ok(Key::Byte(8)); + return Ok(Key::Char(char::from(b'H' - b'@'))); } _ => { continue; -- cgit v1.3.1