• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Tests for extreme `u64` file offsets.
2 //!
3 //! POSIX-ish interfaces tend to use signed integers for file offsets, while
4 //! Rust APIs tend to use `u64`. Test that extreme `u64` values in APIs that
5 //! take file offsets are properly diagnosed.
6 //!
7 //! These tests are disabled on ios/macos since those platforms kill the
8 //! process with `SIGXFSZ` instead of returning an error.
9 
10 #![cfg(not(any(target_os = "redox", target_os = "wasi")))]
11 
12 use rustix::io::SeekFrom;
13 
14 #[test]
invalid_offset_seek()15 fn invalid_offset_seek() {
16     use rustix::fs::{cwd, openat, seek, Mode, OFlags};
17     let tmp = tempfile::tempdir().unwrap();
18     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
19     let file = openat(
20         &dir,
21         "foo",
22         OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE,
23         Mode::RUSR | Mode::WUSR,
24     )
25     .unwrap();
26 
27     seek(&file, SeekFrom::Start(u64::MAX)).unwrap_err();
28     seek(&file, SeekFrom::Start(i64::MAX as u64 + 1)).unwrap_err();
29     seek(&file, SeekFrom::End(-1)).unwrap_err();
30     seek(&file, SeekFrom::End(i64::MIN)).unwrap_err();
31     seek(&file, SeekFrom::Current(-1)).unwrap_err();
32     seek(&file, SeekFrom::Current(i64::MIN)).unwrap_err();
33 }
34 
35 #[cfg(not(any(
36     target_os = "dragonfly",
37     target_os = "illumos",
38     target_os = "netbsd",
39     target_os = "openbsd",
40     target_os = "redox",
41     target_os = "solaris",
42 )))]
43 #[test]
invalid_offset_fallocate()44 fn invalid_offset_fallocate() {
45     use rustix::fs::{cwd, fallocate, openat, FallocateFlags, Mode, OFlags};
46     let tmp = tempfile::tempdir().unwrap();
47     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
48     let file = openat(
49         &dir,
50         "foo",
51         OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE,
52         Mode::RUSR | Mode::WUSR,
53     )
54     .unwrap();
55 
56     fallocate(&file, FallocateFlags::empty(), u64::MAX, 1).unwrap_err();
57     fallocate(&file, FallocateFlags::empty(), i64::MAX as u64 + 1, 1).unwrap_err();
58     fallocate(&file, FallocateFlags::empty(), 0, u64::MAX).unwrap_err();
59     fallocate(&file, FallocateFlags::empty(), 0, i64::MAX as u64 + 1).unwrap_err();
60 }
61 
62 #[cfg(not(any(
63     target_os = "dragonfly",
64     target_os = "haiku",
65     target_os = "illumos",
66     target_os = "ios",
67     target_os = "macos",
68     target_os = "netbsd",
69     target_os = "openbsd",
70     target_os = "redox",
71     target_os = "solaris",
72 )))]
73 #[test]
invalid_offset_fadvise()74 fn invalid_offset_fadvise() {
75     use rustix::fs::{cwd, fadvise, openat, Advice, Mode, OFlags};
76     let tmp = tempfile::tempdir().unwrap();
77     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
78     let file = openat(
79         &dir,
80         "foo",
81         OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE,
82         Mode::RUSR | Mode::WUSR,
83     )
84     .unwrap();
85 
86     // `fadvise` never fails on invalid offsets.
87     fadvise(&file, i64::MAX as u64, i64::MAX as u64, Advice::Normal).unwrap();
88     fadvise(&file, u64::MAX, 0, Advice::Normal).unwrap();
89     fadvise(&file, i64::MAX as u64, 1, Advice::Normal).unwrap();
90     fadvise(&file, 1, i64::MAX as u64, Advice::Normal).unwrap();
91     fadvise(&file, i64::MAX as u64 + 1, 0, Advice::Normal).unwrap();
92     fadvise(&file, u64::MAX, i64::MAX as u64, Advice::Normal).unwrap();
93 
94     // `fadvise` fails on invalid lengths.
95     fadvise(&file, u64::MAX, u64::MAX, Advice::Normal).unwrap_err();
96     fadvise(&file, i64::MAX as u64, u64::MAX, Advice::Normal).unwrap_err();
97     fadvise(&file, 0, u64::MAX, Advice::Normal).unwrap_err();
98     fadvise(&file, u64::MAX, i64::MAX as u64 + 1, Advice::Normal).unwrap_err();
99     fadvise(&file, i64::MAX as u64 + 1, u64::MAX, Advice::Normal).unwrap_err();
100     fadvise(&file, i64::MAX as u64, i64::MAX as u64 + 1, Advice::Normal).unwrap_err();
101     fadvise(&file, 0, i64::MAX as u64 + 1, Advice::Normal).unwrap_err();
102 }
103 
104 #[test]
invalid_offset_pread()105 fn invalid_offset_pread() {
106     use rustix::fs::{cwd, openat, Mode, OFlags};
107     use rustix::io::pread;
108     let tmp = tempfile::tempdir().unwrap();
109     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
110     let file = openat(
111         &dir,
112         "foo",
113         OFlags::RDWR | OFlags::TRUNC | OFlags::CREATE,
114         Mode::RUSR | Mode::WUSR,
115     )
116     .unwrap();
117 
118     let mut buf = [0_u8; 1];
119     pread(&file, &mut buf, u64::MAX).unwrap_err();
120     pread(&file, &mut buf, i64::MAX as u64 + 1).unwrap_err();
121 }
122 
123 #[cfg(not(any(target_os = "ios", target_os = "macos")))]
124 #[test]
invalid_offset_pwrite()125 fn invalid_offset_pwrite() {
126     use rustix::fs::{cwd, openat, Mode, OFlags};
127     use rustix::io::pwrite;
128     let tmp = tempfile::tempdir().unwrap();
129     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
130     let file = openat(
131         &dir,
132         "foo",
133         OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE,
134         Mode::RUSR | Mode::WUSR,
135     )
136     .unwrap();
137 
138     let buf = [0_u8; 1];
139     pwrite(&file, &buf, u64::MAX).unwrap_err();
140     pwrite(&file, &buf, i64::MAX as u64 + 1).unwrap_err();
141 }
142 
143 #[cfg(any(target_os = "android", target_os = "linux"))]
144 #[test]
invalid_offset_copy_file_range()145 fn invalid_offset_copy_file_range() {
146     use rustix::fs::{copy_file_range, cwd, openat, Mode, OFlags};
147     use rustix::io::write;
148     let tmp = tempfile::tempdir().unwrap();
149     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
150     let foo = openat(
151         &dir,
152         "foo",
153         OFlags::RDWR | OFlags::TRUNC | OFlags::CREATE,
154         Mode::RUSR | Mode::WUSR,
155     )
156     .unwrap();
157     let bar = openat(
158         &dir,
159         "bar",
160         OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE,
161         Mode::RUSR | Mode::WUSR,
162     )
163     .unwrap();
164     write(&foo, b"a").unwrap();
165 
166     let mut off_in = u64::MAX;
167     let mut off_out = 0;
168     copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err();
169 
170     let mut off_in = i64::MAX as u64 + 1;
171     let mut off_out = 0;
172     copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err();
173 
174     let mut off_in = 0;
175     let mut off_out = u64::MAX;
176     copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err();
177 
178     let mut off_in = 0;
179     let mut off_out = i64::MAX as u64;
180     copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err();
181 
182     let mut off_in = 0;
183     let mut off_out = i64::MAX as u64 + 1;
184     copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err();
185 }
186