ICU-6204 Ensure valid country code in locale id is either size 2 or 3.

X-SVN-Rev: 26809
This commit is contained in:
Michael Ow 2009-10-26 19:34:32 +00:00
parent e5dc053c11
commit fe62ee5a61
2 changed files with 74 additions and 23 deletions

View File

@ -1276,34 +1276,47 @@ _getCountry(const char *localeID,
char *country, int32_t countryCapacity,
const char **pEnd)
{
int32_t i=0;
int32_t idLen=0;
char cnty[ULOC_COUNTRY_CAPACITY]={ 0, 0, 0, 0 };
int32_t offset;
/* copy the country as far as possible and count its length */
while(!_isTerminator(*localeID) && !_isIDSeparator(*localeID)) {
if(i<countryCapacity) {
country[i]=(char)uprv_toupper(*localeID);
while(!_isTerminator(localeID[idLen]) && !_isIDSeparator(localeID[idLen])) {
if(idLen<(ULOC_COUNTRY_CAPACITY-1)) { /*CWB*/
cnty[idLen]=(char)uprv_toupper(localeID[idLen]);
}
if(i<(ULOC_COUNTRY_CAPACITY-1)) { /*CWB*/
cnty[i]=(char)uprv_toupper(*localeID);
}
i++;
localeID++;
idLen++;
}
/* convert 3 character code to 2 character code if possible *CWB*/
if(i==3) {
offset=_findIndex(COUNTRIES_3, cnty);
if(offset>=0) {
i=_copyCount(country, countryCapacity, COUNTRIES[offset]);
/* the country should be either length 2 or 3 */
if (idLen == 2 || idLen == 3) {
UBool gotCountry = FALSE;
/* convert 3 character code to 2 character code if possible *CWB*/
if(idLen==3) {
offset=_findIndex(COUNTRIES_3, cnty);
if(offset>=0) {
idLen=_copyCount(country, countryCapacity, COUNTRIES[offset]);
gotCountry = TRUE;
}
}
if (!gotCountry) {
int32_t i = 0;
for (i = 0; i < idLen; i++) {
if (i < countryCapacity) {
country[i]=(char)uprv_toupper(localeID[i]);
}
}
}
localeID+=idLen;
} else {
idLen = 0;
}
if(pEnd!=NULL) {
*pEnd=localeID;
}
return i;
return idLen;
}
/**
@ -1600,7 +1613,7 @@ _canonicalize(const char* localeID,
/* if we are doing a full canonicalization, then put results in
localeBuffer, if necessary; otherwise send them to result. */
if (OPTION_SET(options, _ULOC_CANONICALIZE) &&
if (/*OPTION_SET(options, _ULOC_CANONICALIZE) &&*/
(result == NULL || resultCapacity < sizeof(localeBuffer))) {
name = localeBuffer;
nameCapacity = sizeof(localeBuffer);
@ -1645,13 +1658,23 @@ _canonicalize(const char* localeID,
}
if (_isIDSeparator(*localeID)) {
len+=_getCountry(localeID+1, name+len, nameCapacity-len, &localeID);
const char *cntryID;
int32_t cntrySize = _getCountry(localeID+1, name+len, nameCapacity-len, &cntryID);
if (cntrySize > 0) {
/* Found optional country */
localeID = cntryID;
len+=cntrySize;
}
if(_isIDSeparator(*localeID)) {
++fieldCount;
if(len<nameCapacity) {
name[len]='_';
/* If there is something else, then we add the _ if we found country before.*/
if (cntrySize > 0) {
++fieldCount;
if(len<nameCapacity) {
name[len]='_';
}
++len;
}
++len;
variantSize = _getVariant(localeID+1, *localeID, name+len, nameCapacity-len);
if (variantSize > 0) {
variant = name+len;
@ -1933,7 +1956,12 @@ uloc_getVariant(const char* localeID,
}
/* Skip the Country */
if (_isIDSeparator(*localeID)) {
_getCountry(localeID+1, NULL, 0, &localeID);
const char *cntryID;
_getCountry(localeID+1, NULL, 0, &cntryID);
if (cntryID != localeID) {
/* Found optional country */
localeID = cntryID;
}
if(_isIDSeparator(*localeID)) {
i=_getVariant(localeID+1, *localeID, variant, variantCapacity);
}
@ -4020,6 +4048,25 @@ error:
return -1;
}
#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) \
{ int32_t count = 0; \
int32_t i; \
for (i = 0; i < trailingLength; i++) { \
if (trailing[i] == '-' || trailing[i] == '_') { \
count = 0; \
if (count > 8) { \
goto error; \
} \
} else if (trailing[i] == '@') { \
break; \
} else if (count > 8) { \
goto error; \
} else { \
count++; \
} \
} \
}
static int32_t
_uloc_addLikelySubtags(const char* localeID,
char* maximizedLocaleID,
@ -4068,6 +4115,8 @@ _uloc_addLikelySubtags(const char* localeID,
trailing = &localeID[trailingIndex];
trailingLength = uprv_strlen(trailing);
CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
resultLength =
createLikelySubtagsString(
lang,
@ -4172,6 +4221,8 @@ _uloc_minimizeSubtags(const char* localeID,
trailing = &localeID[trailingIndex];
trailingLength = uprv_strlen(trailing);
CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
createTagString(
lang,
langLength,

View File

@ -5388,7 +5388,7 @@ const char* const locale_to_langtag[][3] = {
{"iw_IL", "he-IL", "he-IL"},
{"sr_Latn_SR", "sr-Latn-SR", "sr-Latn-SR"},
{"en__POSIX", "en-posix", "en-posix"},
{"en_POSIX", "en", NULL},
{"en_POSIX", "en", "en"},
{"und_555", "und-555", "und-555"},
{"123", "und", NULL},
{"%$#&", "und", NULL},