memmap-rs: Mmap fails for empty files on Windows
As per the MSDN documentation for CreateFileMapping:
An attempt to map a file with a length of 0 (zero) fails with an error code of ERROR_FILE_INVALID. Applications should test for files with a length of 0 (zero) and reject those files.
I believe this should not be the expected behavior for the memmap-rs crate, and we should check if the size is 0 (we already get the size before mapping the file anyway), and return an empty-slice backed Mmap struct in that case.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Comments: 21 (2 by maintainers)
Commits related to this issue
- Support zero-size `Mmap` and `MmapMut` Fixes https://github.com/danburkert/memmap-rs/issues/72 Previously, mapping an empty file or requesting a zero-size mapping would return an error because under... — committed to SimonSapin/memmap2-rs by SimonSapin 3 years ago
- Support zero-size `Mmap` and `MmapMut` Fixes https://github.com/danburkert/memmap-rs/issues/72 Previously, mapping an empty file or requesting a zero-size mapping would return an error because under... — committed to SimonSapin/memmap2-rs by SimonSapin 3 years ago
- Support zero-size `Mmap` and `MmapMut` Fixes https://github.com/danburkert/memmap-rs/issues/72 Previously, mapping an empty file or requesting a zero-size mapping would return an error because under... — committed to SimonSapin/memmap2-rs by SimonSapin 3 years ago
While the current behavior is consistent, I think almost all callers are going to need special handling for the zero-length case to avoid this error, and as a result there are probably a lot of latent bugs out there waiting for someone to trigger them with an empty file. I just realized I have one in my own code, where I check for a number of conditions but forgot to check for this one.
Maybe relevant, there are cases today where Mmap can accept a zero length and successfully deref to an empty slice. It can happen if you have an offset that isn’t a multiple of the page size, so that the real mapping under the covers isn’t empty. So in that particular case, the caller might end up with an even trickier bug, where their empty maps fail only for certain offsets. (This is especially tough because an “is the file empty” check isn’t good enough here. You have to know how your request offset compares to the file length.)
This doesn’t work well for programs that traverse the entire file hierarchy, like
rgortar. It implies that the user may not invoke the program from/, but that’s something plenty of users want to do. I’m sure there are wacky examples of virtual filesystems in places other than/, too, but that’s bad enough.It seems like the underlying APIs are pretty tightly coupled to the notion that memmapping empty files is an error, and that callers will fall back to normal reading in the face of errors. (Or perhaps that callers won’t try to mmap below a certain size.) If we want to make empty files not an error, it’s suddenly our responsibility to detect when the filesystem is lying to use about a file’s size. And as the old saying goes: If the file system wants to lie to us, then let the file system lie to us.