Avoid integer overflow & stack buffer overrun in ConvertStringArg (called from StrFormat())

The FixedArray size allocated is a multiple of the given buffer size, but this multiplication is not checked. It can potentially overflow and result in a small size that gets placed on the stack, thus resulting in a stack buffer overrun.

PiperOrigin-RevId: 944737638
Change-Id: Ib98028f3546c10b00447cd8f253a85786b647249
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc
index a51f7d7..fae98f4 100644
--- a/absl/strings/internal/str_format/arg.cc
+++ b/absl/strings/internal/str_format/arg.cc
@@ -25,6 +25,7 @@
 #include <cstdlib>
 #include <cstring>
 #include <cwchar>
+#include <limits>
 #include <string>
 #include <string_view>
 #include <type_traits>
@@ -313,7 +314,14 @@
                              size_t len,
                              const FormatConversionSpecImpl conv,
                              FormatSinkImpl *sink) {
-  FixedArray<char> mb(len * 4);
+  // Each wide character may result in up to 4 bytes (UTF-8 code units).
+  constexpr size_t kMaxUtf8CodeUnitsPerWideChar = 4;
+  if (len > (std::numeric_limits<decltype(len)>::max)() /
+                kMaxUtf8CodeUnitsPerWideChar) {
+    // Size too large; we can't handle this.
+    return false;
+  }
+  FixedArray<char> mb(len * kMaxUtf8CodeUnitsPerWideChar);
   strings_internal::ShiftState s;
   size_t chars_written = 0;
   for (size_t i = 0; i < len; ++i) {