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<Box<StderrTerminal>> {
 #[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<String, bool>,
     /// Map of capability name to numeric value
-    pub numbers: HashMap<String, u16>,
+    pub numbers: HashMap<String, u32>,
     /// Map of capability name to raw (unexpanded) string
     pub strings: HashMap<String, Vec<u8>>,
 }
@@ -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<T> {
-    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<u16> {
     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<u32> {
+    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<u8> {
     match r.bytes().next() {
         Some(s) => s,
@@ -194,9 +194,12 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin
 
     // Check magic number
     let magic = t!(read_le_u16(file));
-    if magic != 0x011A {
-        return Err(format!("invalid magic number: expected {:x}, found {:x}", 0x011A, magic));
-    }
+
+    let extended = match magic {
+        0o0432 => 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<TermInfo, Strin
         t!(read_byte(file)); // compensate for padding
     }
 
-    let numbers_map: HashMap<String, u16> = 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<String, u32> = 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<T: Write + Send + 'static> WinConsole<T> {