ICU-21410 fix int32_t overflow in listFormat

See #1479
diff --git a/icu4c/source/i18n/formatted_string_builder.cpp b/icu4c/source/i18n/formatted_string_builder.cpp
index 5aabc31..b370f14 100644
--- a/icu4c/source/i18n/formatted_string_builder.cpp
+++ b/icu4c/source/i18n/formatted_string_builder.cpp
@@ -276,6 +276,11 @@
     char16_t *oldChars = getCharPtr();
     Field *oldFields = getFieldPtr();
     if (fLength + count > oldCapacity) {
+        if ((fLength + count) > INT32_MAX / 2) {
+            // If we continue, then newCapacity will overlow int32_t in the next line.
+            status = U_INPUT_TOO_LONG_ERROR;
+            return -1;
+        }
         int32_t newCapacity = (fLength + count) * 2;
         int32_t newZero = newCapacity / 2 - (fLength + count) / 2;
 
@@ -330,12 +335,14 @@
         fZero = newZero;
         fLength += count;
     }
+    U_ASSERT((fZero + index) >= 0);
     return fZero + index;
 }
 
 int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) {
     // TODO: Reset the heap here?  (If the string after removal can fit on stack?)
     int32_t position = index + fZero;
+    U_ASSERT(position >= 0);
     uprv_memmove2(getCharPtr() + position,
             getCharPtr() + position + count,
             sizeof(char16_t) * (fLength - index - count));
diff --git a/icu4c/source/test/intltest/listformattertest.cpp b/icu4c/source/test/intltest/listformattertest.cpp
index 513d63e..34536e6 100644
--- a/icu4c/source/test/intltest/listformattertest.cpp
+++ b/icu4c/source/test/intltest/listformattertest.cpp
@@ -49,6 +49,7 @@
     TESTCASE_AUTO(TestCreateStyled);
     TESTCASE_AUTO(TestContextual);
     TESTCASE_AUTO(TestNextPosition);
+    TESTCASE_AUTO(TestInt32Overflow);
     TESTCASE_AUTO_END;
 }
 
@@ -828,4 +829,20 @@
     }
 }
 
+void ListFormatterTest::TestInt32Overflow() {
+    if (quick) {
+        return;
+    }
+    IcuTestErrorCode status(*this, "TestInt32Overflow");
+    LocalPointer<ListFormatter> fmt(ListFormatter::createInstance("en", status), status);
+    std::vector<UnicodeString> inputs;
+    UnicodeString input(0xAAAFF00, 0x00000042, 0xAAAFF00);
+    for (int32_t i = 0; i < 16; i++) {
+      inputs.push_back(input);
+    }
+    FormattedList result = fmt->formatStringsToValue(
+        inputs.data(), static_cast<int32_t>(inputs.size()), status);
+    status.expectErrorAndReset(U_INPUT_TOO_LONG_ERROR);
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/icu4c/source/test/intltest/listformattertest.h b/icu4c/source/test/intltest/listformattertest.h
index b3d4005..aeba483 100644
--- a/icu4c/source/test/intltest/listformattertest.h
+++ b/icu4c/source/test/intltest/listformattertest.h
@@ -56,6 +56,7 @@
     void TestCreateStyled();
     void TestContextual();
     void TestNextPosition();
+    void TestInt32Overflow();
 
   private:
     void CheckFormatting(