]> git.lizzy.rs Git - rust.git/blobdiff - src/shims/fs.rs
avoid using unchecked casts or arithmetic
[rust.git] / src / shims / fs.rs
index cc8f18af7d618a512bf199ac4b6079345477cfa8..7c755143f2e81407bdbce5d43b74ff58b03f0d36 100644 (file)
@@ -1,16 +1,16 @@
 use std::collections::BTreeMap;
-use std::collections::HashMap;
 use std::convert::{TryFrom, TryInto};
 use std::fs::{read_dir, remove_dir, remove_file, rename, DirBuilder, File, FileType, OpenOptions, ReadDir};
 use std::io::{Read, Seek, SeekFrom, Write};
 use std::path::PathBuf;
 use std::time::SystemTime;
 
+use rustc_data_structures::fx::FxHashMap;
 use rustc::ty::layout::{Align, LayoutOf, Size};
 
 use crate::stacked_borrows::Tag;
 use crate::*;
-use helpers::immty_from_uint_checked;
+use helpers::{immty_from_int_checked, immty_from_uint_checked};
 use shims::time::system_time_to_duration;
 
 #[derive(Debug)]
@@ -56,7 +56,7 @@ fn insert_fd_with_min_fd(&mut self, file_handle: FileHandle, min_fd: i32) -> i32
         let new_fd = candidate_new_fd.unwrap_or_else(|| {
             // find_map ran out of BTreeMap entries before finding a free fd, use one plus the
             // maximum fd in the map
-            self.handles.last_entry().map(|entry| entry.key() + 1).unwrap_or(min_fd)
+            self.handles.last_entry().map(|entry| entry.key().checked_add(1).unwrap()).unwrap_or(min_fd)
         });
 
         self.handles.insert(new_fd, file_handle).unwrap_none();
@@ -167,11 +167,11 @@ fn file_type_to_d_type(&mut self, file_type: std::io::Result<FileType>) -> Inter
         match file_type {
             Ok(file_type) => {
                 if file_type.is_dir() {
-                    Ok(this.eval_libc("DT_DIR")?.to_u8()? as i32)
+                    Ok(this.eval_libc("DT_DIR")?.to_u8()?.into())
                 } else if file_type.is_file() {
-                    Ok(this.eval_libc("DT_REG")?.to_u8()? as i32)
+                    Ok(this.eval_libc("DT_REG")?.to_u8()?.into())
                 } else if file_type.is_symlink() {
-                    Ok(this.eval_libc("DT_LNK")?.to_u8()? as i32)
+                    Ok(this.eval_libc("DT_LNK")?.to_u8()?.into())
                 } else {
                     // Certain file types are only supported when the host is a Unix system.
                     // (i.e. devices and sockets) If it is, check those cases, if not, fall back to
@@ -181,19 +181,19 @@ fn file_type_to_d_type(&mut self, file_type: std::io::Result<FileType>) -> Inter
                     {
                         use std::os::unix::fs::FileTypeExt;
                         if file_type.is_block_device() {
-                            Ok(this.eval_libc("DT_BLK")?.to_u8()? as i32)
+                            Ok(this.eval_libc("DT_BLK")?.to_u8()?.into())
                         } else if file_type.is_char_device() {
-                            Ok(this.eval_libc("DT_CHR")?.to_u8()? as i32)
+                            Ok(this.eval_libc("DT_CHR")?.to_u8()?.into())
                         } else if file_type.is_fifo() {
-                            Ok(this.eval_libc("DT_FIFO")?.to_u8()? as i32)
+                            Ok(this.eval_libc("DT_FIFO")?.to_u8()?.into())
                         } else if file_type.is_socket() {
-                            Ok(this.eval_libc("DT_SOCK")?.to_u8()? as i32)
+                            Ok(this.eval_libc("DT_SOCK")?.to_u8()?.into())
                         } else {
-                            Ok(this.eval_libc("DT_UNKNOWN")?.to_u8()? as i32)
+                            Ok(this.eval_libc("DT_UNKNOWN")?.to_u8()?.into())
                         }
                     }
                     #[cfg(not(unix))]
-                    Ok(this.eval_libc("DT_UNKNOWN")?.to_u8()? as i32)
+                    Ok(this.eval_libc("DT_UNKNOWN")?.to_u8()?.into())
                 }
             }
             Err(e) => return match e.raw_os_error() {
@@ -212,10 +212,10 @@ pub struct DirHandler {
     /// When opendir is called, a directory iterator is created on the host for the target
     /// directory, and an entry is stored in this hash map, indexed by an ID which represents
     /// the directory stream. When readdir is called, the directory stream ID is used to look up
-    /// the corresponding ReadDir iterator from this HashMap, and information from the next
+    /// the corresponding ReadDir iterator from this map, and information from the next
     /// directory entry is returned. When closedir is called, the ReadDir iterator is removed from
-    /// this HashMap.
-    streams: HashMap<u64, ReadDir>,
+    /// the map.
+    streams: FxHashMap<u64, ReadDir>,
     /// ID number to be used by the next call to opendir
     next_id: u64,
 }
@@ -232,7 +232,7 @@ fn insert_new(&mut self, read_dir: ReadDir) -> u64 {
 impl Default for DirHandler {
     fn default() -> DirHandler {
         DirHandler {
-            streams: HashMap::new(),
+            streams: FxHashMap::default(),
             // Skip 0 as an ID, because it looks like a null pointer to libc
             next_id: 1,
         }
@@ -427,15 +427,15 @@ fn read(
 
         // We cap the number of read bytes to the largest value that we are able to fit in both the
         // host's and target's `isize`. This saves us from having to handle overflows later.
-        let count = count.min(this.isize_max() as u64).min(isize::max_value() as u64);
+        let count = count.min(this.isize_max() as u64).min(isize::MAX as u64);
 
         if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
             // This can never fail because `count` was capped to be smaller than
-            // `isize::max_value()`.
+            // `isize::MAX`.
             let count = isize::try_from(count).unwrap();
             // We want to read at most `count` bytes. We are sure that `count` is not negative
             // because it was a target's `usize`. Also we are sure that its smaller than
-            // `usize::max_value()` because it is a host's `isize`.
+            // `usize::MAX` because it is a host's `isize`.
             let mut bytes = vec![0; count as usize];
             let result = file
                 .read(&mut bytes)
@@ -481,7 +481,7 @@ fn write(
 
         // We cap the number of written bytes to the largest value that we are able to fit in both the
         // host's and target's `isize`. This saves us from having to handle overflows later.
-        let count = count.min(this.isize_max() as u64).min(isize::max_value() as u64);
+        let count = count.min(this.isize_max() as u64).min(isize::MAX as u64);
 
         if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
             let bytes = this.memory.read_bytes(buf, Size::from_bytes(count))?;
@@ -507,7 +507,7 @@ fn lseek64(
         let whence = this.read_scalar(whence_op)?.to_i32()?;
 
         let seek_from = if whence == this.eval_libc_i32("SEEK_SET")? {
-            SeekFrom::Start(offset as u64)
+            SeekFrom::Start(u64::try_from(offset).unwrap())
         } else if whence == this.eval_libc_i32("SEEK_CUR")? {
             SeekFrom::Current(offset)
         } else if whence == this.eval_libc_i32("SEEK_END")? {
@@ -519,7 +519,7 @@ fn lseek64(
         };
 
         if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
-            let result = file.seek(seek_from).map(|offset| offset as i64);
+            let result = file.seek(seek_from).map(|offset| i64::try_from(offset).unwrap());
             this.try_unwrap_io_result(result)
         } else {
             this.handle_not_found()
@@ -810,7 +810,7 @@ fn mkdir(
         this.check_no_isolation("mkdir")?;
 
         let _mode = if this.tcx.sess.target.target.target_os.as_str() == "macos" {
-            this.read_scalar(mode_op)?.not_undef()?.to_u16()? as u32
+            u32::from(this.read_scalar(mode_op)?.not_undef()?.to_u16()?)
         } else {
             this.read_scalar(mode_op)?.to_u32()?
         };
@@ -929,13 +929,13 @@ fn linux_readdir64_r(
                 #[cfg(not(unix))]
                 let ino = 0u64;
 
-                let file_type = this.file_type_to_d_type(dir_entry.file_type())? as u128;
+                let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
 
                 let imms = [
                     immty_from_uint_checked(ino, ino64_t_layout)?, // d_ino
                     immty_from_uint_checked(0u128, off64_t_layout)?, // d_off
                     immty_from_uint_checked(0u128, c_ushort_layout)?, // d_reclen
-                    immty_from_uint_checked(file_type, c_uchar_layout)?, // d_type
+                    immty_from_int_checked(file_type, c_uchar_layout)?, // d_type
                 ];
                 this.write_packed_immediates(entry_place, &imms)?;
 
@@ -1017,14 +1017,14 @@ fn macos_readdir_r(
                 #[cfg(not(unix))]
                 let ino = 0u64;
 
-                let file_type = this.file_type_to_d_type(dir_entry.file_type())? as u128;
+                let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
 
                 let imms = [
                     immty_from_uint_checked(ino, ino_t_layout)?, // d_ino
                     immty_from_uint_checked(0u128, off_t_layout)?, // d_seekoff
                     immty_from_uint_checked(0u128, c_ushort_layout)?, // d_reclen
                     immty_from_uint_checked(file_name_len, c_ushort_layout)?, // d_namlen
-                    immty_from_uint_checked(file_type, c_uchar_layout)?, // d_type
+                    immty_from_int_checked(file_type, c_uchar_layout)?, // d_type
                 ];
                 this.write_packed_immediates(entry_place, &imms)?;