summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md13
-rw-r--r--src/bootstrap/channel.rs2
-rw-r--r--src/liballoc/slice.rs16
-rw-r--r--src/liballoc/str.rs13
4 files changed, 42 insertions, 2 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 82472df727a..6492f725318 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,16 @@
+Version 1.29.1 (2018-09-25)
+===========================
+
+Security Notes
+--------------
+
+- The standard library's `str::repeat` function contained an out of bounds write
+  caused by an integer overflow. This has been fixed by deterministically
+  panicking when an overflow happens.
+
+  Thank you to Scott McMurray for responsibily disclosing this vulnerability to
+  us.
+
 Version 1.29.0 (2018-09-13)
 ==========================
 
diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs
index 04d576df955..e9540d6376a 100644
--- a/src/bootstrap/channel.rs
+++ b/src/bootstrap/channel.rs
@@ -24,7 +24,7 @@ use Build;
 use config::Config;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.29.0";
+pub const CFG_RELEASE_NUM: &str = "1.29.1";
 
 pub struct GitInfo {
     inner: Option<Info>,
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index c27c596e797..73a48e65449 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -392,6 +392,10 @@ impl<T> [T] {
 
     /// Creates a vector by repeating a slice `n` times.
     ///
+    /// # Panics
+    ///
+    /// This function will panic if the capacity would overflow.
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -403,6 +407,16 @@ impl<T> [T] {
     ///     assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
     /// }
     /// ```
+    ///
+    /// A panic upon overflow:
+    ///
+    /// ```should_panic
+    /// #![feature(repeat_generic_slice)]
+    /// fn main() {
+    ///     // this will panic at runtime
+    ///     b"0123456789abcdef".repeat(usize::max_value());
+    /// }
+    /// ```
     #[unstable(feature = "repeat_generic_slice",
                reason = "it's on str, why not on slice?",
                issue = "48784")]
@@ -417,7 +431,7 @@ impl<T> [T] {
         // and `rem` is the remaining part of `n`.
 
         // Using `Vec` to access `set_len()`.
-        let mut buf = Vec::with_capacity(self.len() * n);
+        let mut buf = Vec::with_capacity(self.len().checked_mul(n).expect("capacity overflow"));
 
         // `2^expn` repetition is done by doubling `buf` `expn`-times.
         buf.extend(self);
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 870bf971cd3..f1bc9a83988 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -515,6 +515,10 @@ impl str {
 
     /// Create a [`String`] by repeating a string `n` times.
     ///
+    /// # Panics
+    ///
+    /// This function will panic if the capacity would overflow.
+    ///
     /// [`String`]: string/struct.String.html
     ///
     /// # Examples
@@ -524,6 +528,15 @@ impl str {
     /// ```
     /// assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));
     /// ```
+    ///
+    /// A panic upon overflow:
+    ///
+    /// ```should_panic
+    /// fn main() {
+    ///     // this will panic at runtime
+    ///     "0123456789abcdef".repeat(usize::max_value());
+    /// }
+    /// ```
     #[stable(feature = "repeat_str", since = "1.16.0")]
     pub fn repeat(&self, n: usize) -> String {
         unsafe { String::from_utf8_unchecked(self.as_bytes().repeat(n)) }