import icu-60.3-2.el8_1
This commit is contained in:
parent
5c9b25fb39
commit
c3951b7104
@ -0,0 +1,108 @@
|
|||||||
|
From 23d76d88630ecee02515e2c8f5c8769cc795ae23 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Shane Carr <shane@unicode.org>
|
||||||
|
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 <iostream>
|
||||||
|
+
|
||||||
|
+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<int64_t>(a);
|
||||||
|
+ auto b64 = static_cast<int64_t>(b);
|
||||||
|
+ int64_t res64 = a64 + b64;
|
||||||
|
+ *res = static_cast<int32_t>(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<int64_t>(a);
|
||||||
|
+ auto b64 = static_cast<int64_t>(b);
|
||||||
|
+ int64_t res64 = a64 * b64;
|
||||||
|
+ *res = static_cast<int32_t>(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
|
||||||
|
|
103
SOURCES/ICU-20958-Prevent-SEGV_MAPERR-in-append.patch
Normal file
103
SOURCES/ICU-20958-Prevent-SEGV_MAPERR-in-append.patch
Normal file
@ -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
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Name: icu
|
Name: icu
|
||||||
Version: 60.3
|
Version: 60.3
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
Summary: International Components for Unicode
|
Summary: International Components for Unicode
|
||||||
|
|
||||||
License: MIT and UCD and Public Domain
|
License: MIT and UCD and Public Domain
|
||||||
@ -20,6 +20,8 @@ Patch5: icuinfo-man.patch
|
|||||||
Patch6: negative-daylight-savings.patch
|
Patch6: negative-daylight-savings.patch
|
||||||
Patch100: armv7hl-disable-tests.patch
|
Patch100: armv7hl-disable-tests.patch
|
||||||
Patch101: icu-covscan.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
|
%description
|
||||||
Tools and utilities for developing with icu.
|
Tools and utilities for developing with icu.
|
||||||
@ -67,6 +69,8 @@ BuildArch: noarch
|
|||||||
%patch100 -p1 -b .armv7hl-disable-tests.patch
|
%patch100 -p1 -b .armv7hl-disable-tests.patch
|
||||||
%endif
|
%endif
|
||||||
%patch101 -p1 -b .covscan
|
%patch101 -p1 -b .covscan
|
||||||
|
%patch200 -p2 -b .ICU-13634
|
||||||
|
%patch201 -p1 -b .ICU-20958
|
||||||
|
|
||||||
%build
|
%build
|
||||||
pushd source
|
pushd source
|
||||||
@ -190,6 +194,11 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Mar 03 2020 Mike FABIAN <mfabian@redhat.com> - 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 <mfabian@redhat.com> - 60.3-1
|
* Tue May 07 2019 Mike FABIAN <mfabian@redhat.com> - 60.3-1
|
||||||
- Update to 60.3 maintenance release including support for new Japanese era Reiwa (令和).
|
- Update to 60.3 maintenance release including support for new Japanese era Reiwa (令和).
|
||||||
- Resolves: rhbz#1677093
|
- Resolves: rhbz#1677093
|
||||||
|
Loading…
Reference in New Issue
Block a user