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

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);
}
}