|  | diff --git a/source/common/locid.cpp b/source/common/locid.cpp | 
|  | index 1efe0da9..feadbcbc 100644 | 
|  | --- a/source/common/locid.cpp | 
|  | +++ b/source/common/locid.cpp | 
|  | @@ -2457,9 +2457,13 @@ Locale::setKeywordValue(const char* keywordName, const char* keywordValue, UErro | 
|  | if (U_FAILURE(status)) { | 
|  | return; | 
|  | } | 
|  | +    if (status == U_STRING_NOT_TERMINATED_WARNING) { | 
|  | +        status = U_ZERO_ERROR; | 
|  | +    } | 
|  | int32_t bufferLength = uprv_max((int32_t)(uprv_strlen(fullName) + 1), ULOC_FULLNAME_CAPACITY); | 
|  | int32_t newLength = uloc_setKeywordValue(keywordName, keywordValue, fullName, | 
|  | bufferLength, &status) + 1; | 
|  | +    U_ASSERT(status != U_STRING_NOT_TERMINATED_WARNING); | 
|  | /* Handle the case the current buffer is not enough to hold the new id */ | 
|  | if (status == U_BUFFER_OVERFLOW_ERROR) { | 
|  | U_ASSERT(newLength > bufferLength); | 
|  | @@ -2476,6 +2480,7 @@ Locale::setKeywordValue(const char* keywordName, const char* keywordValue, UErro | 
|  | fullName = newFullName; | 
|  | status = U_ZERO_ERROR; | 
|  | uloc_setKeywordValue(keywordName, keywordValue, fullName, newLength, &status); | 
|  | +        U_ASSERT(status != U_STRING_NOT_TERMINATED_WARNING); | 
|  | } else { | 
|  | U_ASSERT(newLength <= bufferLength); | 
|  | } | 
|  | diff --git a/source/common/uloc.cpp b/source/common/uloc.cpp | 
|  | index 522f33db..ebfbb506 100644 | 
|  | --- a/source/common/uloc.cpp | 
|  | +++ b/source/common/uloc.cpp | 
|  | @@ -877,6 +877,9 @@ uloc_setKeywordValue(const char* keywordName, | 
|  | if(U_FAILURE(*status)) { | 
|  | return -1; | 
|  | } | 
|  | +    if (*status == U_STRING_NOT_TERMINATED_WARNING) { | 
|  | +        *status = U_ZERO_ERROR; | 
|  | +    } | 
|  | if (keywordName == NULL || keywordName[0] == 0 || bufferCapacity <= 1) { | 
|  | *status = U_ILLEGAL_ARGUMENT_ERROR; | 
|  | return 0; | 
|  | @@ -914,6 +917,7 @@ uloc_setKeywordValue(const char* keywordName, | 
|  | startSearchHere = (char*)locale_getKeywordsStart(buffer); | 
|  | if(startSearchHere == NULL || (startSearchHere[1]==0)) { | 
|  | if(keywordValueLen == 0) { /* no keywords = nothing to remove */ | 
|  | +            U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING); | 
|  | return bufLen; | 
|  | } | 
|  |  | 
|  | @@ -933,6 +937,7 @@ uloc_setKeywordValue(const char* keywordName, | 
|  | startSearchHere += keywordNameLen; | 
|  | *startSearchHere++ = '='; | 
|  | uprv_strcpy(startSearchHere, keywordValueBuffer); | 
|  | +        U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING); | 
|  | return needLen; | 
|  | } /* end shortcut - no @ */ | 
|  |  | 
|  | @@ -1047,13 +1052,27 @@ uloc_setKeywordValue(const char* keywordName, | 
|  | if (!handledInputKeyAndValue || U_FAILURE(*status)) { | 
|  | /* if input key/value specified removal of a keyword not present in locale, or | 
|  | * there was an error in CharString.append, leave original locale alone. */ | 
|  | +        U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING); | 
|  | return bufLen; | 
|  | } | 
|  |  | 
|  | // needLen = length of the part before '@' | 
|  | needLen = (int32_t)(startSearchHere - buffer); | 
|  | -    return needLen + updatedKeysAndValues.extract( | 
|  | +    // Check to see can we fit the startSearchHere, if not, return | 
|  | +    // U_BUFFER_OVERFLOW_ERROR without copy updatedKeysAndValues into it. | 
|  | +    // We do this because this API function does not behave like most others: | 
|  | +    // It promises never to set a U_STRING_NOT_TERMINATED_WARNING. | 
|  | +    // When the contents fits but without the terminating NUL, in this case we need to not change | 
|  | +    // the buffer contents and return with a buffer overflow error. | 
|  | +    int32_t appendLength = updatedKeysAndValues.length(); | 
|  | +    if (appendLength >= bufferCapacity - needLen) { | 
|  | +        *status = U_BUFFER_OVERFLOW_ERROR; | 
|  | +        return needLen + appendLength; | 
|  | +    } | 
|  | +    needLen += updatedKeysAndValues.extract( | 
|  | startSearchHere, bufferCapacity - needLen, *status); | 
|  | +    U_ASSERT(*status != U_STRING_NOT_TERMINATED_WARNING); | 
|  | +    return needLen; | 
|  | } | 
|  |  | 
|  | /* ### ID parsing implementation **************************************************/ |