Add upper bound length checks to `InlinedVector` capacity, size, and insertion methods

* Add unconditional `ThrowStdLengthError` checks across `InlinedVector` methods (`insert`, `emplace`, `emplace_back`, `push_back`, `resize`, `reserve`, `assign`, and constructors) when the requested size or element count exceeds `max_size()`.
* This prevents integer overflow when computing `size() + n` in `insert` (which could wrap around to `0` and cause `Storage::Insert` to bypass allocation and write out of bounds) across all build modes, and ensures full compliance with C++ standard container exception behavior (`std::length_error`) for exceeding `max_size()`.
* Update unit tests in `inlined_vector_test.cc` (`TEST(IntVec, LengthThrows)` and `TEST(IntVec, EmplaceLengthThrows)`) verifying that exceeding `max_size()` throws `std::length_error` (or cleanly terminates when exceptions are disabled).

PiperOrigin-RevId: 945154401
Change-Id: I8501776d3be95e85bfe5e89ce58429543b7392ff
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 8132564..744d3d9 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -72,7 +72,7 @@
 // designed to cover the same API footprint as covered by `std::vector`.
 template <typename T, size_t N, typename A = std::allocator<T>>
 class ABSL_ATTRIBUTE_WARN_UNUSED InlinedVector {
-  static_assert(N > 0, "`absl::InlinedVector` requires an inlined capacity.");
+  static_assert(N > 0, "absl::InlinedVector requires an inlined capacity.");
 
   using Storage = inlined_vector_internal::Storage<T, N, A>;
 
@@ -135,6 +135,9 @@
   explicit InlinedVector(size_type n,
                          const allocator_type& allocator = allocator_type())
       : storage_(allocator) {
+    if (ABSL_PREDICT_FALSE(n > max_size())) {
+      ThrowStdLengthError("InlinedVector::InlinedVector failed length check");
+    }
     storage_.Initialize(DefaultValueAdapter<A>(), n);
   }
 
@@ -142,6 +145,9 @@
   InlinedVector(size_type n, const_reference v,
                 const allocator_type& allocator = allocator_type())
       : storage_(allocator) {
+    if (ABSL_PREDICT_FALSE(n > max_size())) {
+      ThrowStdLengthError("InlinedVector::InlinedVector failed length check");
+    }
     storage_.Initialize(CopyValueAdapter<A>(std::addressof(v)), n);
   }
 
@@ -161,8 +167,11 @@
   InlinedVector(ForwardIterator first, ForwardIterator last,
                 const allocator_type& allocator = allocator_type())
       : storage_(allocator) {
-    storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first),
-                        static_cast<size_t>(std::distance(first, last)));
+    const size_type s = static_cast<size_type>(std::distance(first, last));
+    if (ABSL_PREDICT_FALSE(s > max_size())) {
+      ThrowStdLengthError("InlinedVector::InlinedVector failed length check");
+    }
+    storage_.Initialize(IteratorValueAdapter<A, ForwardIterator>(first), s);
   }
 
   // Creates an inlined vector with elements constructed from the provided input
@@ -383,7 +392,7 @@
   // in both debug and non-debug builds, `std::out_of_range` will be thrown.
   reference at(size_type i) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     if (ABSL_PREDICT_FALSE(i >= size())) {
-      ThrowStdOutOfRange("`InlinedVector::at(size_type)` failed bounds check");
+      ThrowStdOutOfRange("InlinedVector::at(size_type) failed bounds check");
     }
     return data()[i];
   }
@@ -395,8 +404,7 @@
   // in both debug and non-debug builds, `std::out_of_range` will be thrown.
   const_reference at(size_type i) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
     if (ABSL_PREDICT_FALSE(i >= size())) {
-      ThrowStdOutOfRange(
-          "`InlinedVector::at(size_type) const` failed bounds check");
+      ThrowStdOutOfRange("InlinedVector::at(size_type) failed bounds check");
     }
     return data()[i];
   }
@@ -558,6 +566,9 @@
   //
   // Replaces the contents of the inlined vector with `n` copies of `v`.
   void assign(size_type n, const_reference v) {
+    if (ABSL_PREDICT_FALSE(n > max_size())) {
+      ThrowStdLengthError("InlinedVector::assign failed length check");
+    }
     storage_.Assign(CopyValueAdapter<A>(std::addressof(v)), n);
   }
 
@@ -574,8 +585,11 @@
   template <typename ForwardIterator,
             EnableIfAtLeastForwardIterator<ForwardIterator> = 0>
   void assign(ForwardIterator first, ForwardIterator last) {
-    storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first),
-                    static_cast<size_t>(std::distance(first, last)));
+    const size_type s = static_cast<size_type>(std::distance(first, last));
+    if (ABSL_PREDICT_FALSE(s > max_size())) {
+      ThrowStdLengthError("InlinedVector::assign failed length check");
+    }
+    storage_.Assign(IteratorValueAdapter<A, ForwardIterator>(first), s);
   }
 
   // Overload of `InlinedVector::assign(...)` to replace the contents of the
@@ -601,7 +615,9 @@
   // NOTE: If `n` is smaller than `size()`, extra elements are destroyed. If `n`
   // is larger than `size()`, new elements are value-initialized.
   void resize(size_type n) {
-    absl::base_internal::HardeningAssertLE(n, max_size());
+    if (ABSL_PREDICT_FALSE(n > max_size())) {
+      ThrowStdLengthError("InlinedVector::resize failed length check");
+    }
     storage_.Resize(DefaultValueAdapter<A>(), n);
   }
 
@@ -611,7 +627,9 @@
   // NOTE: if `n` is smaller than `size()`, extra elements are destroyed. If `n`
   // is larger than `size()`, new elements are copied-constructed from `v`.
   void resize(size_type n, const_reference v) {
-    absl::base_internal::HardeningAssertLE(n, max_size());
+    if (ABSL_PREDICT_FALSE(n > max_size())) {
+      ThrowStdLengthError("InlinedVector::resize failed length check");
+    }
     storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n);
   }
 
@@ -638,6 +656,9 @@
                   const_reference v) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     absl::base_internal::HardeningAssertGE(pos, cbegin());
     absl::base_internal::HardeningAssertLE(pos, cend());
+    if (ABSL_PREDICT_FALSE(n > max_size() - size())) {
+      ThrowStdLengthError("InlinedVector::insert failed length check");
+    }
 
     if (ABSL_PREDICT_TRUE(n != 0)) {
       value_type dealias = v;
@@ -679,11 +700,14 @@
                   ForwardIterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     absl::base_internal::HardeningAssertGE(pos, cbegin());
     absl::base_internal::HardeningAssertLE(pos, cend());
+    const size_type s = static_cast<size_type>(std::distance(first, last));
+    if (ABSL_PREDICT_FALSE(s > max_size() - size())) {
+      ThrowStdLengthError("InlinedVector::insert failed length check");
+    }
 
     if (ABSL_PREDICT_TRUE(first != last)) {
       return storage_.Insert(
-          pos, IteratorValueAdapter<A, ForwardIterator>(first),
-          static_cast<size_type>(std::distance(first, last)));
+          pos, IteratorValueAdapter<A, ForwardIterator>(first), s);
     } else {
       return const_cast<iterator>(pos);
     }
@@ -718,6 +742,9 @@
                    Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
     absl::base_internal::HardeningAssertGE(pos, cbegin());
     absl::base_internal::HardeningAssertLE(pos, cend());
+    if (ABSL_PREDICT_FALSE(size() == max_size())) {
+      ThrowStdLengthError("InlinedVector::emplace failed length check");
+    }
 
     value_type dealias(std::forward<Args>(args)...);
     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102329#c2
@@ -744,6 +771,9 @@
   // `end()`, returning a `reference` to the newly emplaced element.
   template <typename... Args>
   reference emplace_back(Args&&... args) ABSL_ATTRIBUTE_LIFETIME_BOUND {
+    if (ABSL_PREDICT_FALSE(size() == max_size())) {
+      ThrowStdLengthError("InlinedVector::emplace_back failed length check");
+    }
     return storage_.EmplaceBack(std::forward<Args>(args)...);
   }
 
@@ -825,7 +855,12 @@
   // `InlinedVector::reserve(...)`
   //
   // Ensures that there is enough room for at least `n` elements.
-  void reserve(size_type n) { storage_.Reserve(n); }
+  void reserve(size_type n) {
+    if (ABSL_PREDICT_FALSE(n > max_size())) {
+      ThrowStdLengthError("InlinedVector::reserve failed length check");
+    }
+    storage_.Reserve(n);
+  }
 
   // `InlinedVector::shrink_to_fit()`
   //
diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc
index d6cc175..67b4368 100644
--- a/absl/container/inlined_vector_test.cc
+++ b/absl/container/inlined_vector_test.cc
@@ -207,6 +207,42 @@
                                  "failed bounds check");
 }
 
+TEST(IntVec, LengthThrows) {
+  IntVec v = {1, 2, 3};
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.insert(v.begin(), v.max_size() + 1, 0),
+                                 std::length_error, "failed length check");
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(
+      v.insert(v.begin(), static_cast<size_t>(-1), 0), std::length_error,
+      "failed length check");
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.resize(v.max_size() + 1), std::length_error,
+                                 "failed length check");
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.reserve(v.max_size() + 1), std::length_error,
+                                 "failed length check");
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(static_cast<void>(IntVec(v.max_size() + 1, 0)),
+                                 std::length_error, "failed length check");
+}
+
+template <typename T>
+struct SmallMaxAllocator : std::allocator<T> {
+  template <typename U>
+  struct rebind {
+    using other = SmallMaxAllocator<U>;
+  };
+  size_t max_size() const noexcept { return 2; }
+};
+
+TEST(IntVec, EmplaceLengthThrows) {
+  absl::InlinedVector<int, 1, SmallMaxAllocator<int>> v = {1, 2};
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.push_back(3), std::length_error,
+                                 "failed length check");
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.emplace_back(3), std::length_error,
+                                 "failed length check");
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.insert(v.begin(), 3), std::length_error,
+                                 "failed length check");
+  ABSL_BASE_INTERNAL_EXPECT_FAIL(v.emplace(v.begin(), 3), std::length_error,
+                                 "failed length check");
+}
+
 TEST(IntVec, ReverseIterator) {
   for (size_t len = 0; len < 20; len++) {
     IntVec v;
@@ -262,7 +298,6 @@
   absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
   EXPECT_DEATH_IF_SUPPORTED(v[10], "");
   EXPECT_DEATH_IF_SUPPORTED(v[static_cast<size_t>(-1)], "");
-  EXPECT_DEATH_IF_SUPPORTED(v.resize(v.max_size() + 1), "");
 #endif
 }