ICU-13823 Merged #13840 number parser memory overflow fix (r41541) to maint-62 for 62.1 GA.

X-SVN-Rev: 41542
diff --git a/icu4c/source/i18n/number_decimalquantity.cpp b/icu4c/source/i18n/number_decimalquantity.cpp
index 8830419..9d80e33 100644
--- a/icu4c/source/i18n/number_decimalquantity.cpp
+++ b/icu4c/source/i18n/number_decimalquantity.cpp
@@ -1058,7 +1058,7 @@
         auto bcd1 = static_cast<int8_t*>(uprv_malloc(capacity * 2 * sizeof(int8_t)));
         uprv_memcpy(bcd1, fBCD.bcdBytes.ptr, oldCapacity * sizeof(int8_t));
         // Initialize the rest of the byte array to zeros (this is done automatically in Java)
-        uprv_memset(fBCD.bcdBytes.ptr + oldCapacity, 0, (capacity - oldCapacity) * sizeof(int8_t));
+        uprv_memset(bcd1 + oldCapacity, 0, (capacity - oldCapacity) * sizeof(int8_t));
         uprv_free(fBCD.bcdBytes.ptr);
         fBCD.bcdBytes.ptr = bcd1;
         fBCD.bcdBytes.len = capacity * 2;
diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp
index f5fb64e..b718429 100644
--- a/icu4c/source/test/intltest/numfmtst.cpp
+++ b/icu4c/source/test/intltest/numfmtst.cpp
@@ -215,6 +215,7 @@
   TESTCASE_AUTO(Test13763_FieldPositionIteratorOffset);
   TESTCASE_AUTO(Test13777_ParseLongNameNonCurrencyMode);
   TESTCASE_AUTO(Test13804_EmptyStringsWhenParsing);
+  TESTCASE_AUTO(Test13840_ParseLongStringCrash);
   TESTCASE_AUTO_END;
 }
 
@@ -9154,4 +9155,34 @@
     }
 }
 
+void NumberFormatTest::Test13840_ParseLongStringCrash() {
+    IcuTestErrorCode status(*this, "Test13840_ParseLongStringCrash");
+
+    LocalPointer<NumberFormat> nf(NumberFormat::createInstance("en", status), status);
+    if (status.errIfFailureAndReset()) { return; }
+
+    Formattable result;
+    static const char16_t* bigString =
+        u"111111111111111111111111111111111111111111111111111111111111111111111"
+        u"111111111111111111111111111111111111111111111111111111111111111111111"
+        u"111111111111111111111111111111111111111111111111111111111111111111111"
+        u"111111111111111111111111111111111111111111111111111111111111111111111"
+        u"111111111111111111111111111111111111111111111111111111111111111111111"
+        u"111111111111111111111111111111111111111111111111111111111111111111111";
+    nf->parse(bigString, result, status);
+
+    // Normalize the input string:
+    CharString expectedChars;
+    expectedChars.appendInvariantChars(bigString, status);
+    DecimalQuantity expectedDQ;
+    expectedDQ.setToDecNumber(expectedChars.toStringPiece(), status);
+    UnicodeString expectedUString = expectedDQ.toScientificString();
+
+    // Get the output string:
+    StringPiece actualChars = result.getDecimalNumber(status);
+    UnicodeString actualUString = UnicodeString(actualChars.data(), actualChars.length(), US_INV);
+
+    assertEquals("Should round-trip without crashing", expectedUString, actualUString);
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h
index 1c7c862..b51e752 100644
--- a/icu4c/source/test/intltest/numfmtst.h
+++ b/icu4c/source/test/intltest/numfmtst.h
@@ -279,6 +279,7 @@
     void Test13763_FieldPositionIteratorOffset();
     void Test13777_ParseLongNameNonCurrencyMode();
     void Test13804_EmptyStringsWhenParsing();
+    void Test13840_ParseLongStringCrash();
 
  private:
     UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
index 78bf6b5..effd33f 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
@@ -6223,4 +6223,27 @@
             df.parse("1E+2.3", ppos);
         }
     }
+
+    @Test
+    public void test13840_ParseLongStringCrash() throws ParseException {
+        NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH);
+        String bigString =
+            "111111111111111111111111111111111111111111111111111111111111111111111" +
+            "111111111111111111111111111111111111111111111111111111111111111111111" +
+            "111111111111111111111111111111111111111111111111111111111111111111111" +
+            "111111111111111111111111111111111111111111111111111111111111111111111" +
+            "111111111111111111111111111111111111111111111111111111111111111111111" +
+            "111111111111111111111111111111111111111111111111111111111111111111111";
+        Number result = nf.parse(bigString);
+
+        // Normalize the input string:
+        BigDecimal expectedBigDecimal = new BigDecimal(bigString);
+        String expectedUString = expectedBigDecimal.toString();
+
+        // Get the output string:
+        BigDecimal actualBigDecimal = (BigDecimal) result;
+        String actualUString = actualBigDecimal.toString();
+
+        assertEquals("Should round-trip without crashing", expectedUString, actualUString);
+    }
 }