Cherry pick upstream patch for integer overflow

Fix: https://github.com/unicode-org/icu/pull/253

Bug: https://unicode-org.atlassian.net/browse/ICU-20246

TBR=ftang@chromium.org
Bug: 900059
Test: See the bug
Change-Id: I6c75502e44b41f7b77f6f6265dfd099e42196178
Reviewed-on: https://chromium-review.googlesource.com/c/1312653
Reviewed-by: Jungshik Shin <jshin@chromium.org>
diff --git a/README.chromium b/README.chromium
index 1d98c85..143d973 100644
--- a/README.chromium
+++ b/README.chromium
@@ -243,3 +243,13 @@
   - upstream bugs:
     https://unicode-org.atlassian.net/browse/ICU-20222
   - Fix: https://github.com/unicode-org/icu/pull/228
+
+8. Fix an integer overflow in the number parsing
+
+  - patches/numparse_overflow.patch
+  - upstream bug:
+    https://unicode-org.atlassian.net/browse/ICU-20246
+  - Fix:
+    https://github.com/unicode-org/icu/pull/253
+           
+
diff --git a/patches/numparse_overflow.patch b/patches/numparse_overflow.patch
new file mode 100644
index 0000000..195fda6
--- /dev/null
+++ b/patches/numparse_overflow.patch
@@ -0,0 +1,29 @@
+diff --git a/source/i18n/fmtable.cpp b/source/i18n/fmtable.cpp
+index 45c7024f..8601d95f 100644
+--- a/source/i18n/fmtable.cpp
++++ b/source/i18n/fmtable.cpp
+@@ -734,7 +734,7 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) {
+       // not print scientific notation for magnitudes greater than -5 and smaller than some amount (+5?).
+       if (fDecimalQuantity->isZero()) {
+         fDecimalStr->append("0", -1, status);
+-      } else if (std::abs(fDecimalQuantity->getMagnitude()) < 5) {
++      } else if (fDecimalQuantity->getMagnitude() != INT32_MIN && std::abs(fDecimalQuantity->getMagnitude()) < 5) {
+         fDecimalStr->appendInvariantChars(fDecimalQuantity->toPlainString(), status);
+       } else {
+         fDecimalStr->appendInvariantChars(fDecimalQuantity->toScientificString(), status);
+diff --git a/source/i18n/number_decimalquantity.cpp b/source/i18n/number_decimalquantity.cpp
+index 2c4182b1..f6f2b20f 100644
+--- a/source/i18n/number_decimalquantity.cpp
++++ b/source/i18n/number_decimalquantity.cpp
+@@ -820,7 +820,10 @@ UnicodeString DecimalQuantity::toScientificString() const {
+     }
+     result.append(u'E');
+     int32_t _scale = upperPos + scale;
+-    if (_scale < 0) {
++    if (_scale == INT32_MIN) {
++        result.append({u"-2147483648", -1});
++        return result;
++    } else if (_scale < 0) {
+         _scale *= -1;
+         result.append(u'-');
+     } else {
diff --git a/source/i18n/fmtable.cpp b/source/i18n/fmtable.cpp
index 45c7024..8601d95 100644
--- a/source/i18n/fmtable.cpp
+++ b/source/i18n/fmtable.cpp
@@ -734,7 +734,7 @@
       // not print scientific notation for magnitudes greater than -5 and smaller than some amount (+5?).
       if (fDecimalQuantity->isZero()) {
         fDecimalStr->append("0", -1, status);
-      } else if (std::abs(fDecimalQuantity->getMagnitude()) < 5) {
+      } else if (fDecimalQuantity->getMagnitude() != INT32_MIN && std::abs(fDecimalQuantity->getMagnitude()) < 5) {
         fDecimalStr->appendInvariantChars(fDecimalQuantity->toPlainString(), status);
       } else {
         fDecimalStr->appendInvariantChars(fDecimalQuantity->toScientificString(), status);
diff --git a/source/i18n/number_decimalquantity.cpp b/source/i18n/number_decimalquantity.cpp
index 2c4182b..f6f2b20 100644
--- a/source/i18n/number_decimalquantity.cpp
+++ b/source/i18n/number_decimalquantity.cpp
@@ -820,7 +820,10 @@
     }
     result.append(u'E');
     int32_t _scale = upperPos + scale;
-    if (_scale < 0) {
+    if (_scale == INT32_MIN) {
+        result.append({u"-2147483648", -1});
+        return result;
+    } else if (_scale < 0) {
         _scale *= -1;
         result.append(u'-');
     } else {