You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.5 KiB
156 lines
4.5 KiB
Index: icu/trunk/source/common/locid.cpp |
|
=================================================================== |
|
--- icu/source/common/locid.cpp (revision 39282) |
|
+++ icu/source/common/locid.cpp (revision 39384) |
|
@@ -45,4 +45,5 @@ |
|
#include "ucln_cmn.h" |
|
#include "ustr_imp.h" |
|
+#include "charstr.h" |
|
|
|
U_CDECL_BEGIN |
|
@@ -59,4 +60,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 |
|
@@ -286,5 +293,5 @@ |
|
else |
|
{ |
|
- MaybeStackArray<char, ULOC_FULLNAME_CAPACITY> togo; |
|
+ UErrorCode status = U_ZERO_ERROR; |
|
int32_t size = 0; |
|
int32_t lsize = 0; |
|
@@ -292,5 +299,4 @@ |
|
int32_t vsize = 0; |
|
int32_t ksize = 0; |
|
- char *p; |
|
|
|
// Calculate the size of the resulting string. |
|
@@ -300,6 +306,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 |
|
@@ -307,4 +319,8 @@ |
|
{ |
|
csize = (int32_t)uprv_strlen(newCountry); |
|
+ if ( csize < 0 || csize > ULOC_STRING_LIMIT ) { // int32 wrap |
|
+ setToBogus(); |
|
+ return; |
|
+ } |
|
size += csize; |
|
} |
|
@@ -321,4 +337,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) ) |
|
{ |
|
@@ -345,48 +365,30 @@ |
|
{ |
|
ksize = (int32_t)uprv_strlen(newKeywords); |
|
+ if ( ksize < 0 || ksize > ULOC_STRING_LIMIT ) { |
|
+ setToBogus(); |
|
+ return; |
|
+ } |
|
size += ksize + 1; |
|
} |
|
|
|
- |
|
// 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); |
|
} |
|
|
|
@@ -394,19 +396,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); |
|
} |
|
}
|
|
|