From 37777be83d3f336489405aecbf93b51a7ac9c8a5 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 19 2020 10:44:36 +0000 Subject: import icu-60.3-2.el8_1 --- diff --git a/SOURCES/ICU-13634-Adding-integer-overflow-logic-to-ICU4C-num.patch b/SOURCES/ICU-13634-Adding-integer-overflow-logic-to-ICU4C-num.patch new file mode 100644 index 0000000..8a4ceed --- /dev/null +++ b/SOURCES/ICU-13634-Adding-integer-overflow-logic-to-ICU4C-num.patch @@ -0,0 +1,108 @@ +From 23d76d88630ecee02515e2c8f5c8769cc795ae23 Mon Sep 17 00:00:00 2001 +From: Shane Carr +Date: Fri, 23 Mar 2018 00:56:16 +0000 +Subject: [PATCH] ICU-13634 Adding integer overflow logic to ICU4C number + pipeline in places where it is in ICU4J. + +X-SVN-Rev: 41136 + +diff --git a/icu4c/source/common/putil.cpp b/icu4c/source/common/putil.cpp +index 83f08ac070..452e2fd79c 100644 +--- a/icu4c/source/common/putil.cpp ++++ b/icu4c/source/common/putil.cpp +@@ -533,6 +533,30 @@ uprv_fmin(double x, double y) + return (x > y ? y : x); + } + ++#include ++ ++U_CAPI UBool U_EXPORT2 ++uprv_add32_overflow(int32_t a, int32_t b, int32_t* res) { ++ // NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_add_overflow. ++ // This function could be optimized by calling one of those primitives. ++ auto a64 = static_cast(a); ++ auto b64 = static_cast(b); ++ int64_t res64 = a64 + b64; ++ *res = static_cast(res64); ++ return res64 != *res; ++} ++ ++U_CAPI UBool U_EXPORT2 ++uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res) { ++ // NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_mul_overflow. ++ // This function could be optimized by calling one of those primitives. ++ auto a64 = static_cast(a); ++ auto b64 = static_cast(b); ++ int64_t res64 = a64 * b64; ++ *res = static_cast(res64); ++ return res64 != *res; ++} ++ + /** + * Truncates the given double. + * trunc(3.3) = 3.0, trunc (-3.3) = -3.0 +diff --git a/icu4c/source/common/putilimp.h b/icu4c/source/common/putilimp.h +index eb9b5380f1..8b858df9e3 100644 +--- a/icu4c/source/common/putilimp.h ++++ b/icu4c/source/common/putilimp.h +@@ -391,6 +391,32 @@ U_INTERNAL double U_EXPORT2 uprv_log(double d); + */ + U_INTERNAL double U_EXPORT2 uprv_round(double x); + ++/** ++ * Adds the signed integers a and b, storing the result in res. ++ * Checks for signed integer overflow. ++ * Similar to the GCC/Clang extension __builtin_add_overflow ++ * ++ * @param a The first operand. ++ * @param b The second operand. ++ * @param res a + b ++ * @return true if overflow occurred; false if no overflow occurred. ++ * @internal ++ */ ++U_INTERNAL UBool U_EXPORT2 uprv_add32_overflow(int32_t a, int32_t b, int32_t* res); ++ ++/** ++ * Multiplies the signed integers a and b, storing the result in res. ++ * Checks for signed integer overflow. ++ * Similar to the GCC/Clang extension __builtin_mul_overflow ++ * ++ * @param a The first multiplicand. ++ * @param b The second multiplicand. ++ * @param res a * b ++ * @return true if overflow occurred; false if no overflow occurred. ++ * @internal ++ */ ++U_INTERNAL UBool U_EXPORT2 uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res); ++ + #if 0 + /** + * Returns the number of digits after the decimal point in a double number x. +diff --git a/icu4c/source/test/cintltst/putiltst.c b/icu4c/source/test/cintltst/putiltst.c +index b99d9fca9c..1c3e073041 100644 +--- a/icu4c/source/test/cintltst/putiltst.c ++++ b/icu4c/source/test/cintltst/putiltst.c +@@ -128,6 +128,20 @@ static void TestPUtilAPI(void){ + log_err("ERROR: uprv_isInfinite failed.\n"); + } + ++ log_verbose("Testing the APIs uprv_add32_overflow and uprv_mul32_overflow\n"); ++ int32_t overflow_result; ++ doAssert(FALSE, uprv_add32_overflow(INT32_MAX - 2, 1, &overflow_result), "should not overflow"); ++ doAssert(INT32_MAX - 1, overflow_result, "should equal INT32_MAX - 1"); ++ doAssert(FALSE, uprv_add32_overflow(INT32_MAX - 2, 2, &overflow_result), "should not overflow"); ++ doAssert(INT32_MAX, overflow_result, "should equal exactly INT32_MAX"); ++ doAssert(TRUE, uprv_add32_overflow(INT32_MAX - 2, 3, &overflow_result), "should overflow"); ++ doAssert(FALSE, uprv_mul32_overflow(INT32_MAX / 5, 4, &overflow_result), "should not overflow"); ++ doAssert(INT32_MAX / 5 * 4, overflow_result, "should equal INT32_MAX / 5 * 4"); ++ doAssert(TRUE, uprv_mul32_overflow(INT32_MAX / 5, 6, &overflow_result), "should overflow"); ++ // Test on negative numbers: ++ doAssert(FALSE, uprv_add32_overflow(-3, -2, &overflow_result), "should not overflow"); ++ doAssert(-5, overflow_result, "should equal -5"); ++ + #if 0 + log_verbose("Testing the API uprv_digitsAfterDecimal()....\n"); + doAssert(uprv_digitsAfterDecimal(value1), 3, "uprv_digitsAfterDecimal() failed."); +-- +2.24.1 + diff --git a/SOURCES/ICU-20958-Prevent-SEGV_MAPERR-in-append.patch b/SOURCES/ICU-20958-Prevent-SEGV_MAPERR-in-append.patch new file mode 100644 index 0000000..adf88fc --- /dev/null +++ b/SOURCES/ICU-20958-Prevent-SEGV_MAPERR-in-append.patch @@ -0,0 +1,103 @@ +diff -ru icu/source/common/unistr.cpp icu.new/source/common/unistr.cpp +--- icu/source/common/unistr.cpp 2019-04-12 00:26:16.000000000 +0200 ++++ icu.new/source/common/unistr.cpp 2020-03-03 15:39:37.069874709 +0100 +@@ -1544,7 +1544,11 @@ + } + + int32_t oldLength = length(); +- int32_t newLength = oldLength + srcLength; ++ int32_t newLength; ++ if (uprv_add32_overflow(oldLength, srcLength, &newLength)) { ++ setToBogus(); ++ return *this; ++ } + // optimize append() onto a large-enough, owned string + if((newLength <= getCapacity() && isBufferWritable()) || + cloneArrayIfNeeded(newLength, getGrowCapacity(newLength))) { +diff -ru icu/source/test/intltest/ustrtest.cpp icu.new/source/test/intltest/ustrtest.cpp +--- icu/source/test/intltest/ustrtest.cpp 2019-04-12 00:26:16.000000000 +0200 ++++ icu.new/source/test/intltest/ustrtest.cpp 2020-03-03 15:44:59.059239188 +0100 +@@ -64,6 +64,7 @@ + TESTCASE_AUTO(TestUInt16Pointers); + TESTCASE_AUTO(TestWCharPointers); + TESTCASE_AUTO(TestNullPointers); ++ TESTCASE_AUTO(TestLargeAppend); + TESTCASE_AUTO_END; + } + +@@ -2248,3 +2249,64 @@ + UnicodeString(u"def").extract(nullptr, 0, errorCode); + assertEquals("buffer overflow extracting to nullptr", U_BUFFER_OVERFLOW_ERROR, errorCode); + } ++ ++void UnicodeStringTest::TestLargeAppend() { ++ if(quick) return; ++ ++ IcuTestErrorCode status(*this, "TestLargeAppend"); ++ // Make a large UnicodeString ++ int32_t len = 0xAFFFFFF; ++ UnicodeString str; ++ char16_t *buf = str.getBuffer(len); ++ // A fast way to set buffer to valid Unicode. ++ // 4E4E is a valid unicode character ++ uprv_memset(buf, 0x4e, len * 2); ++ str.releaseBuffer(len); ++ UnicodeString dest; ++ // Append it 16 times ++ // 0xAFFFFFF times 16 is 0xA4FFFFF1, ++ // which is greater than INT32_MAX, which is 0x7FFFFFFF. ++ int64_t total = 0; ++ for (int32_t i = 0; i < 16; i++) { ++ dest.append(str); ++ total += len; ++ if (total <= INT32_MAX) { ++ assertFalse("dest is not bogus", dest.isBogus()); ++ } else { ++ assertTrue("dest should be bogus", dest.isBogus()); ++ } ++ } ++ dest.remove(); ++ total = 0; ++ for (int32_t i = 0; i < 16; i++) { ++ dest.append(str); ++ total += len; ++ if (total + len <= INT32_MAX) { ++ assertFalse("dest is not bogus", dest.isBogus()); ++ } else if (total <= INT32_MAX) { ++ // Check that a string of exactly the maximum size works ++ UnicodeString str2; ++ int32_t remain = INT32_MAX - total; ++ char16_t *buf2 = str2.getBuffer(remain); ++ if (buf2 == nullptr) { ++ // if somehow memory allocation fail, return the test ++ return; ++ } ++ uprv_memset(buf2, 0x4e, remain * 2); ++ str2.releaseBuffer(remain); ++ dest.append(str2); ++ total += remain; ++ assertEquals("When a string of exactly the maximum size works", (int64_t)INT32_MAX, total); ++ assertEquals("When a string of exactly the maximum size works", INT32_MAX, dest.length()); ++ assertFalse("dest is not bogus", dest.isBogus()); ++ ++ // Check that a string size+1 goes bogus ++ str2.truncate(1); ++ dest.append(str2); ++ total++; ++ assertTrue("dest should be bogus", dest.isBogus()); ++ } else { ++ assertTrue("dest should be bogus", dest.isBogus()); ++ } ++ } ++} +diff -ru icu/source/test/intltest/ustrtest.h icu.new/source/test/intltest/ustrtest.h +--- icu/source/test/intltest/ustrtest.h 2019-04-12 00:26:16.000000000 +0200 ++++ icu.new/source/test/intltest/ustrtest.h 2020-03-03 15:45:36.147935611 +0100 +@@ -96,6 +96,7 @@ + void TestUInt16Pointers(); + void TestWCharPointers(); + void TestNullPointers(); ++ void TestLargeAppend(); + }; + + #endif diff --git a/SPECS/icu.spec b/SPECS/icu.spec index 2284b6d..ce0c5f2 100644 --- a/SPECS/icu.spec +++ b/SPECS/icu.spec @@ -2,7 +2,7 @@ Name: icu Version: 60.3 -Release: 1%{?dist} +Release: 2%{?dist} Summary: International Components for Unicode License: MIT and UCD and Public Domain @@ -20,6 +20,8 @@ Patch5: icuinfo-man.patch Patch6: negative-daylight-savings.patch Patch100: armv7hl-disable-tests.patch Patch101: icu-covscan.patch +Patch200: ICU-13634-Adding-integer-overflow-logic-to-ICU4C-num.patch +Patch201: ICU-20958-Prevent-SEGV_MAPERR-in-append.patch %description Tools and utilities for developing with icu. @@ -67,6 +69,8 @@ BuildArch: noarch %patch100 -p1 -b .armv7hl-disable-tests.patch %endif %patch101 -p1 -b .covscan +%patch200 -p2 -b .ICU-13634 +%patch201 -p1 -b .ICU-20958 %build pushd source @@ -190,6 +194,11 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l %changelog +* Tue Mar 03 2020 Mike FABIAN - 60.3-2 +- Apply ICU-13634-Adding-integer-overflow-logic-to-ICU4C-num.patch +- Apply ICU-20958-Prevent-SEGV_MAPERR-in-append.patch +- Resolves: rhbz#1808238 + * Tue May 07 2019 Mike FABIAN - 60.3-1 - Update to 60.3 maintenance release including support for new Japanese era Reiwa (令和). - Resolves: rhbz#1677093