Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable] std: Check for overflow in str::repeat #54397

Merged
merged 1 commit into from Sep 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions 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)
==========================

Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/channel.rs
Expand Up @@ -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>,
Expand Down
16 changes: 15 additions & 1 deletion src/liballoc/slice.rs
Expand Up @@ -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:
Expand All @@ -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")]
Expand All @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions src/liballoc/str.rs
Expand Up @@ -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
Expand All @@ -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)) }
Expand Down