Skip to content

Commit

Permalink
libstd: explicitly disallow io::fs::File to open a directory.
Browse files Browse the repository at this point in the history
On *BSD systems, we can open(2) a directory and directly read(2) from
it due to an old tradition.  We should avoid doing so by explicitly
calling fstat(2) to check the type of the opened file.

Opening a directory as a module file can't always be avoided.
Even when there's no "path" attribute trick involved, there can always
be a *directory* named "my_module.rs".

Fix rust-lang#12460

Signed-off-by: NODA, Kai <[email protected]>
  • Loading branch information
nodakai committed Dec 3, 2014
1 parent fc40c0c commit e7e2d7a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 10 deletions.
28 changes: 21 additions & 7 deletions src/libstd/io/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
use clone::Clone;
use io::standard_error;
use io::{FilePermission, Write, Open, FileAccess, FileMode, FileType};
use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader};
use io::{IoResult, IoError, InvalidInput};
use io::{FileStat, SeekStyle, Seek, Writer, Reader};
use io::{Read, Truncate, ReadWrite, Append};
use io::UpdateIoError;
use io;
Expand Down Expand Up @@ -134,13 +135,26 @@ impl File {
pub fn open_mode(path: &Path,
mode: FileMode,
access: FileAccess) -> IoResult<File> {
fs_imp::open(path, mode, access).map(|fd| {
File {
path: path.clone(),
fd: fd,
last_nread: -1
fs_imp::open(path, mode, access).and_then(|fd| {
// On *BSD systems, we can open a directory as a file and read from it:
// fd=open("/tmp", O_RDONLY); read(fd, buf, N);
// due to an old tradition before the introduction of opendir(3).
// We explicitly reject it because there are few use cases.
if cfg!(not(any(windows, target_os = "linux", target_os = "android"))) &&
try!(fd.fstat()).kind == FileType::Directory {
Err(IoError {
kind: InvalidInput,
desc: "is a directory",
detail: None
})
} else {
Ok(File {
path: path.clone(),
fd: fd,
last_nread: -1
})
}
}).update_err("couldn't open file", |e| {
}).update_err("couldn't open path as file", |e| {
format!("{}; path={}; mode={}; access={}", e, path.display(),
mode_string(mode), access_string(access))
})
Expand Down
4 changes: 1 addition & 3 deletions src/test/compile-fail/issue-5806.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-freebsd FIXME #12460

#[path = "../compile-fail"]
mod foo; //~ ERROR: illegal operation on a directory
mod foo; //~ ERROR: a directory

fn main() {}

2 comments on commit e7e2d7a

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+

@alexcrichton
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors: retry

Please sign in to comment.