From 8985e60d381fbd15aef66c2df4d2395162ca6fc4 Mon Sep 17 00:00:00 2001
From: Fredrik Roubert <roubert@google.com>
Date: Fri, 14 Sep 2018 13:16:59 -0700
Subject: [PATCH] ICU-13417 Improved error handling in
 Locale::create(Unicode)?Keywords().

Follow-up from pull request #117:

Specify buffer size in only one place, explicitly check status before
proceeding and set status = U_MEMORY_ALLOCATION_ERROR if new fails.
---
 icu4c/source/common/locid.cpp | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp
index 784193f2511..6a69bab7222 100644
--- a/icu4c/source/common/locid.cpp
+++ b/icu4c/source/common/locid.cpp
@@ -1201,16 +1201,23 @@ StringEnumeration *
 Locale::createKeywords(UErrorCode &status) const
 {
     char keywords[256];
-    int32_t keywordCapacity = 256;
+    int32_t keywordCapacity = sizeof keywords;
     StringEnumeration *result = NULL;
 
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
     const char* variantStart = uprv_strchr(fullName, '@');
     const char* assignment = uprv_strchr(fullName, '=');
     if(variantStart) {
         if(assignment > variantStart) {
             int32_t keyLen = locale_getKeywords(variantStart+1, '@', keywords, keywordCapacity, NULL, 0, NULL, FALSE, &status);
-            if(keyLen) {
+            if(U_SUCCESS(status) && keyLen) {
                 result = new KeywordEnumeration(keywords, keyLen, 0, status);
+                if (!result) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                }
             }
         } else {
             status = U_INVALID_FORMAT_ERROR;
@@ -1223,16 +1230,23 @@ StringEnumeration *
 Locale::createUnicodeKeywords(UErrorCode &status) const
 {
     char keywords[256];
-    int32_t keywordCapacity = 256;
+    int32_t keywordCapacity = sizeof keywords;
     StringEnumeration *result = NULL;
 
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
     const char* variantStart = uprv_strchr(fullName, '@');
     const char* assignment = uprv_strchr(fullName, '=');
     if(variantStart) {
         if(assignment > variantStart) {
             int32_t keyLen = locale_getKeywords(variantStart+1, '@', keywords, keywordCapacity, NULL, 0, NULL, FALSE, &status);
-            if(keyLen) {
+            if(U_SUCCESS(status) && keyLen) {
                 result = new UnicodeKeywordEnumeration(keywords, keyLen, 0, status);
+                if (!result) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                }
             }
         } else {
             status = U_INVALID_FORMAT_ERROR;
-- 
2.40.0