ICU-6204 Ensure valid country code in locale id is either size 2 or 3.
X-SVN-Rev: 26809
This commit is contained in:
parent
e5dc053c11
commit
fe62ee5a61
@ -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,
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user