diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index d2e3b07ab855d..2116b433fce3f 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -91,7 +91,7 @@ pub fn stderr() -> Option> { #[allow(missing_docs)] pub mod color { /// Number for a terminal color - pub type Color = u16; + pub type Color = u32; pub const BLACK: Color = 0; pub const RED: Color = 1; diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index f1adc536a3dc4..918875e792a66 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -24,7 +24,7 @@ pub struct TermInfo { /// Map of capability name to boolean value pub bools: HashMap, /// Map of capability name to numeric value - pub numbers: HashMap, + pub numbers: HashMap, /// Map of capability name to raw (unexpanded) string pub strings: HashMap>, } @@ -129,7 +129,7 @@ fn cap_for_attr(attr: Attr) -> &'static str { /// A Terminal that knows how many colors it supports, with a reference to its /// parsed Terminfo database record. pub struct TerminfoTerminal { - num_colors: u16, + num_colors: u32, out: T, ti: TermInfo, } diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index d36adb72c8eef..fbc5aebdb2c6c 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -159,16 +159,16 @@ pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear", fn read_le_u16(r: &mut dyn io::Read) -> io::Result { let mut b = [0; 2]; - let mut amt = 0; - while amt < b.len() { - match r.read(&mut b[amt..])? { - 0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")), - n => amt += n, - } - } + r.read_exact(&mut b)?; Ok((b[0] as u16) | ((b[1] as u16) << 8)) } +fn read_le_u32(r: &mut dyn io::Read) -> io::Result { + let mut b = [0; 4]; + r.read_exact(&mut b)?; + Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24)) +} + fn read_byte(r: &mut dyn io::Read) -> io::Result { match r.bytes().next() { Some(s) => s, @@ -194,9 +194,12 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result false, + 0o01036 => true, + _ => return Err(format!("invalid magic number, found {:o}", magic)), + }; // According to the spec, these fields must be >= -1 where -1 means that the feature is not // supported. Using 0 instead of -1 works because we skip sections with length 0. @@ -258,11 +261,15 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result = t! { - (0..numbers_count).filter_map(|i| match read_le_u16(file) { - Ok(0xFFFF) => None, - Ok(n) => Some(Ok((nnames[i].to_string(), n))), - Err(e) => Some(Err(e)) + let numbers_map: HashMap = t! { + (0..numbers_count).filter_map(|i| { + let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) }; + + match number { + Ok(0xFFFF) => None, + Ok(n) => Some(Ok((nnames[i].to_string(), n))), + Err(e) => Some(Err(e)) + } }).collect() }; @@ -318,7 +325,7 @@ pub fn msys_terminfo() -> TermInfo { strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec()); let mut numbers = HashMap::new(); - numbers.insert("colors".to_string(), 8u16); + numbers.insert("colors".to_string(), 8); TermInfo { names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version diff --git a/src/libterm/win.rs b/src/libterm/win.rs index b6c607a30816c..c24cf9518aa25 100644 --- a/src/libterm/win.rs +++ b/src/libterm/win.rs @@ -89,7 +89,7 @@ fn bits_to_color(bits: u16) -> color::Color { _ => unreachable!(), }; - color | (bits & 0x8) // copy the hi-intensity bit + color | (u32::from(bits) & 0x8) // copy the hi-intensity bit } impl WinConsole {