1 | /* Test case for bug with mmap stdio read past end of file. */ |
2 | |
3 | #include <stdio.h> |
4 | #include <error.h> |
5 | #include <errno.h> |
6 | |
7 | static void do_prepare (void); |
8 | #define PREPARE(argc, argv) do_prepare () |
9 | static int do_test (void); |
10 | #define TEST_FUNCTION do_test () |
11 | #include <test-skeleton.c> |
12 | |
13 | static char *temp_file; |
14 | |
15 | static const char text1[] = "hello\n" ; |
16 | |
17 | static void |
18 | do_prepare (void) |
19 | { |
20 | int temp_fd = create_temp_file (base: "tst-mmap-offend." , filename: &temp_file); |
21 | if (temp_fd == -1) |
22 | error (status: 1, errno, format: "cannot create temporary file" ); |
23 | else |
24 | { |
25 | ssize_t cc = write (temp_fd, text1, sizeof text1 - 1); |
26 | if (cc != sizeof text1 - 1) |
27 | error (status: 1, errno, format: "cannot write to temporary file" ); |
28 | } |
29 | close (fd: temp_fd); |
30 | } |
31 | |
32 | static int |
33 | do_test (void) |
34 | { |
35 | unsigned char buffer[8192]; |
36 | int result = 0; |
37 | FILE *f = fopen (temp_file, "rm" ); |
38 | size_t cc; |
39 | |
40 | if (f == NULL) |
41 | { |
42 | perror (temp_file); |
43 | return 1; |
44 | } |
45 | |
46 | cc = fread (ptr: buffer, size: 1, n: sizeof (buffer), stream: f); |
47 | printf (format: "fread %zu: \"%.*s\"\n" , cc, (int) cc, buffer); |
48 | if (cc != sizeof text1 - 1) |
49 | { |
50 | perror ("fread" ); |
51 | result = 1; |
52 | } |
53 | |
54 | if (fseek (f, 2048, SEEK_SET) != 0) |
55 | { |
56 | perror ("fseek off end" ); |
57 | result = 1; |
58 | } |
59 | |
60 | if (fread (ptr: buffer, size: 1, n: sizeof (buffer), stream: f) != 0 |
61 | || ferror (stream: f) || !feof (stream: f)) |
62 | { |
63 | printf (format: "after fread error %d eof %d\n" , |
64 | ferror (stream: f), feof (stream: f)); |
65 | result = 1; |
66 | } |
67 | |
68 | printf (format: "ftell %ld\n" , ftell (stream: f)); |
69 | |
70 | if (fseek (f, 0, SEEK_SET) != 0) |
71 | { |
72 | perror ("fseek rewind" ); |
73 | result = 1; |
74 | } |
75 | |
76 | cc = fread (ptr: buffer, size: 1, n: sizeof (buffer), stream: f); |
77 | printf (format: "fread after rewind %zu: \"%.*s\"\n" , cc, (int) cc, buffer); |
78 | if (cc != sizeof text1 - 1) |
79 | { |
80 | perror ("fread after rewind" ); |
81 | result = 1; |
82 | } |
83 | |
84 | fclose (f); |
85 | return result; |
86 | } |
87 | |