update net-mail/vacation
[portage-squeep] / dev-libs / icu / files / icu-65.1-integer-overflow.patch
1 From b7d08bc04a4296982fcef8b6b8a354a9e4e7afca Mon Sep 17 00:00:00 2001
2 From: Frank Tang <ftang@chromium.org>
3 Date: Sat, 1 Feb 2020 02:39:04 +0000
4 Subject: [PATCH] ICU-20958 Prevent SEGV_MAPERR in append
5
6 See #971
7 ---
8 common/unistr.cpp | 6 ++-
9 test/intltest/ustrtest.cpp | 62 +++++++++++++++++++++++++
10 test/intltest/ustrtest.h | 1 +
11 3 files changed, 68 insertions(+), 1 deletion(-)
12
13 diff --git a/common/unistr.cpp b/common/unistr.cpp
14 index 901bb3358ba..077b4d6ef20 100644
15 --- a/common/unistr.cpp
16 +++ b/common/unistr.cpp
17 @@ -1563,7 +1563,11 @@ UnicodeString::doAppend(const UChar *srcChars, int32_t srcStart, int32_t srcLeng
18 }
19
20 int32_t oldLength = length();
21 - int32_t newLength = oldLength + srcLength;
22 + int32_t newLength;
23 + if (uprv_add32_overflow(oldLength, srcLength, &newLength)) {
24 + setToBogus();
25 + return *this;
26 + }
27
28 // Check for append onto ourself
29 const UChar* oldArray = getArrayStart();
30 diff --git a/test/intltest/ustrtest.cpp b/test/intltest/ustrtest.cpp
31 index b6515ea813c..ad38bdf53a3 100644
32 --- a/test/intltest/ustrtest.cpp
33 +++ b/test/intltest/ustrtest.cpp
34 @@ -67,6 +67,7 @@ void UnicodeStringTest::runIndexedTest( int32_t index, UBool exec, const char* &
35 TESTCASE_AUTO(TestWCharPointers);
36 TESTCASE_AUTO(TestNullPointers);
37 TESTCASE_AUTO(TestUnicodeStringInsertAppendToSelf);
38 + TESTCASE_AUTO(TestLargeAppend);
39 TESTCASE_AUTO_END;
40 }
41
42 @@ -2310,3 +2311,64 @@ void UnicodeStringTest::TestUnicodeStringInsertAppendToSelf() {
43 str.insert(2, sub);
44 assertEquals("", u"abbcdcde", str);
45 }
46 +
47 +void UnicodeStringTest::TestLargeAppend() {
48 + if(quick) return;
49 +
50 + IcuTestErrorCode status(*this, "TestLargeAppend");
51 + // Make a large UnicodeString
52 + int32_t len = 0xAFFFFFF;
53 + UnicodeString str;
54 + char16_t *buf = str.getBuffer(len);
55 + // A fast way to set buffer to valid Unicode.
56 + // 4E4E is a valid unicode character
57 + uprv_memset(buf, 0x4e, len * 2);
58 + str.releaseBuffer(len);
59 + UnicodeString dest;
60 + // Append it 16 times
61 + // 0xAFFFFFF times 16 is 0xA4FFFFF1,
62 + // which is greater than INT32_MAX, which is 0x7FFFFFFF.
63 + int64_t total = 0;
64 + for (int32_t i = 0; i < 16; i++) {
65 + dest.append(str);
66 + total += len;
67 + if (total <= INT32_MAX) {
68 + assertFalse("dest is not bogus", dest.isBogus());
69 + } else {
70 + assertTrue("dest should be bogus", dest.isBogus());
71 + }
72 + }
73 + dest.remove();
74 + total = 0;
75 + for (int32_t i = 0; i < 16; i++) {
76 + dest.append(str);
77 + total += len;
78 + if (total + len <= INT32_MAX) {
79 + assertFalse("dest is not bogus", dest.isBogus());
80 + } else if (total <= INT32_MAX) {
81 + // Check that a string of exactly the maximum size works
82 + UnicodeString str2;
83 + int32_t remain = INT32_MAX - total;
84 + char16_t *buf2 = str2.getBuffer(remain);
85 + if (buf2 == nullptr) {
86 + // if somehow memory allocation fail, return the test
87 + return;
88 + }
89 + uprv_memset(buf2, 0x4e, remain * 2);
90 + str2.releaseBuffer(remain);
91 + dest.append(str2);
92 + total += remain;
93 + assertEquals("When a string of exactly the maximum size works", (int64_t)INT32_MAX, total);
94 + assertEquals("When a string of exactly the maximum size works", INT32_MAX, dest.length());
95 + assertFalse("dest is not bogus", dest.isBogus());
96 +
97 + // Check that a string size+1 goes bogus
98 + str2.truncate(1);
99 + dest.append(str2);
100 + total++;
101 + assertTrue("dest should be bogus", dest.isBogus());
102 + } else {
103 + assertTrue("dest should be bogus", dest.isBogus());
104 + }
105 + }
106 +}
107 diff --git a/test/intltest/ustrtest.h b/test/intltest/ustrtest.h
108 index 218befdcc68..4a356a92c7a 100644
109 --- a/test/intltest/ustrtest.h
110 +++ b/test/intltest/ustrtest.h
111 @@ -97,6 +97,7 @@ class UnicodeStringTest: public IntlTest {
112 void TestWCharPointers();
113 void TestNullPointers();
114 void TestUnicodeStringInsertAppendToSelf();
115 + void TestLargeAppend();
116 };
117
118 #endif