Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1287)

Unified Diff: source/common/locid.cpp

Issue 2440913002: Update ICU to 58.1
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/common/locdspnm.cpp ('k') | source/common/loclikely.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/common/locid.cpp
diff --git a/source/common/locid.cpp b/source/common/locid.cpp
index 27e403065f2e933c99c215e6d2de93f856c5981f..d2781db95bdd8cf8b4e0c31f9659406add9e299e 100644
--- a/source/common/locid.cpp
+++ b/source/common/locid.cpp
@@ -1,6 +1,8 @@
+// Copyright (C) 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/*
**********************************************************************
- * Copyright (C) 1997-2015, International Business Machines
+ * Copyright (C) 1997-2016, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*
@@ -42,6 +44,7 @@
#include "uhash.h"
#include "ucln_cmn.h"
#include "ustr_imp.h"
+#include "charstr.h"
U_CDECL_BEGIN
static UBool U_CALLCONV locale_cleanup(void);
@@ -57,6 +60,12 @@ static UMutex gDefaultLocaleMutex = U_MUTEX_INITIALIZER;
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
typedef enum ELocalePos {
@@ -283,13 +292,12 @@ Locale::Locale( const char * newLanguage,
}
else
{
- MaybeStackArray<char, ULOC_FULLNAME_CAPACITY> togo;
+ UErrorCode status = U_ZERO_ERROR;
int32_t size = 0;
int32_t lsize = 0;
int32_t csize = 0;
int32_t vsize = 0;
int32_t ksize = 0;
- char *p;
// Calculate the size of the resulting string.
@@ -297,13 +305,23 @@ Locale::Locale( const char * newLanguage,
if ( newLanguage != NULL )
{
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
if ( newCountry != NULL )
{
csize = (int32_t)uprv_strlen(newCountry);
+ if ( csize < 0 || csize > ULOC_STRING_LIMIT ) { // int32 wrap
+ setToBogus();
+ return;
+ }
size += csize;
}
@@ -318,6 +336,10 @@ Locale::Locale( const char * newLanguage,
// 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) )
{
vsize--;
@@ -342,70 +364,56 @@ Locale::Locale( const char * newLanguage,
if ( newKeywords != NULL)
{
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);
}
if ( ksize != 0)
{
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);
}
}
@@ -536,7 +544,7 @@ Locale& Locale::init(const char* localeID, UBool canonicalize)
/* after uloc_getName/canonicalize() we know that only '_' are separators */
separator = field[0] = fullName;
fieldIdx = 1;
- while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) && fieldIdx < (int32_t)(sizeof(field)/sizeof(field[0]))-1) {
+ while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) && fieldIdx < UPRV_LENGTHOF(field)-1) {
field[fieldIdx] = separator + 1;
fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
fieldIdx++;
@@ -662,6 +670,7 @@ Locale::setToBogus() {
*script = 0;
*country = 0;
fIsBogus = TRUE;
+ variantBegin = 0;
}
const Locale& U_EXPORT2
« no previous file with comments | « source/common/locdspnm.cpp ('k') | source/common/loclikely.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698