]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/coll.cpp
ICU-64243.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / coll.cpp
index be4b6b886407ab4a161b486024f89b72a3b2b22d..ee2665793e3f856bd8934c5fd7b1060877629e57 100644 (file)
 #include "ustrenum.h"
 #include "uresimp.h"
 #include "ucln_in.h"
+#if U_PLATFORM_IS_DARWIN_BASED
+#include <os/log.h>
+#endif
 
 static icu::Locale* availableLocaleList = NULL;
 static int32_t  availableLocaleListCount;
+#if !UCONFIG_NO_SERVICE
 static icu::ICULocaleService* gService = NULL;
 static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER;
-static icu::UInitOnce gAvailableLocaleListInitOnce;
+#endif
+static icu::UInitOnce gAvailableLocaleListInitOnce = U_INITONCE_INITIALIZER;
 
 /**
  * Release all static memory held by collator.
@@ -224,27 +229,25 @@ initAvailableLocaleList(UErrorCode &status) {
     U_ASSERT(availableLocaleList == NULL);
     // for now, there is a hardcoded list, so just walk through that list and set it up.
     UResourceBundle *index = NULL;
-    UResourceBundle installed;
+    StackUResourceBundle installed;
     int32_t i = 0;
     
-    ures_initStackObject(&installed);
     index = ures_openDirect(U_ICUDATA_COLL, "res_index", &status);
-    ures_getByKey(index, "InstalledLocales", &installed, &status);
-    
+    ures_getByKey(index, "InstalledLocales", installed.getAlias(), &status);
+
     if(U_SUCCESS(status)) {
-        availableLocaleListCount = ures_getSize(&installed);
+        availableLocaleListCount = ures_getSize(installed.getAlias());
         availableLocaleList = new Locale[availableLocaleListCount];
         
         if (availableLocaleList != NULL) {
-            ures_resetIterator(&installed);
-            while(ures_hasNext(&installed)) {
+            ures_resetIterator(installed.getAlias());
+            while(ures_hasNext(installed.getAlias())) {
                 const char *tempKey = NULL;
-                ures_getNextString(&installed, NULL, &tempKey, &status);
+                ures_getNextString(installed.getAlias(), NULL, &tempKey, &status);
                 availableLocaleList[i++] = Locale(tempKey);
             }
         }
         U_ASSERT(availableLocaleListCount == i);
-        ures_close(&installed);
     }
     ures_close(index);
     ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup);
@@ -446,6 +449,27 @@ Collator* U_EXPORT2 Collator::createInstance(const Locale& desiredLocale,
 #endif
     {
         coll = makeInstance(desiredLocale, status);
+        // Either returns NULL with U_FAILURE(status), or non-NULL with U_SUCCESS(status)
+    }
+    // The use of *coll in setAttributesFromKeywords can cause the NULL check to be
+    // optimized out of the delete even though setAttributesFromKeywords returns
+    // immediately if U_FAILURE(status), so we add a check here.
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+    // makeInstance either returns NULL with U_FAILURE(status), or non-NULL with U_SUCCESS(status).
+    // The *coll in setAttributesFromKeywords causes the NULL check to be optimized out of the delete
+    // even though setAttributesFromKeywords returns immediately if U_FAILURE(status), so we add a
+    // check here and also log the locale name for failures. <rdar://problem/40930320>
+    if (U_FAILURE(status)) {
+#if U_PLATFORM_IS_DARWIN_BASED
+#if 0
+        // logging disabled for shipping system, can enable for internal debugging
+        const char* locname = desiredLocale.getName();
+        os_log(OS_LOG_DEFAULT, "Collator::createInstance fails with locale: %{public}s", locname? locname: "(NULL)");
+#endif
+#endif
+        return NULL;
     }
     setAttributesFromKeywords(desiredLocale, *coll, status);
     if (U_FAILURE(status)) {
@@ -984,8 +1008,8 @@ Collator::internalCompareUTF8(const char *left, int32_t leftLength,
         return UCOL_EQUAL;
     }
     return compareUTF8(
-            StringPiece(left, (leftLength < 0) ? uprv_strlen(left) : leftLength),
-            StringPiece(right, (rightLength < 0) ? uprv_strlen(right) : rightLength),
+            StringPiece(left, (leftLength < 0) ? static_cast<int32_t>(uprv_strlen(left)) : leftLength),
+            StringPiece(right, (rightLength < 0) ? static_cast<int32_t>(uprv_strlen(right)) : rightLength),
             errorCode);
 }