diff options
| author | Jeremy Soller <jackpot51@gmail.com> | 2016-11-10 20:37:34 -0700 |
|---|---|---|
| committer | Jeremy Soller <jackpot51@gmail.com> | 2016-11-10 20:37:34 -0700 |
| commit | 0bb9a959074bb7f027cf05a240a0044116fa0ab0 (patch) | |
| tree | 69fca65cd12f30f97f8bcfd403b39577f2ce3c57 /src/libstd | |
| parent | 25e1a4a0084a56807d7a1e4ca676e078c085b3aa (diff) | |
| parent | 1473007618e6ab85a994f86348acdaf125b7914f (diff) | |
| download | rust-0bb9a959074bb7f027cf05a240a0044116fa0ab0.tar.gz rust-0bb9a959074bb7f027cf05a240a0044116fa0ab0.zip | |
Merge branch 'master' into redox
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/collections/hash/map.rs | 26 | ||||
| -rw-r--r-- | src/libstd/ffi/c_str.rs | 2 | ||||
| -rw-r--r-- | src/libstd/io/error.rs | 78 | ||||
| -rw-r--r-- | src/libstd/io/mod.rs | 27 | ||||
| -rw-r--r-- | src/libstd/io/stdio.rs | 3 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 2 | ||||
| -rw-r--r-- | src/libstd/net/udp.rs | 3 | ||||
| -rw-r--r-- | src/libstd/path.rs | 14 | ||||
| -rw-r--r-- | src/libstd/sys/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/unix/rand.rs | 28 | ||||
| -rw-r--r-- | src/libstd/sys_common/mod.rs | 2 |
11 files changed, 120 insertions, 67 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index fb8a0c3c265..ece51d6d826 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -11,6 +11,7 @@ use self::Entry::*; use self::VacantEntryState::*; +use cell::Cell; use borrow::Borrow; use cmp::max; use fmt::{self, Debug}; @@ -2049,24 +2050,21 @@ impl RandomState { // many hash maps are created on a thread. To solve this performance // trap we cache the first set of randomly generated keys per-thread. // - // In doing this, however, we lose the property that all hash maps have - // nondeterministic iteration order as all of those created on the same - // thread would have the same hash keys. This property has been nice in - // the past as it allows for maximal flexibility in the implementation - // of `HashMap` itself. - // - // The constraint here (if there even is one) is just that maps created - // on the same thread have the same iteration order, and that *may* be - // relied upon even though it is not a documented guarantee at all of - // the `HashMap` type. In any case we've decided that this is reasonable - // for now, so caching keys thread-locally seems fine. - thread_local!(static KEYS: (u64, u64) = { + // Later in #36481 it was discovered that exposing a deterministic + // iteration order allows a form of DOS attack. To counter that we + // increment one of the seeds on every RandomState creation, giving + // every corresponding HashMap a different iteration order. + thread_local!(static KEYS: Cell<(u64, u64)> = { let r = rand::OsRng::new(); let mut r = r.expect("failed to create an OS RNG"); - (r.gen(), r.gen()) + Cell::new((r.gen(), r.gen())) }); - KEYS.with(|&(k0, k1)| RandomState { k0: k0, k1: k1 }) + KEYS.with(|keys| { + let (k0, k1) = keys.get(); + keys.set((k0.wrapping_add(1), k1)); + RandomState { k0: k0, k1: k1 } + }) } } diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 3ad5b5627d3..d1b8fcd7440 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -686,7 +686,7 @@ impl ToOwned for CStr { type Owned = CString; fn to_owned(&self) -> CString { - unsafe { CString::from_vec_unchecked(self.to_bytes().to_vec()) } + CString { inner: self.to_bytes_with_nul().to_vec().into_boxed_slice() } } } diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index ddf0030858e..795c89c0007 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -12,6 +12,7 @@ use error; use fmt; use result; use sys; +use convert::From; /// A specialized [`Result`](../result/enum.Result.html) type for I/O /// operations. @@ -62,6 +63,7 @@ pub struct Error { enum Repr { Os(i32), + Simple(ErrorKind), Custom(Box<Custom>), } @@ -124,23 +126,28 @@ pub enum ErrorKind { InvalidInput, /// Data not valid for the operation were encountered. /// - /// Unlike `InvalidInput`, this typically means that the operation + /// Unlike [`InvalidInput`], this typically means that the operation /// parameters were valid, however the error was caused by malformed /// input data. /// /// For example, a function that reads a file into a string will error with /// `InvalidData` if the file's contents are not valid UTF-8. + /// + /// [`InvalidInput`]: #variant.InvalidInput #[stable(feature = "io_invalid_data", since = "1.2.0")] InvalidData, /// The I/O operation's timeout expired, causing it to be canceled. #[stable(feature = "rust1", since = "1.0.0")] TimedOut, /// An error returned when an operation could not be completed because a - /// call to `write` returned `Ok(0)`. + /// call to [`write()`] returned [`Ok(0)`]. /// /// This typically means that an operation could only succeed if it wrote a /// particular number of bytes but only a smaller number of bytes could be /// written. + /// + /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write + /// [`Ok(0)`]: ../../std/io/type.Result.html #[stable(feature = "rust1", since = "1.0.0")] WriteZero, /// This operation was interrupted. @@ -171,6 +178,43 @@ pub enum ErrorKind { __Nonexhaustive, } +impl ErrorKind { + fn as_str(&self) -> &'static str { + match *self { + ErrorKind::NotFound => "entity not found", + ErrorKind::PermissionDenied => "permission denied", + ErrorKind::ConnectionRefused => "connection refused", + ErrorKind::ConnectionReset => "connection reset", + ErrorKind::ConnectionAborted => "connection aborted", + ErrorKind::NotConnected => "not connected", + ErrorKind::AddrInUse => "address in use", + ErrorKind::AddrNotAvailable => "address not available", + ErrorKind::BrokenPipe => "broken pipe", + ErrorKind::AlreadyExists => "entity already exists", + ErrorKind::WouldBlock => "operation would block", + ErrorKind::InvalidInput => "invalid input parameter", + ErrorKind::InvalidData => "invalid data", + ErrorKind::TimedOut => "timed out", + ErrorKind::WriteZero => "write zero", + ErrorKind::Interrupted => "operation interrupted", + ErrorKind::Other => "other os error", + ErrorKind::UnexpectedEof => "unexpected end of file", + ErrorKind::__Nonexhaustive => unreachable!() + } + } +} + +/// Intended for use for errors not exposed to the user, where allocating onto +/// the heap (for normal construction via Error::new) is too costly. +#[stable(feature = "io_error_from_errorkind", since = "1.14.0")] +impl From<ErrorKind> for Error { + fn from(kind: ErrorKind) -> Error { + Error { + repr: Repr::Simple(kind) + } + } +} + impl Error { /// Creates a new I/O error from a known kind of error as well as an /// arbitrary error payload. @@ -285,6 +329,7 @@ impl Error { match self.repr { Repr::Os(i) => Some(i), Repr::Custom(..) => None, + Repr::Simple(..) => None, } } @@ -317,6 +362,7 @@ impl Error { pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, + Repr::Simple(..) => None, Repr::Custom(ref c) => Some(&*c.error), } } @@ -387,6 +433,7 @@ impl Error { pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, + Repr::Simple(..) => None, Repr::Custom(ref mut c) => Some(&mut *c.error), } } @@ -420,6 +467,7 @@ impl Error { pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> { match self.repr { Repr::Os(..) => None, + Repr::Simple(..) => None, Repr::Custom(c) => Some(c.error) } } @@ -447,6 +495,7 @@ impl Error { match self.repr { Repr::Os(code) => sys::decode_error_kind(code), Repr::Custom(ref c) => c.kind, + Repr::Simple(kind) => kind, } } } @@ -458,6 +507,7 @@ impl fmt::Debug for Repr { fmt.debug_struct("Os").field("code", code) .field("message", &sys::os::error_string(*code)).finish(), Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(), + Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(), } } } @@ -471,6 +521,7 @@ impl fmt::Display for Error { write!(fmt, "{} (os error {})", detail, code) } Repr::Custom(ref c) => c.error.fmt(fmt), + Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()), } } } @@ -479,27 +530,7 @@ impl fmt::Display for Error { impl error::Error for Error { fn description(&self) -> &str { match self.repr { - Repr::Os(..) => match self.kind() { - ErrorKind::NotFound => "entity not found", - ErrorKind::PermissionDenied => "permission denied", - ErrorKind::ConnectionRefused => "connection refused", - ErrorKind::ConnectionReset => "connection reset", - ErrorKind::ConnectionAborted => "connection aborted", - ErrorKind::NotConnected => "not connected", - ErrorKind::AddrInUse => "address in use", - ErrorKind::AddrNotAvailable => "address not available", - ErrorKind::BrokenPipe => "broken pipe", - ErrorKind::AlreadyExists => "entity already exists", - ErrorKind::WouldBlock => "operation would block", - ErrorKind::InvalidInput => "invalid input parameter", - ErrorKind::InvalidData => "invalid data", - ErrorKind::TimedOut => "timed out", - ErrorKind::WriteZero => "write zero", - ErrorKind::Interrupted => "operation interrupted", - ErrorKind::Other => "other os error", - ErrorKind::UnexpectedEof => "unexpected end of file", - ErrorKind::__Nonexhaustive => unreachable!() - }, + Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(), Repr::Custom(ref c) => c.error.description(), } } @@ -507,6 +538,7 @@ impl error::Error for Error { fn cause(&self) -> Option<&error::Error> { match self.repr { Repr::Os(..) => None, + Repr::Simple(..) => None, Repr::Custom(ref c) => c.error.cause(), } } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 193f396c0d4..ad9ae5638b6 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -21,7 +21,7 @@ //! of other types, and you can implement them for your types too. As such, //! you'll see a few different types of I/O throughout the documentation in //! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec<T>`]s. For -//! example, `Read` adds a `read()` method, which we can use on `File`s: +//! example, [`Read`] adds a [`read()`] method, which we can use on `File`s: //! //! ``` //! use std::io; @@ -251,6 +251,7 @@ //! [`Lines`]: struct.Lines.html //! [`io::Result`]: type.Result.html //! [`try!`]: ../macro.try.html +//! [`read()`]: trait.Read.html#tymethod.read #![stable(feature = "rust1", since = "1.0.0")] @@ -814,19 +815,23 @@ pub trait Read { /// /// Implementors of the `Write` trait are sometimes called 'writers'. /// -/// Writers are defined by two required methods, `write()` and `flush()`: +/// Writers are defined by two required methods, [`write()`] and [`flush()`]: /// -/// * The `write()` method will attempt to write some data into the object, +/// * The [`write()`] method will attempt to write some data into the object, /// returning how many bytes were successfully written. /// -/// * The `flush()` method is useful for adaptors and explicit buffers +/// * The [`flush()`] method is useful for adaptors and explicit buffers /// themselves for ensuring that all buffered data has been pushed out to the /// 'true sink'. /// /// Writers are intended to be composable with one another. Many implementors -/// throughout `std::io` take and provide types which implement the `Write` +/// throughout [`std::io`] take and provide types which implement the `Write` /// trait. /// +/// [`write()`]: #tymethod.write +/// [`flush()`]: #tymethod.flush +/// [`std::io`]: index.html +/// /// # Examples /// /// ``` @@ -1475,10 +1480,10 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> { /// Reader adaptor which limits the bytes read from an underlying reader. /// -/// This struct is generally created by calling [`take()`][take] on a reader. -/// Please see the documentation of `take()` for more details. +/// This struct is generally created by calling [`take()`] on a reader. +/// Please see the documentation of [`take()`] for more details. /// -/// [take]: trait.Read.html#method.take +/// [`take()`]: trait.Read.html#method.take #[stable(feature = "rust1", since = "1.0.0")] pub struct Take<T> { inner: T, @@ -1491,8 +1496,10 @@ impl<T> Take<T> { /// /// # Note /// - /// This instance may reach EOF after reading fewer bytes than indicated by - /// this method if the underlying `Read` instance reaches EOF. + /// This instance may reach `EOF` after reading fewer bytes than indicated by + /// this method if the underlying [`Read`] instance reaches EOF. + /// + /// [`Read`]: ../../std/io/trait.Read.html /// /// # Examples /// diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 27bc5f0890c..f6ee0be47fa 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -324,10 +324,11 @@ impl<'a> BufRead for StdinLock<'a> { /// /// Each handle shares a global buffer of data to be written to the standard /// output stream. Access is also synchronized via a lock and explicit control -/// over locking is available via the `lock` method. +/// over locking is available via the [`lock()`] method. /// /// Created by the [`io::stdout`] method. /// +/// [`lock()`]: #method.lock /// [`io::stdout`]: fn.stdout.html #[stable(feature = "rust1", since = "1.0.0")] pub struct Stdout { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 8d973fc1ade..12dbbe3c469 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -249,7 +249,7 @@ #![feature(const_fn)] #![feature(core_float)] #![feature(core_intrinsics)] -#![feature(dotdot_in_tuple_patterns)] +#![cfg_attr(stage0, feature(dotdot_in_tuple_patterns))] #![feature(dropck_parametricity)] #![feature(float_extras)] #![feature(float_from_str_radix)] diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index c03ac496adb..559250adac5 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -67,6 +67,9 @@ impl UdpSocket { /// /// Address type can be any implementor of `ToSocketAddrs` trait. See its /// documentation for concrete examples. + /// This will return an error when the IP version of the local socket + /// does not match that returned from `ToSocketAddrs` + /// See https://github.com/rust-lang/rust/issues/34202 for more details. #[stable(feature = "rust1", since = "1.0.0")] pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9b7f9980cc0..bb6883236e8 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1173,6 +1173,13 @@ impl From<OsString> for PathBuf { } } +#[stable(feature = "from_path_buf_for_os_string", since = "1.14.0")] +impl From<PathBuf> for OsString { + fn from(path_buf : PathBuf) -> OsString { + path_buf.inner + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl From<String> for PathBuf { fn from(s: String) -> PathBuf { @@ -1283,13 +1290,6 @@ impl AsRef<OsStr> for PathBuf { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl Into<OsString> for PathBuf { - fn into(self) -> OsString { - self.inner - } -} - /// A slice of a path (akin to [`str`]). /// /// This type supports a number of operations for inspecting a path, including diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index a237d8a067e..e4b0d980c92 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -23,7 +23,7 @@ //! integration code in `std::sys_common`. See that module's //! documentation for details. //! -//! In the future it would be desirable for the indepedent +//! In the future it would be desirable for the independent //! implementations of this module to be extracted to their own crates //! that `std` can link to, thus enabling their implementation //! out-of-tree via crate replacement. Though due to the complex diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index 3aebb8c18ec..9b1cf6ffd0e 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -350,11 +350,19 @@ mod imp { #[link(name = "magenta")] extern { - fn mx_cprng_draw(buffer: *mut u8, len: usize) -> isize; + fn mx_cprng_draw(buffer: *mut u8, len: usize, actual: *mut usize) -> i32; } - fn getrandom(buf: &mut [u8]) -> isize { - unsafe { mx_cprng_draw(buf.as_mut_ptr(), buf.len()) } + fn getrandom(buf: &mut [u8]) -> Result<usize, i32> { + unsafe { + let mut actual = 0; + let status = mx_cprng_draw(buf.as_mut_ptr(), buf.len(), &mut actual); + if status == 0 { + Ok(actual) + } else { + Err(status) + } + } } pub struct OsRng { @@ -381,12 +389,16 @@ mod imp { let mut buf = v; while !buf.is_empty() { let ret = getrandom(buf); - if ret < 0 { - panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})", - ret, buf.len()); + match ret { + Err(err) => { + panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})", + err, buf.len()) + } + Ok(actual) => { + let move_buf = buf; + buf = &mut move_buf[(actual as usize)..]; + } } - let move_buf = buf; - buf = &mut move_buf[(ret as usize)..]; } } } diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index 5f5ea09c78d..5c07e36508c 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -10,7 +10,7 @@ //! Platform-independent platform abstraction //! -//! This is the platform-independent portion of the standard libraries +//! This is the platform-independent portion of the standard library's //! platform abstraction layer, whereas `std::sys` is the //! platform-specific portion. //! |
