mirror of
https://abf.rosa.ru/djam/icu.git
synced 2025-02-23 19:02:50 +00:00
commit
54da52d6ab
7 changed files with 771 additions and 1 deletions
232
CVE-2016-6293.patch
Normal file
232
CVE-2016-6293.patch
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
Index: /source/common/uloc.cpp
|
||||||
|
===================================================================
|
||||||
|
--- /source/common/uloc.cpp (revision 39108)
|
||||||
|
+++ /source/common/uloc.cpp (revision 39109)
|
||||||
|
@@ -2247,5 +2247,5 @@
|
||||||
|
float q;
|
||||||
|
int32_t dummy; /* to avoid uninitialized memory copy from qsort */
|
||||||
|
- char *locale;
|
||||||
|
+ char locale[ULOC_FULLNAME_CAPACITY+1];
|
||||||
|
} _acceptLangItem;
|
||||||
|
|
||||||
|
@@ -2289,7 +2289,5 @@
|
||||||
|
UErrorCode *status)
|
||||||
|
{
|
||||||
|
- _acceptLangItem *j;
|
||||||
|
- _acceptLangItem smallBuffer[30];
|
||||||
|
- char **strs;
|
||||||
|
+ MaybeStackArray<_acceptLangItem, 4> items; // Struct for collecting items.
|
||||||
|
char tmp[ULOC_FULLNAME_CAPACITY +1];
|
||||||
|
int32_t n = 0;
|
||||||
|
@@ -2301,9 +2299,5 @@
|
||||||
|
int32_t i;
|
||||||
|
int32_t l = (int32_t)uprv_strlen(httpAcceptLanguage);
|
||||||
|
- int32_t jSize;
|
||||||
|
- char *tempstr; /* Use for null pointer check */
|
||||||
|
-
|
||||||
|
- j = smallBuffer;
|
||||||
|
- jSize = UPRV_LENGTHOF(smallBuffer);
|
||||||
|
+
|
||||||
|
if(U_FAILURE(*status)) {
|
||||||
|
return -1;
|
||||||
|
@@ -2333,25 +2327,27 @@
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
- j[n].q = (float)_uloc_strtod(t,NULL);
|
||||||
|
+ items[n].q = (float)_uloc_strtod(t,NULL);
|
||||||
|
} else {
|
||||||
|
/* no semicolon - it's 1.0 */
|
||||||
|
- j[n].q = 1.0f;
|
||||||
|
+ items[n].q = 1.0f;
|
||||||
|
paramEnd = itemEnd;
|
||||||
|
}
|
||||||
|
- j[n].dummy=0;
|
||||||
|
+ items[n].dummy=0;
|
||||||
|
/* eat spaces prior to semi */
|
||||||
|
for(t=(paramEnd-1);(paramEnd>s)&&isspace(*t);t--)
|
||||||
|
;
|
||||||
|
- /* Check for null pointer from uprv_strndup */
|
||||||
|
- tempstr = uprv_strndup(s,(int32_t)((t+1)-s));
|
||||||
|
- if (tempstr == NULL) {
|
||||||
|
- *status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- j[n].locale = tempstr;
|
||||||
|
- uloc_canonicalize(j[n].locale,tmp,UPRV_LENGTHOF(tmp),status);
|
||||||
|
- if(strcmp(j[n].locale,tmp)) {
|
||||||
|
- uprv_free(j[n].locale);
|
||||||
|
- j[n].locale=uprv_strdup(tmp);
|
||||||
|
+ int32_t slen = ((t+1)-s);
|
||||||
|
+ if(slen > ULOC_FULLNAME_CAPACITY) {
|
||||||
|
+ *status = U_BUFFER_OVERFLOW_ERROR;
|
||||||
|
+ return -1; // too big
|
||||||
|
+ }
|
||||||
|
+ uprv_strncpy(items[n].locale, s, slen);
|
||||||
|
+ items[n].locale[slen]=0; // terminate
|
||||||
|
+ int32_t clen = uloc_canonicalize(items[n].locale, tmp, UPRV_LENGTHOF(tmp)-1, status);
|
||||||
|
+ if(U_FAILURE(*status)) return -1;
|
||||||
|
+ if((clen!=slen) || (uprv_strncmp(items[n].locale, tmp, slen))) {
|
||||||
|
+ // canonicalization had an effect- copy back
|
||||||
|
+ uprv_strncpy(items[n].locale, tmp, clen);
|
||||||
|
+ items[n].locale[clen] = 0; // terminate
|
||||||
|
}
|
||||||
|
#if defined(ULOC_DEBUG)
|
||||||
|
@@ -2363,42 +2359,18 @@
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
- if(n>=jSize) {
|
||||||
|
- if(j==smallBuffer) { /* overflowed the small buffer. */
|
||||||
|
- j = static_cast<_acceptLangItem *>(uprv_malloc(sizeof(j[0])*(jSize*2)));
|
||||||
|
- if(j!=NULL) {
|
||||||
|
- uprv_memcpy(j,smallBuffer,sizeof(j[0])*jSize);
|
||||||
|
- }
|
||||||
|
+ if(n>=items.getCapacity()) { // If we need more items
|
||||||
|
+ if(NULL == items.resize(items.getCapacity()*2, items.getCapacity())) {
|
||||||
|
+ *status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
#if defined(ULOC_DEBUG)
|
||||||
|
- fprintf(stderr,"malloced at size %d\n", jSize);
|
||||||
|
+ fprintf(stderr,"malloced at size %d\n", items.getCapacity());
|
||||||
|
#endif
|
||||||
|
- } else {
|
||||||
|
- j = static_cast<_acceptLangItem *>(uprv_realloc(j, sizeof(j[0])*jSize*2));
|
||||||
|
-#if defined(ULOC_DEBUG)
|
||||||
|
- fprintf(stderr,"re-alloced at size %d\n", jSize);
|
||||||
|
-#endif
|
||||||
|
- }
|
||||||
|
- jSize *= 2;
|
||||||
|
- if(j==NULL) {
|
||||||
|
- *status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- uprv_sortArray(j, n, sizeof(j[0]), uloc_acceptLanguageCompare, NULL, TRUE, status);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ uprv_sortArray(items.getAlias(), n, sizeof(items[0]), uloc_acceptLanguageCompare, NULL, TRUE, status);
|
||||||
|
+ LocalArray<const char*> strs(new const char*[n], *status);
|
||||||
|
if(U_FAILURE(*status)) {
|
||||||
|
- if(j != smallBuffer) {
|
||||||
|
-#if defined(ULOC_DEBUG)
|
||||||
|
- fprintf(stderr,"freeing j %p\n", j);
|
||||||
|
-#endif
|
||||||
|
- uprv_free(j);
|
||||||
|
- }
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- strs = static_cast<char **>(uprv_malloc((size_t)(sizeof(strs[0])*n)));
|
||||||
|
- /* Check for null pointer */
|
||||||
|
- if (strs == NULL) {
|
||||||
|
- uprv_free(j); /* Free to avoid memory leak */
|
||||||
|
- *status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
|
- return -1;
|
||||||
|
+ return -1;
|
||||||
|
}
|
||||||
|
for(i=0;i<n;i++) {
|
||||||
|
@@ -2406,18 +2378,8 @@
|
||||||
|
/*fprintf(stderr,"%d: s <%s> q <%g>\n", i, j[i].locale, j[i].q);*/
|
||||||
|
#endif
|
||||||
|
- strs[i]=j[i].locale;
|
||||||
|
+ strs[i]=items[i].locale;
|
||||||
|
}
|
||||||
|
res = uloc_acceptLanguage(result, resultAvailable, outResult,
|
||||||
|
- (const char**)strs, n, availableLocales, status);
|
||||||
|
- for(i=0;i<n;i++) {
|
||||||
|
- uprv_free(strs[i]);
|
||||||
|
- }
|
||||||
|
- uprv_free(strs);
|
||||||
|
- if(j != smallBuffer) {
|
||||||
|
-#if defined(ULOC_DEBUG)
|
||||||
|
- fprintf(stderr,"freeing j %p\n", j);
|
||||||
|
-#endif
|
||||||
|
- uprv_free(j);
|
||||||
|
- }
|
||||||
|
+ strs.getAlias(), n, availableLocales, status);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
Index: /source/test/cintltst/cloctst.c
|
||||||
|
===================================================================
|
||||||
|
--- /source/test/cintltst/cloctst.c (revision 39108)
|
||||||
|
+++ /source/test/cintltst/cloctst.c (revision 39109)
|
||||||
|
@@ -2776,14 +2776,18 @@
|
||||||
|
const char *expect; /**< The expected locale result */
|
||||||
|
UAcceptResult res; /**< The expected error code */
|
||||||
|
+ UErrorCode expectStatus; /**< expected status */
|
||||||
|
} tests[] = {
|
||||||
|
- /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID },
|
||||||
|
- /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID },
|
||||||
|
- /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK },
|
||||||
|
- /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED },
|
||||||
|
- /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID },
|
||||||
|
-
|
||||||
|
- /*5*/{ 5, NULL, "en", ULOC_ACCEPT_VALID }, /* XF */
|
||||||
|
- /*6*/{ 6, NULL, "ja", ULOC_ACCEPT_FALLBACK }, /* XF */
|
||||||
|
- /*7*/{ 7, NULL, "zh", ULOC_ACCEPT_FALLBACK }, /* XF */
|
||||||
|
+ /*0*/{ 0, NULL, "mt_MT", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
|
||||||
|
+ /*1*/{ 1, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
|
||||||
|
+ /*2*/{ 2, NULL, "en", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR},
|
||||||
|
+ /*3*/{ 3, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR},
|
||||||
|
+ /*4*/{ 4, NULL, "es", ULOC_ACCEPT_VALID, U_ZERO_ERROR},
|
||||||
|
+ /*5*/{ 5, NULL, "en", ULOC_ACCEPT_VALID, U_ZERO_ERROR}, /* XF */
|
||||||
|
+ /*6*/{ 6, NULL, "ja", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR}, /* XF */
|
||||||
|
+ /*7*/{ 7, NULL, "zh", ULOC_ACCEPT_FALLBACK, U_ZERO_ERROR}, /* XF */
|
||||||
|
+ /*8*/{ 8, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR }, /* */
|
||||||
|
+ /*9*/{ 9, NULL, "", ULOC_ACCEPT_FAILED, U_ZERO_ERROR }, /* */
|
||||||
|
+ /*10*/{10, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR }, /* */
|
||||||
|
+ /*11*/{11, NULL, "", ULOC_ACCEPT_FAILED, U_BUFFER_OVERFLOW_ERROR }, /* */
|
||||||
|
};
|
||||||
|
const int32_t numTests = UPRV_LENGTHOF(tests);
|
||||||
|
@@ -2801,8 +2805,23 @@
|
||||||
|
"xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xx-yy;q=.1, "
|
||||||
|
"es",
|
||||||
|
-
|
||||||
|
/*5*/ "zh-xx;q=0.9, en;q=0.6",
|
||||||
|
/*6*/ "ja-JA",
|
||||||
|
/*7*/ "zh-xx;q=0.9",
|
||||||
|
+ /*08*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 156
|
||||||
|
+ /*09*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB", // 157 (this hits U_STRING_NOT_TERMINATED_WARNING )
|
||||||
|
+ /*10*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABC", // 158
|
||||||
|
+ /*11*/ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", // 163 bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -2819,5 +2838,9 @@
|
||||||
|
uenum_close(available);
|
||||||
|
log_verbose(" got %s, %s [%s]\n", tmp[0]?tmp:"(EMPTY)", acceptResult(outResult), u_errorName(status));
|
||||||
|
- if(outResult != tests[i].res) {
|
||||||
|
+ if(status != tests[i].expectStatus) {
|
||||||
|
+ log_err_status(status, "FAIL: expected status %s but got %s\n", u_errorName(tests[i].expectStatus), u_errorName(status));
|
||||||
|
+ } else if(U_SUCCESS(tests[i].expectStatus)) {
|
||||||
|
+ /* don't check content if expected failure */
|
||||||
|
+ if(outResult != tests[i].res) {
|
||||||
|
log_err_status(status, "FAIL: #%d: expected outResult of %s but got %s\n", i,
|
||||||
|
acceptResult( tests[i].res),
|
||||||
|
@@ -2825,9 +2848,10 @@
|
||||||
|
log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
|
||||||
|
i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect,acceptResult(tests[i].res));
|
||||||
|
- }
|
||||||
|
- if((outResult>0)&&uprv_strcmp(tmp, tests[i].expect)) {
|
||||||
|
- log_err_status(status, "FAIL: #%d: expected %s but got %s\n", i, tests[i].expect, tmp);
|
||||||
|
- log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
|
||||||
|
- i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, acceptResult(tests[i].res));
|
||||||
|
+ }
|
||||||
|
+ if((outResult>0)&&uprv_strcmp(tmp, tests[i].expect)) {
|
||||||
|
+ log_err_status(status, "FAIL: #%d: expected %s but got %s\n", i, tests[i].expect, tmp);
|
||||||
|
+ log_info("test #%d: http[%s], ICU[%s], expect %s, %s\n",
|
||||||
|
+ i, http[tests[i].httpSet], tests[i].icuSet, tests[i].expect, acceptResult(tests[i].res));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
176
CVE-2016-7415.patch
Normal file
176
CVE-2016-7415.patch
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
Index: source/common/locid.cpp
|
||||||
|
===================================================================
|
||||||
|
--- a/source/common/locid.cpp (revision 39353)
|
||||||
|
+++ b/source/common/locid.cpp (revision 39356)
|
||||||
|
@@ -43,4 +43,5 @@
|
||||||
|
#include "ucln_cmn.h"
|
||||||
|
#include "ustr_imp.h"
|
||||||
|
+#include "charstr.h"
|
||||||
|
|
||||||
|
U_CDECL_BEGIN
|
||||||
|
@@ -57,4 +58,10 @@
|
||||||
|
static UHashtable *gDefaultLocalesHashT = NULL;
|
||||||
|
static Locale *gDefaultLocale = NULL;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * \def ULOC_STRING_LIMIT
|
||||||
|
+ * strings beyond this value crash in CharString
|
||||||
|
+ */
|
||||||
|
+#define ULOC_STRING_LIMIT 357913941
|
||||||
|
|
||||||
|
U_NAMESPACE_END
|
||||||
|
@@ -284,5 +291,5 @@
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- MaybeStackArray<char, ULOC_FULLNAME_CAPACITY> togo;
|
||||||
|
+ UErrorCode status = U_ZERO_ERROR;
|
||||||
|
int32_t size = 0;
|
||||||
|
int32_t lsize = 0;
|
||||||
|
@@ -290,5 +297,4 @@
|
||||||
|
int32_t vsize = 0;
|
||||||
|
int32_t ksize = 0;
|
||||||
|
- char *p;
|
||||||
|
|
||||||
|
// Calculate the size of the resulting string.
|
||||||
|
@@ -298,6 +304,12 @@
|
||||||
|
{
|
||||||
|
lsize = (int32_t)uprv_strlen(newLanguage);
|
||||||
|
+ if ( lsize < 0 || lsize > ULOC_STRING_LIMIT ) { // int32 wrap
|
||||||
|
+ setToBogus();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
size = lsize;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ CharString togo(newLanguage, lsize, status); // start with newLanguage
|
||||||
|
|
||||||
|
// _Country
|
||||||
|
@@ -305,4 +317,8 @@
|
||||||
|
{
|
||||||
|
csize = (int32_t)uprv_strlen(newCountry);
|
||||||
|
+ if ( csize < 0 || csize > ULOC_STRING_LIMIT ) { // int32 wrap
|
||||||
|
+ setToBogus();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
size += csize;
|
||||||
|
}
|
||||||
|
@@ -319,4 +335,8 @@
|
||||||
|
// remove trailing _'s
|
||||||
|
vsize = (int32_t)uprv_strlen(newVariant);
|
||||||
|
+ if ( vsize < 0 || vsize > ULOC_STRING_LIMIT ) { // int32 wrap
|
||||||
|
+ setToBogus();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
while( (vsize>1) && (newVariant[vsize-1] == SEP_CHAR) )
|
||||||
|
{
|
||||||
|
@@ -343,48 +363,34 @@
|
||||||
|
{
|
||||||
|
ksize = (int32_t)uprv_strlen(newKeywords);
|
||||||
|
+ if ( ksize < 0 || ksize > ULOC_STRING_LIMIT ) {
|
||||||
|
+ setToBogus();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
size += ksize + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
+ if (size < 0) {
|
||||||
|
+ setToBogus();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
// NOW we have the full locale string..
|
||||||
|
-
|
||||||
|
- /*if the whole string is longer than our internal limit, we need
|
||||||
|
- to go to the heap for temporary buffers*/
|
||||||
|
- if (size >= togo.getCapacity())
|
||||||
|
- {
|
||||||
|
- // If togo_heap could not be created, initialize with default settings.
|
||||||
|
- if (togo.resize(size+1) == NULL) {
|
||||||
|
- init(NULL, FALSE);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- togo[0] = 0;
|
||||||
|
-
|
||||||
|
// Now, copy it back.
|
||||||
|
- p = togo.getAlias();
|
||||||
|
- if ( lsize != 0 )
|
||||||
|
- {
|
||||||
|
- uprv_strcpy(p, newLanguage);
|
||||||
|
- p += lsize;
|
||||||
|
- }
|
||||||
|
+
|
||||||
|
+ // newLanguage is already copied
|
||||||
|
|
||||||
|
if ( ( vsize != 0 ) || (csize != 0) ) // at least: __v
|
||||||
|
{ // ^
|
||||||
|
- *p++ = SEP_CHAR;
|
||||||
|
+ togo.append(SEP_CHAR, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( csize != 0 )
|
||||||
|
{
|
||||||
|
- uprv_strcpy(p, newCountry);
|
||||||
|
- p += csize;
|
||||||
|
+ togo.append(newCountry, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( vsize != 0)
|
||||||
|
{
|
||||||
|
- *p++ = SEP_CHAR; // at least: __v
|
||||||
|
-
|
||||||
|
- uprv_strncpy(p, newVariant, vsize); // Must use strncpy because
|
||||||
|
- p += vsize; // of trimming (above).
|
||||||
|
- *p = 0; // terminate
|
||||||
|
+ togo.append(SEP_CHAR, status)
|
||||||
|
+ .append(newVariant, vsize, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -392,19 +398,23 @@
|
||||||
|
{
|
||||||
|
if (uprv_strchr(newKeywords, '=')) {
|
||||||
|
- *p++ = '@'; /* keyword parsing */
|
||||||
|
+ togo.append('@', status); /* keyword parsing */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- *p++ = '_'; /* Variant parsing with a script */
|
||||||
|
+ togo.append('_', status); /* Variant parsing with a script */
|
||||||
|
if ( vsize == 0) {
|
||||||
|
- *p++ = '_'; /* No country found */
|
||||||
|
+ togo.append('_', status); /* No country found */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- uprv_strcpy(p, newKeywords);
|
||||||
|
- p += ksize;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ togo.append(newKeywords, status);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (U_FAILURE(status)) {
|
||||||
|
+ // Something went wrong with appending, etc.
|
||||||
|
+ setToBogus();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
// Parse it, because for example 'language' might really be a complete
|
||||||
|
// string.
|
||||||
|
- init(togo.getAlias(), FALSE);
|
||||||
|
+ init(togo.data(), FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Index: source/test/intltest/numfmtst.cpp
|
||||||
|
===================================================================
|
||||||
|
--- a/source/test/intltest/numfmtst.cpp (revision 39353)
|
||||||
|
+++ b/source/test/intltest/numfmtst.cpp (revision 39356)
|
||||||
|
@@ -2421,9 +2421,10 @@
|
||||||
|
const char *localeName = badLocales[i];
|
||||||
|
Locale locBad(localeName);
|
||||||
|
+ TEST_ASSERT_TRUE(!locBad.isBogus());
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString intlCurrencySymbol((UChar)0xa4);
|
||||||
|
|
||||||
|
intlCurrencySymbol.append((UChar)0xa4);
|
||||||
|
-
|
||||||
|
+
|
||||||
|
logln("Current locale is %s", Locale::getDefault().getName());
|
||||||
|
Locale::setDefault(locBad, status);
|
10
CVE-2017-14952.patch
Normal file
10
CVE-2017-14952.patch
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Index: source/i18n/zonemeta.cpp
|
||||||
|
===================================================================
|
||||||
|
--- a/source/i18n/zonemeta.cpp (revision 40283)
|
||||||
|
+++ b/source/i18n/zonemeta.cpp (revision 40324)
|
||||||
|
@@ -682,5 +682,4 @@
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
delete mzMappings;
|
||||||
|
- deleteOlsonToMetaMappingEntry(entry);
|
||||||
|
uprv_free(entry);
|
||||||
|
break;
|
118
CVE-2017-15422.patch
Normal file
118
CVE-2017-15422.patch
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
Index: icu4c/source/i18n/gregoimp.cpp
|
||||||
|
===================================================================
|
||||||
|
--- icu4c/source/i18n/gregoimp.cpp (revision 40653)
|
||||||
|
+++ icu4c/source/i18n/gregoimp.cpp (revision 40654)
|
||||||
|
@@ -29,6 +29,11 @@ int32_t ClockMath::floorDivide(int32_t n
|
||||||
|
numerator / denominator : ((numerator + 1) / denominator) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int64_t ClockMath::floorDivide(int64_t numerator, int64_t denominator) {
|
||||||
|
+ return (numerator >= 0) ?
|
||||||
|
+ numerator / denominator : ((numerator + 1) / denominator) - 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int32_t ClockMath::floorDivide(double numerator, int32_t denominator,
|
||||||
|
int32_t& remainder) {
|
||||||
|
double quotient;
|
||||||
|
Index: icu4c/source/i18n/gregoimp.h
|
||||||
|
===================================================================
|
||||||
|
--- icu4c/source/i18n/gregoimp.h (revision 40653)
|
||||||
|
+++ icu4c/source/i18n/gregoimp.h (revision 40654)
|
||||||
|
@@ -39,6 +39,17 @@ class ClockMath {
|
||||||
|
static int32_t floorDivide(int32_t numerator, int32_t denominator);
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * Divide two integers, returning the floor of the quotient.
|
||||||
|
+ * Unlike the built-in division, this is mathematically
|
||||||
|
+ * well-behaved. E.g., <code>-1/4</code> => 0 but
|
||||||
|
+ * <code>floorDivide(-1,4)</code> => -1.
|
||||||
|
+ * @param numerator the numerator
|
||||||
|
+ * @param denominator a divisor which must be != 0
|
||||||
|
+ * @return the floor of the quotient
|
||||||
|
+ */
|
||||||
|
+ static int64_t floorDivide(int64_t numerator, int64_t denominator);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
* Divide two numbers, returning the floor of the quotient.
|
||||||
|
* Unlike the built-in division, this is mathematically
|
||||||
|
* well-behaved. E.g., <code>-1/4</code> => 0 but
|
||||||
|
Index: icu4c/source/i18n/persncal.cpp
|
||||||
|
===================================================================
|
||||||
|
--- icu4c/source/i18n/persncal.cpp (revision 40653)
|
||||||
|
+++ icu4c/source/i18n/persncal.cpp (revision 40654)
|
||||||
|
@@ -211,7 +211,7 @@ void PersianCalendar::handleComputeField
|
||||||
|
int32_t year, month, dayOfMonth, dayOfYear;
|
||||||
|
|
||||||
|
int32_t daysSinceEpoch = julianDay - PERSIAN_EPOCH;
|
||||||
|
- year = 1 + ClockMath::floorDivide(33 * daysSinceEpoch + 3, 12053);
|
||||||
|
+ year = 1 + (int32_t)ClockMath::floorDivide(33 * (int64_t)daysSinceEpoch + 3, (int64_t)12053);
|
||||||
|
|
||||||
|
int32_t farvardin1 = 365 * (year - 1) + ClockMath::floorDivide(8 * year + 21, 33);
|
||||||
|
dayOfYear = (daysSinceEpoch - farvardin1); // 0-based
|
||||||
|
Index: icu4c/source/test/intltest/calregts.cpp
|
||||||
|
===================================================================
|
||||||
|
--- icu4c/source/test/intltest/calregts.cpp (revision 40653)
|
||||||
|
+++ icu4c/source/test/intltest/calregts.cpp (revision 40654)
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
|
||||||
|
#include "calregts.h"
|
||||||
|
|
||||||
|
+#include "unicode/calendar.h"
|
||||||
|
#include "unicode/gregocal.h"
|
||||||
|
#include "unicode/simpletz.h"
|
||||||
|
#include "unicode/smpdtfmt.h"
|
||||||
|
@@ -88,6 +89,7 @@ CalendarRegressionTest::runIndexedTest(
|
||||||
|
CASE(48,TestT8596);
|
||||||
|
CASE(49,Test9019);
|
||||||
|
CASE(50,TestT9452);
|
||||||
|
+ CASE(51,TestPersianCalOverflow);
|
||||||
|
default: name = ""; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2944,4 +2946,34 @@ void CalendarRegressionTest::TestT9452(v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * @bug ticket 13454
|
||||||
|
+ */
|
||||||
|
+void CalendarRegressionTest::TestPersianCalOverflow(void) {
|
||||||
|
+ const char* localeID = "bs_Cyrl@calendar=persian";
|
||||||
|
+ UErrorCode status = U_ZERO_ERROR;
|
||||||
|
+ Calendar* cal = Calendar::createInstance(Locale(localeID), status);
|
||||||
|
+ if(U_FAILURE(status)) {
|
||||||
|
+ dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID, u_errorName(status));
|
||||||
|
+ } else {
|
||||||
|
+ int32_t maxMonth = cal->getMaximum(UCAL_MONTH);
|
||||||
|
+ int32_t maxDayOfMonth = cal->getMaximum(UCAL_DATE);
|
||||||
|
+ int32_t jd, month, dayOfMonth;
|
||||||
|
+ for (jd = 67023580; jd <= 67023584; jd++) { // year 178171, int32_t overflow if jd >= 67023582
|
||||||
|
+ status = U_ZERO_ERROR;
|
||||||
|
+ cal->clear();
|
||||||
|
+ cal->set(UCAL_JULIAN_DAY, jd);
|
||||||
|
+ month = cal->get(UCAL_MONTH, status);
|
||||||
|
+ dayOfMonth = cal->get(UCAL_DATE, status);
|
||||||
|
+ if ( U_FAILURE(status) ) {
|
||||||
|
+ errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s\n", localeID, jd, u_errorName(status));
|
||||||
|
+ } else if (month > maxMonth || dayOfMonth > maxDayOfMonth) {
|
||||||
|
+ errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d\n",
|
||||||
|
+ localeID, jd, maxMonth, month, maxDayOfMonth, dayOfMonth);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ delete cal;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||||
|
Index: icu4c/source/test/intltest/calregts.h
|
||||||
|
===================================================================
|
||||||
|
--- icu4c/source/test/intltest/calregts.h (revision 40653)
|
||||||
|
+++ icu4c/source/test/intltest/calregts.h (revision 40654)
|
||||||
|
@@ -75,6 +75,7 @@ public:
|
||||||
|
void TestT8596(void);
|
||||||
|
void Test9019(void);
|
||||||
|
void TestT9452(void);
|
||||||
|
+ void TestPersianCalOverflow(void);
|
||||||
|
|
||||||
|
void printdate(GregorianCalendar *cal, const char *string);
|
||||||
|
void dowTest(UBool lenient) ;
|
176
CVE-2017-7867_CVE-2017-7868.patch
Normal file
176
CVE-2017-7867_CVE-2017-7868.patch
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
Index: icu/source/test/intltest/utxttest.h
|
||||||
|
===================================================================
|
||||||
|
--- icu/source/test/intltest/utxttest.h (revision 39670)
|
||||||
|
+++ icu/source/test/intltest/utxttest.h (revision 39671)
|
||||||
|
@@ -36,6 +36,7 @@
|
||||||
|
void Ticket10562();
|
||||||
|
void Ticket10983();
|
||||||
|
void Ticket12130();
|
||||||
|
+ void Ticket12888();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct m { // Map between native indices & code points.
|
||||||
|
Index: icu/source/test/intltest/utxttest.cpp
|
||||||
|
===================================================================
|
||||||
|
--- icu/source/test/intltest/utxttest.cpp (revision 39670)
|
||||||
|
+++ icu/source/test/intltest/utxttest.cpp (revision 39671)
|
||||||
|
@@ -65,6 +65,8 @@
|
||||||
|
if (exec) Ticket10983(); break;
|
||||||
|
case 7: name = "Ticket12130";
|
||||||
|
if (exec) Ticket12130(); break;
|
||||||
|
+ case 8: name = "Ticket12888";
|
||||||
|
+ if (exec) Ticket12888(); break;
|
||||||
|
default: name = ""; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1581,3 +1583,63 @@
|
||||||
|
}
|
||||||
|
utext_close(&ut);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+// Ticket 12888: bad handling of illegal utf-8 containing many instances of the archaic, now illegal,
|
||||||
|
+// six byte utf-8 forms. Original implementation had an assumption that
|
||||||
|
+// there would be at most three utf-8 bytes per UTF-16 code unit.
|
||||||
|
+// The five and six byte sequences map to a single replacement character.
|
||||||
|
+
|
||||||
|
+void UTextTest::Ticket12888() {
|
||||||
|
+ const char *badString =
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
|
||||||
|
+ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80";
|
||||||
|
+
|
||||||
|
+ UErrorCode status = U_ZERO_ERROR;
|
||||||
|
+ LocalUTextPointer ut(utext_openUTF8(NULL, badString, -1, &status));
|
||||||
|
+ TEST_SUCCESS(status);
|
||||||
|
+ for (;;) {
|
||||||
|
+ UChar32 c = utext_next32(ut.getAlias());
|
||||||
|
+ if (c == U_SENTINEL) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ int32_t endIdx = utext_getNativeIndex(ut.getAlias());
|
||||||
|
+ if (endIdx != (int32_t)strlen(badString)) {
|
||||||
|
+ errln("%s:%d expected=%d, actual=%d", __FILE__, __LINE__, strlen(badString), endIdx);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (int32_t prevIndex = endIdx; prevIndex>0;) {
|
||||||
|
+ UChar32 c = utext_previous32(ut.getAlias());
|
||||||
|
+ int32_t currentIndex = utext_getNativeIndex(ut.getAlias());
|
||||||
|
+ if (c != 0xfffd) {
|
||||||
|
+ errln("%s:%d (expected, actual, index) = (%d, %d, %d)\n",
|
||||||
|
+ __FILE__, __LINE__, 0xfffd, c, currentIndex);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (currentIndex != prevIndex - 6) {
|
||||||
|
+ errln("%s:%d: wrong index. Expected, actual = %d, %d",
|
||||||
|
+ __FILE__, __LINE__, prevIndex - 6, currentIndex);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ prevIndex = currentIndex;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
Index: icu/source/common/utext.cpp
|
||||||
|
===================================================================
|
||||||
|
--- icu/source/common/utext.cpp (revision 39670)
|
||||||
|
+++ icu/source/common/utext.cpp (revision 39671)
|
||||||
|
@@ -845,9 +845,15 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Chunk size.
|
||||||
|
-// Must be less than 85, because of byte mapping from UChar indexes to native indexes.
|
||||||
|
-// Worst case is three native bytes to one UChar. (Supplemenaries are 4 native bytes
|
||||||
|
-// to two UChars.)
|
||||||
|
+// Must be less than 42 (256/6), because of byte mapping from UChar indexes to native indexes.
|
||||||
|
+// Worst case there are six UTF-8 bytes per UChar.
|
||||||
|
+// obsolete 6 byte form fd + 5 trails maps to fffd
|
||||||
|
+// obsolete 5 byte form fc + 4 trails maps to fffd
|
||||||
|
+// non-shortest 4 byte forms maps to fffd
|
||||||
|
+// normal supplementaries map to a pair of utf-16, two utf8 bytes per utf-16 unit
|
||||||
|
+// mapToUChars array size must allow for the worst case, 6.
|
||||||
|
+// This could be brought down to 4, by treating fd and fc as pure illegal,
|
||||||
|
+// rather than obsolete lead bytes. But that is not compatible with the utf-8 access macros.
|
||||||
|
//
|
||||||
|
enum { UTF8_TEXT_CHUNK_SIZE=32 };
|
||||||
|
|
||||||
|
@@ -887,7 +893,7 @@
|
||||||
|
// Requires two extra slots,
|
||||||
|
// one for a supplementary starting in the last normal position,
|
||||||
|
// and one for an entry for the buffer limit position.
|
||||||
|
- uint8_t mapToUChars[UTF8_TEXT_CHUNK_SIZE*3+6]; // Map native offset from bufNativeStart to
|
||||||
|
+ uint8_t mapToUChars[UTF8_TEXT_CHUNK_SIZE*6+6]; // Map native offset from bufNativeStart to
|
||||||
|
// correspoding offset in filled part of buf.
|
||||||
|
int32_t align;
|
||||||
|
};
|
||||||
|
@@ -1030,6 +1036,7 @@
|
||||||
|
// Requested index is in this buffer.
|
||||||
|
u8b = (UTF8Buf *)ut->p; // the current buffer
|
||||||
|
mapIndex = ix - u8b->toUCharsMapStart;
|
||||||
|
+ U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
|
||||||
|
ut->chunkOffset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
@@ -1296,6 +1303,10 @@
|
||||||
|
// Can only do this if the incoming index is somewhere in the interior of the string.
|
||||||
|
// If index is at the end, there is no character there to look at.
|
||||||
|
if (ix != ut->b) {
|
||||||
|
+ // Note: this function will only move the index back if it is on a trail byte
|
||||||
|
+ // and there is a preceding lead byte and the sequence from the lead
|
||||||
|
+ // through this trail could be part of a valid UTF-8 sequence
|
||||||
|
+ // Otherwise the index remains unchanged.
|
||||||
|
U8_SET_CP_START(s8, 0, ix);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1309,7 +1320,10 @@
|
||||||
|
UChar *buf = u8b->buf;
|
||||||
|
uint8_t *mapToNative = u8b->mapToNative;
|
||||||
|
uint8_t *mapToUChars = u8b->mapToUChars;
|
||||||
|
- int32_t toUCharsMapStart = ix - (UTF8_TEXT_CHUNK_SIZE*3 + 1);
|
||||||
|
+ int32_t toUCharsMapStart = ix - sizeof(UTF8Buf::mapToUChars) + 1;
|
||||||
|
+ // Note that toUCharsMapStart can be negative. Happens when the remaining
|
||||||
|
+ // text from current position to the beginning is less than the buffer size.
|
||||||
|
+ // + 1 because mapToUChars must have a slot at the end for the bufNativeLimit entry.
|
||||||
|
int32_t destIx = UTF8_TEXT_CHUNK_SIZE+2; // Start in the overflow region
|
||||||
|
// at end of buffer to leave room
|
||||||
|
// for a surrogate pair at the
|
||||||
|
@@ -1336,6 +1350,7 @@
|
||||||
|
if (c<0x80) {
|
||||||
|
// Special case ASCII range for speed.
|
||||||
|
buf[destIx] = (UChar)c;
|
||||||
|
+ U_ASSERT(toUCharsMapStart <= srcIx);
|
||||||
|
mapToUChars[srcIx - toUCharsMapStart] = (uint8_t)destIx;
|
||||||
|
mapToNative[destIx] = (uint8_t)(srcIx - toUCharsMapStart);
|
||||||
|
} else {
|
||||||
|
@@ -1365,6 +1380,7 @@
|
||||||
|
do {
|
||||||
|
mapToUChars[sIx-- - toUCharsMapStart] = (uint8_t)destIx;
|
||||||
|
} while (sIx >= srcIx);
|
||||||
|
+ U_ASSERT(toUCharsMapStart <= (srcIx+1));
|
||||||
|
|
||||||
|
// Set native indexing limit to be the current position.
|
||||||
|
// We are processing a non-ascii, non-native-indexing char now;
|
||||||
|
@@ -1539,6 +1555,7 @@
|
||||||
|
U_ASSERT(index>=ut->chunkNativeStart+ut->nativeIndexingLimit);
|
||||||
|
U_ASSERT(index<=ut->chunkNativeLimit);
|
||||||
|
int32_t mapIndex = index - u8b->toUCharsMapStart;
|
||||||
|
+ U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
|
||||||
|
int32_t offset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
|
||||||
|
U_ASSERT(offset>=0 && offset<=ut->chunkLength);
|
||||||
|
return offset;
|
44
CVE-2020-10531.patch
Normal file
44
CVE-2020-10531.patch
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
From b7d08bc04a4296982fcef8b6b8a354a9e4e7afca Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Tang <ftang@chromium.org>
|
||||||
|
Date: Sat, 1 Feb 2020 02:39:04 +0000
|
||||||
|
Subject: [PATCH] ICU-20958 Prevent SEGV_MAPERR in append
|
||||||
|
|
||||||
|
See #971
|
||||||
|
---
|
||||||
|
source/common/unistr.cpp | 6 ++-
|
||||||
|
|
||||||
|
diff --git a/source/common/unistr.cpp b/source/common/unistr.cpp
|
||||||
|
index 901bb3358ba..077b4d6ef20 100644
|
||||||
|
--- a/source/common/unistr.cpp
|
||||||
|
+++ b/source/common/unistr.cpp
|
||||||
|
@@ -73,6 +73,17 @@ print(const UChar *s,
|
||||||
|
// END DEBUGGING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+// Adding this function as support of CVE-2020-10531
|
||||||
|
+// since this version has not uprv_add32_overflow
|
||||||
|
+// implement it here.
|
||||||
|
+UBool uprv_add32_overflow(int32_t a, int32_t b, int32_t* res) {
|
||||||
|
+ int64_t a64 = static_cast<int64_t>(a);
|
||||||
|
+ int64_t b64 = static_cast<int64_t>(b);
|
||||||
|
+ int64_t res64 = a64 + b64;
|
||||||
|
+ *res = static_cast<int32_t>(res64);
|
||||||
|
+ return res64 != *res;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Local function definitions for now
|
||||||
|
|
||||||
|
// need to copy areas that may overlap
|
||||||
|
@@ -1510,7 +1510,11 @@ UnicodeString::doAppend(const UChar *src
|
||||||
|
}
|
||||||
|
|
||||||
|
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, newLength + (newLength >> 2) + kGrowSize)) {
|
16
icu.spec
16
icu.spec
|
@ -17,7 +17,7 @@ Summary: International Components for Unicode
|
||||||
Name: icu
|
Name: icu
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
Version: 57.1
|
Version: 57.1
|
||||||
Release: 8
|
Release: 9
|
||||||
License: MIT
|
License: MIT
|
||||||
Group: System/Libraries
|
Group: System/Libraries
|
||||||
Url: http://www.icu-project.org/index.html
|
Url: http://www.icu-project.org/index.html
|
||||||
|
@ -29,6 +29,14 @@ Patch1: icu-57.1-ICU-12936.patch
|
||||||
Patch10: icu.7601.Indic-ccmp.patch
|
Patch10: icu.7601.Indic-ccmp.patch
|
||||||
Patch11: icu.8198.revert.icu5431.patch
|
Patch11: icu.8198.revert.icu5431.patch
|
||||||
Patch12: icu.8800.freeserif.crash.patch
|
Patch12: icu.8800.freeserif.crash.patch
|
||||||
|
# From Debian
|
||||||
|
Patch20: CVE-2016-6293.patch
|
||||||
|
Patch21: CVE-2016-7415.patch
|
||||||
|
Patch22: CVE-2017-7867_CVE-2017-7868.patch
|
||||||
|
Patch23: CVE-2017-14952.patch
|
||||||
|
Patch24: CVE-2017-15422.patch
|
||||||
|
Patch25: CVE-2020-10531.patch
|
||||||
|
|
||||||
BuildRequires: doxygen
|
BuildRequires: doxygen
|
||||||
|
|
||||||
%description
|
%description
|
||||||
|
@ -213,6 +221,12 @@ Development files and headers for the International Components for Unicode.
|
||||||
%patch10 -p1
|
%patch10 -p1
|
||||||
%patch11 -p2 -R
|
%patch11 -p2 -R
|
||||||
%patch12 -p1
|
%patch12 -p1
|
||||||
|
%patch20 -p1
|
||||||
|
%patch21 -p1
|
||||||
|
%patch22 -p1
|
||||||
|
%patch23 -p1
|
||||||
|
%patch24 -p1
|
||||||
|
%patch25 -p1
|
||||||
|
|
||||||
mkdir -p docs
|
mkdir -p docs
|
||||||
cd docs
|
cd docs
|
||||||
|
|
Loading…
Add table
Reference in a new issue