浏览代码

Fix bug in fread

Bug discovered by @xTibor. Test and input data provided by him.
jD91mZM2 6 年之前
父节点
当前提交
dd711f4dee
共有 6 个文件被更改,包括 64 次插入8 次删除
  1. 9 8
      src/header/stdio/mod.rs
  2. 1 0
      tests/Makefile
  3. 0 0
      tests/expected/stdio/fread.stderr
  4. 32 0
      tests/expected/stdio/fread.stdout
  5. 21 0
      tests/stdio/fread.c
  6. 1 0
      tests/stdio/fread.in

+ 9 - 8
src/header/stdio/mod.rs

@@ -71,20 +71,21 @@ pub struct FILE {
 }
 
 impl Read for FILE {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        if !buf.is_empty() {
+    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
+        if !out.is_empty() {
             if let Some(c) = self.unget.take() {
-                buf[0] = c;
+                out[0] = c;
                 return Ok(1);
             }
         }
 
-        if self.read_pos == self.read_size {
-            self.fill_buf()?;
-        }
+        let len = {
+            let buf = self.fill_buf()?;
+            let len = buf.len().min(out.len());
 
-        let len = buf.len().min(self.read_size);
-        buf[..len].copy_from_slice(&mut self.read_buf[..len]);
+            out[..len].copy_from_slice(&buf[..len]);
+            len
+        };
         self.consume(len);
         Ok(len)
     }

+ 1 - 0
tests/Makefile

@@ -17,6 +17,7 @@ EXPECT_BINS=\
 	stdio/all \
 	stdio/buffer \
 	stdio/fgets \
+	stdio/fread \
 	stdio/freopen \
 	stdio/fseek \
 	stdio/fwrite \

+ 0 - 0
tests/expected/stdio/fread.stderr


+ 32 - 0
tests/expected/stdio/fread.stdout

@@ -0,0 +1,32 @@
+1
+22
+333
+4444
+55555
+666666
+7777777
+88888888
+999999999
+AAAAAAAAAA
+BBBBBBBBBBB
+CCCCCCCCCCCC
+DDDDDDDDDDDDD
+EEEEEEEEEEEEEE
+FFFFFFFFFFFFFFF
+0000000000000000
+11111111111111111
+222222222222222222
+3333333333333333333
+44444444444444444444
+555555555555555555555
+6666666666666666666666
+77777777777777777777777
+888888888888888888888888
+9999999999999999999999999
+AAAAAAAAAAAAAAAAAAAAAAAAAA
+BBBBBBBBBBBBBBBBBBBBBBBBBBB
+CCCCCCCCCCCCCCCCCCCCCCCCCCCC
+DDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+00000000000000000000000000000000

+ 21 - 0
tests/stdio/fread.c

@@ -0,0 +1,21 @@
+#include <errno.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+    FILE *fp = fopen("stdio/fread.in", "rb");
+
+    char buf[33] = { 0 };
+    for (int i = 1; i <= 32; ++i) {
+        if (fread(buf, 1, i, fp) < 0) {
+            perror("fread");
+            return 0;
+        }
+        buf[i] = 0;
+
+        printf("%s\n", buf);
+    }
+
+    fclose(fp);
+
+    return 0;
+}

+ 1 - 0
tests/stdio/fread.in

@@ -0,0 +1 @@
+122333444455555666666777777788888888999999999AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCCDDDDDDDDDDDDDEEEEEEEEEEEEEEFFFFFFFFFFFFFFF0000000000000000111111111111111112222222222222222223333333333333333333444444444444444444445555555555555555555556666666666666666666666777777777777777777777778888888888888888888888889999999999999999999999999AAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000