about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-21 08:04:19 +0000
committerbors <bors@rust-lang.org>2021-10-21 08:04:19 +0000
commite015ef5b2633960e7653b744d7a1c3d1d336313a (patch)
treeb97de10e82d74e3f73f4bc12e0fbcb66a1df5a65 /library/std/src
parent40ebd073829959d47b977c168096968a6ed753f9 (diff)
parent3680ecd8a6e8dcac98833bc8bbc349277f780419 (diff)
downloadrust-e015ef5b2633960e7653b744d7a1c3d1d336313a.tar.gz
rust-e015ef5b2633960e7653b744d7a1c3d1d336313a.zip
Auto merge of #90119 - JohnTitor:rollup-e5t6khz, r=JohnTitor
Rollup of 14 pull requests

Successful merges:

 - #86984 (Reject octal zeros in IPv4 addresses)
 - #87440 (Remove unnecessary condition in Barrier::wait())
 - #88644 (`AbstractConst` private fields)
 - #89292 (Stabilize CString::from_vec_with_nul[_unchecked])
 - #90010 (Avoid overflow in `VecDeque::with_capacity_in()`.)
 - #90029 (Add test for debug logging during incremental compilation)
 - #90031 (config: add the option to enable LLVM tests)
 - #90048 (Add test for line-number setting)
 - #90071 (Remove hir::map::blocks and use FnKind instead)
 - #90074 (2229 migrations small cleanup)
 - #90077 (Make `From` impls of NonZero integer const.)
 - #90097 (Add test for duplicated sidebar entries for reexported macro)
 - #90098 (Add test to ensure that the missing_doc_code_examples is not triggered on foreign trait implementations)
 - #90099 (Fix MIRI UB in `Vec::swap_remove`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/ffi/c_str.rs20
-rw-r--r--library/std/src/ffi/mod.rs2
-rw-r--r--library/std/src/net/ip.rs6
-rw-r--r--library/std/src/net/ip/tests.rs8
-rw-r--r--library/std/src/net/parser.rs28
-rw-r--r--library/std/src/sync/barrier.rs2
6 files changed, 42 insertions, 24 deletions
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 6827d3a8d24..cb09717bde5 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -251,13 +251,12 @@ pub struct FromBytesWithNulError {
 /// # Examples
 ///
 /// ```
-/// #![feature(cstring_from_vec_with_nul)]
 /// use std::ffi::{CString, FromVecWithNulError};
 ///
 /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"f\0oo".to_vec()).unwrap_err();
 /// ```
 #[derive(Clone, PartialEq, Eq, Debug)]
-#[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
+#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 pub struct FromVecWithNulError {
     error_kind: FromBytesWithNulErrorKind,
     bytes: Vec<u8>,
@@ -278,7 +277,7 @@ impl FromBytesWithNulError {
     }
 }
 
-#[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
+#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 impl FromVecWithNulError {
     /// Returns a slice of [`u8`]s bytes that were attempted to convert to a [`CString`].
     ///
@@ -287,7 +286,6 @@ impl FromVecWithNulError {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(cstring_from_vec_with_nul)]
     /// use std::ffi::CString;
     ///
     /// // Some invalid bytes in a vector
@@ -298,6 +296,7 @@ impl FromVecWithNulError {
     /// assert_eq!(&bytes[..], value.unwrap_err().as_bytes());
     /// ```
     #[must_use]
+    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
     pub fn as_bytes(&self) -> &[u8] {
         &self.bytes[..]
     }
@@ -313,7 +312,6 @@ impl FromVecWithNulError {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(cstring_from_vec_with_nul)]
     /// use std::ffi::CString;
     ///
     /// // Some invalid bytes in a vector
@@ -324,6 +322,7 @@ impl FromVecWithNulError {
     /// assert_eq!(bytes, value.unwrap_err().into_bytes());
     /// ```
     #[must_use = "`self` will be dropped if the result is not used"]
+    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
     pub fn into_bytes(self) -> Vec<u8> {
         self.bytes
     }
@@ -704,7 +703,6 @@ impl CString {
     /// # Example
     ///
     /// ```
-    /// #![feature(cstring_from_vec_with_nul)]
     /// use std::ffi::CString;
     /// assert_eq!(
     ///     unsafe { CString::from_vec_with_nul_unchecked(b"abc\0".to_vec()) },
@@ -712,7 +710,7 @@ impl CString {
     /// );
     /// ```
     #[must_use]
-    #[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
+    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
     pub unsafe fn from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
         Self { inner: v.into_boxed_slice() }
     }
@@ -733,7 +731,6 @@ impl CString {
     /// when called without the ending nul byte.
     ///
     /// ```
-    /// #![feature(cstring_from_vec_with_nul)]
     /// use std::ffi::CString;
     /// assert_eq!(
     ///     CString::from_vec_with_nul(b"abc\0".to_vec())
@@ -745,14 +742,13 @@ impl CString {
     /// An incorrectly formatted [`Vec`] will produce an error.
     ///
     /// ```
-    /// #![feature(cstring_from_vec_with_nul)]
     /// use std::ffi::{CString, FromVecWithNulError};
     /// // Interior nul byte
     /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"a\0bc".to_vec()).unwrap_err();
     /// // No nul byte
     /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"abc".to_vec()).unwrap_err();
     /// ```
-    #[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
+    #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
     pub fn from_vec_with_nul(v: Vec<u8>) -> Result<Self, FromVecWithNulError> {
         let nul_pos = memchr::memchr(0, &v);
         match nul_pos {
@@ -1084,10 +1080,10 @@ impl fmt::Display for FromBytesWithNulError {
     }
 }
 
-#[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
+#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 impl Error for FromVecWithNulError {}
 
-#[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
+#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 impl fmt::Display for FromVecWithNulError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.error_kind {
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index 82a76aa73c5..7f3bb836754 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -145,7 +145,7 @@
 
 #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
 pub use self::c_str::FromBytesWithNulError;
-#[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
+#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 pub use self::c_str::FromVecWithNulError;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::c_str::{CStr, CString, IntoStringError, NulError};
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index e5e9fedb61e..c080f783cbb 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -59,7 +59,8 @@ pub enum IpAddr {
 ///
 /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal
 /// notation, divided by `.` (this is called "dot-decimal notation").
-/// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943].
+/// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which
+/// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943].
 ///
 /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1
 /// [`FromStr`]: crate::str::FromStr
@@ -72,6 +73,9 @@ pub enum IpAddr {
 /// let localhost = Ipv4Addr::new(127, 0, 0, 1);
 /// assert_eq!("127.0.0.1".parse(), Ok(localhost));
 /// assert_eq!(localhost.is_loopback(), true);
+/// assert!("012.004.002.000".parse::<Ipv4Addr>().is_err()); // all octets are in octal
+/// assert!("0000000.0.0.0".parse::<Ipv4Addr>().is_err()); // first octet is a zero in octal
+/// assert!("0xcb.0x0.0x71.0x00".parse::<Ipv4Addr>().is_err()); // all octets are in hex
 /// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs
index babc854cd1d..17581f33026 100644
--- a/library/std/src/net/ip/tests.rs
+++ b/library/std/src/net/ip/tests.rs
@@ -20,6 +20,14 @@ fn test_from_str_ipv4() {
     // no number between dots
     let none: Option<Ipv4Addr> = "255.0..1".parse().ok();
     assert_eq!(None, none);
+    // octal
+    let none: Option<Ipv4Addr> = "255.0.0.01".parse().ok();
+    assert_eq!(None, none);
+    // octal zero
+    let none: Option<Ipv4Addr> = "255.0.0.00".parse().ok();
+    assert_eq!(None, none);
+    let none: Option<Ipv4Addr> = "255.0.00.0".parse().ok();
+    assert_eq!(None, none);
 }
 
 #[test]
diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs
index 88a8cb76bef..4e16a55edec 100644
--- a/library/std/src/net/parser.rs
+++ b/library/std/src/net/parser.rs
@@ -111,10 +111,12 @@ impl<'a> Parser<'a> {
         &mut self,
         radix: u32,
         max_digits: Option<usize>,
+        allow_zero_prefix: bool,
     ) -> Option<T> {
         self.read_atomically(move |p| {
             let mut result = T::ZERO;
             let mut digit_count = 0;
+            let has_leading_zero = p.peek_char() == Some('0');
 
             while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
                 result = result.checked_mul(radix)?;
@@ -127,7 +129,13 @@ impl<'a> Parser<'a> {
                 }
             }
 
-            if digit_count == 0 { None } else { Some(result) }
+            if digit_count == 0 {
+                None
+            } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
+                None
+            } else {
+                Some(result)
+            }
         })
     }
 
@@ -140,10 +148,7 @@ impl<'a> Parser<'a> {
                 *slot = p.read_separator('.', i, |p| {
                     // Disallow octal number in IP string.
                     // https://tools.ietf.org/html/rfc6943#section-3.1.1
-                    match (p.peek_char(), p.read_number(10, None)) {
-                        (Some('0'), Some(number)) if number != 0 => None,
-                        (_, number) => number,
-                    }
+                    p.read_number(10, Some(3), false)
                 })?;
             }
 
@@ -175,7 +180,7 @@ impl<'a> Parser<'a> {
                     }
                 }
 
-                let group = p.read_separator(':', i, |p| p.read_number(16, Some(4)));
+                let group = p.read_separator(':', i, |p| p.read_number(16, Some(4), true));
 
                 match group {
                     Some(g) => *slot = g,
@@ -227,7 +232,7 @@ impl<'a> Parser<'a> {
     fn read_port(&mut self) -> Option<u16> {
         self.read_atomically(|p| {
             p.read_given_char(':')?;
-            p.read_number(10, None)
+            p.read_number(10, None, true)
         })
     }
 
@@ -235,7 +240,7 @@ impl<'a> Parser<'a> {
     fn read_scope_id(&mut self) -> Option<u32> {
         self.read_atomically(|p| {
             p.read_given_char('%')?;
-            p.read_number(10, None)
+            p.read_number(10, None, true)
         })
     }
 
@@ -281,7 +286,12 @@ impl FromStr for IpAddr {
 impl FromStr for Ipv4Addr {
     type Err = AddrParseError;
     fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
-        Parser::new(s).parse_with(|p| p.read_ipv4_addr())
+        // don't try to parse if too long
+        if s.len() > 15 {
+            Err(AddrParseError(()))
+        } else {
+            Parser::new(s).parse_with(|p| p.read_ipv4_addr())
+        }
     }
 }
 
diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs
index 133c3e46cd8..11836b7b694 100644
--- a/library/std/src/sync/barrier.rs
+++ b/library/std/src/sync/barrier.rs
@@ -130,7 +130,7 @@ impl Barrier {
         if lock.count < self.num_threads {
             // We need a while loop to guard against spurious wakeups.
             // https://en.wikipedia.org/wiki/Spurious_wakeup
-            while local_gen == lock.generation_id && lock.count < self.num_threads {
+            while local_gen == lock.generation_id {
                 lock = self.cvar.wait(lock).unwrap();
             }
             BarrierWaitResult(false)