]> git.lizzy.rs Git - rust.git/commitdiff
Return earlier when reading/writing 0 bytes
authorChristian Poveda <christianpoveda@protonmail.com>
Wed, 2 Oct 2019 13:50:32 +0000 (08:50 -0500)
committerChristian Poveda <christianpoveda@protonmail.com>
Wed, 2 Oct 2019 14:12:03 +0000 (09:12 -0500)
src/shims/io.rs
tests/run-pass/file_read.rs

index 9d3e3d261625ba4c520828ecd7132be84930d9e4..74b8dde5c7fcbfff9ccde03764ebea7247a19a42 100644 (file)
@@ -149,25 +149,23 @@ fn read(
 
         let tcx = &{ this.tcx.tcx };
 
+        let count = this.read_scalar(count_op)?.to_usize(&*this.tcx)?;
+        // Reading zero bytes should not change `buf`
+        if count == 0 {
+            return Ok(0);
+        }
         let fd = this.read_scalar(fd_op)?.to_i32()?;
         let buf_scalar = this.read_scalar(buf_op)?.not_undef()?;
-        let count = this.read_scalar(count_op)?.to_usize(&*this.tcx)?;
 
         // Remove the file handle to avoid borrowing issues
         this.remove_handle_and(fd, |mut handle, this| {
             // Don't use `?` to avoid returning before reinserting the handle
-            let bytes =
-            if count == 0 {
-                Ok(handle.file.read(&mut []))
-            } else {
-                this.force_ptr(buf_scalar).and_then(|buf| this
-                    .memory_mut()
-                    .get_mut(buf.alloc_id).and_then(|alloc|
-                        alloc.get_bytes_mut(tcx, buf, Size::from_bytes(count))
-                        .map(|buffer| handle.file.read(buffer))
-                    ))
-
-            };
+            let bytes = this.force_ptr(buf_scalar).and_then(|buf| {
+                this.memory_mut()
+                    .get_mut(buf.alloc_id)?
+                    .get_bytes_mut(tcx, buf, Size::from_bytes(count))
+                    .map(|buffer| handle.file.read(buffer))
+            });
             // Reinsert the file handle
             this.machine.file_handler.handles.insert(fd, handle);
             this.consume_result(bytes?.map(|bytes| bytes as i64))
@@ -188,9 +186,13 @@ fn write(
 
         let tcx = &{ this.tcx.tcx };
 
+        let count = this.read_scalar(count_op)?.to_usize(&*this.tcx)?;
+        // Writing zero bytes should not change `buf`
+        if count == 0 {
+            return Ok(0);
+        }
         let fd = this.read_scalar(fd_op)?.to_i32()?;
         let buf = this.force_ptr(this.read_scalar(buf_op)?.not_undef()?)?;
-        let count = this.read_scalar(count_op)?.to_usize(&*this.tcx)?;
 
         this.remove_handle_and(fd, |mut handle, this| {
             let bytes = this.memory().get(buf.alloc_id).and_then(|alloc| {
index a17f948980a935bce931b1a2f4c13f2c39cac3a2..666abd65c12e12cb0b079900413983e4a6974646 100644 (file)
@@ -2,7 +2,7 @@
 // compile-flags: -Zmiri-disable-isolation
 
 use std::fs::File;
-use std::io::{ Read, Write };
+use std::io::{Read, Write};
 
 fn main() {
     // FIXME: remove the file and delete it when `rm` is implemented.
@@ -10,13 +10,15 @@ fn main() {
     let bytes = b"Hello, World!\n";
     // Test creating, writing and closing a file (closing is tested when `file` is dropped).
     let mut file = File::create(path).unwrap();
+    // Writing 0 bytes should not change the file contents.
+    file.write(&mut []).unwrap();
+
     file.write(bytes).unwrap();
     // Test opening, reading and closing a file.
     let mut file = File::open(path).unwrap();
     let mut contents = Vec::new();
-    // Reading 0 bytes should not fill `contents`.
-    file.read(&mut contents).unwrap();
-    assert!(contents.is_empty());
+    // Reading 0 bytes should not move the file pointer.
+    file.read(&mut []).unwrap();
     // Reading until EOF should get the whole text.
     file.read_to_end(&mut contents).unwrap();
     assert_eq!(bytes, contents.as_slice());