diff options
| author | The8472 <git@infinite-source.de> | 2021-03-31 23:09:28 +0200 |
|---|---|---|
| committer | The8472 <git@infinite-source.de> | 2021-03-31 23:09:28 +0200 |
| commit | ad3a791e2a8c0300090fa73d4ce414a738346a41 (patch) | |
| tree | 9d57bf3fecd0771f47c531dbaf8a9d6f23fe9b68 /library/alloc/src/vec | |
| parent | a5029ac0ab372aec515db2e718da6d7787f3d122 (diff) | |
| download | rust-ad3a791e2a8c0300090fa73d4ce414a738346a41.tar.gz rust-ad3a791e2a8c0300090fa73d4ce414a738346a41.zip | |
panic early when TrustedLen indicates a length > usize::MAX
Diffstat (limited to 'library/alloc/src/vec')
| -rw-r--r-- | library/alloc/src/vec/mod.rs | 8 | ||||
| -rw-r--r-- | library/alloc/src/vec/spec_extend.rs | 7 | ||||
| -rw-r--r-- | library/alloc/src/vec/spec_from_iter_nested.rs | 9 |
3 files changed, 20 insertions, 4 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 20c2aae1789..91c3b16deee 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -410,6 +410,10 @@ impl<T> Vec<T> { /// /// [Capacity and reallocation]: #capacity-and-reallocation /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// /// # Examples /// /// ``` @@ -541,6 +545,10 @@ impl<T, A: Allocator> Vec<T, A> { /// /// [Capacity and reallocation]: #capacity-and-reallocation /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` bytes. + /// /// # Examples /// /// ``` diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index b6186a7ebaf..e132befcfa5 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -47,7 +47,12 @@ where }); } } else { - self.extend_desugared(iterator) + // Per TrustedLen contract a `None` upper bound means that the iterator length + // truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway. + // Since the other branch already panics eagerly (via `reserve()`) we do the same here. + // This avoids additional codegen for a fallback code path which would eventually + // panic anyway. + panic!("capacity overflow"); } } } diff --git a/library/alloc/src/vec/spec_from_iter_nested.rs b/library/alloc/src/vec/spec_from_iter_nested.rs index ec390c62165..948cf044197 100644 --- a/library/alloc/src/vec/spec_from_iter_nested.rs +++ b/library/alloc/src/vec/spec_from_iter_nested.rs @@ -46,10 +46,13 @@ where fn from_iter(iterator: I) -> Self { let mut vector = match iterator.size_hint() { (_, Some(upper)) => Vec::with_capacity(upper), - _ => Vec::new(), + // TrustedLen contract guarantees that `size_hint() == (_, None)` means that there + // are more than `usize::MAX` elements. + // Since the previous branch would eagerly panic if the capacity is too large + // (via `with_capacity`) we do the same here. + _ => panic!("capacity overflow"), }; - // must delegate to spec_extend() since extend() itself delegates - // to spec_from for empty Vecs + // reuse extend specialization for TrustedLen vector.spec_extend(iterator); vector } |
