]> granicus.if.org Git - icu/commitdiff
ICU-21035 Replace backward compatibility ulocimp_getLanguage() overload.
authorFredrik Roubert <roubert@google.com>
Thu, 20 Aug 2020 16:08:21 +0000 (18:08 +0200)
committerFredrik Roubert <fredrik@roubert.name>
Thu, 20 Aug 2020 21:38:30 +0000 (23:38 +0200)
By always calling the dynamic memory allocation implementation directly
instead, the fixed memory buffer boundary gets pushed one step further
towards the edges.

icu4c/source/common/loclikely.cpp
icu4c/source/common/uloc.cpp
icu4c/source/common/ulocimp.h

index 54c4a464ee39e89a9827825d820c6c3d1875b277..ea0d98cd9e350402f6c3c57b37362cbf2e7bacb5 100644 (file)
@@ -464,8 +464,18 @@ parseTagString(
         goto error;
     }
 
-    subtagLength = ulocimp_getLanguage(position, lang, *langLength, &position);
-    u_terminateChars(lang, *langLength, subtagLength, err);
+    {
+        icu::CharString result = ulocimp_getLanguage(position, &position, *err);
+        if (U_FAILURE(*err)) {
+            goto error;
+        }
+
+        subtagLength = result.length();
+        if (subtagLength <= *langLength) {
+            uprv_memcpy(lang, result.data(), subtagLength);
+        }
+        u_terminateChars(lang, *langLength, subtagLength, err);
+    }
 
     /*
      * Note that we explicit consider U_STRING_NOT_TERMINATED_WARNING
index 0e235d7958ceb1b6fbda0ca104cc5dfec158a62c..94cbaab220e629e37db313e0bac3f4a2b2455f17 100644 (file)
@@ -1148,7 +1148,7 @@ uloc_getCurrentLanguageID(const char* oldID){
  *
  * TODO try to use this in Locale
  */
-static CharString
+CharString U_EXPORT2
 ulocimp_getLanguage(const char *localeID,
                     const char **pEnd,
                     UErrorCode &status) {
@@ -1193,20 +1193,6 @@ ulocimp_getLanguage(const char *localeID,
     return result;
 }
 
-U_CFUNC int32_t
-ulocimp_getLanguage(const char *localeID,
-                    char *language, int32_t languageCapacity,
-                    const char **pEnd) {
-    ErrorCode status;
-    CharString result = ulocimp_getLanguage(localeID, pEnd, status);
-    if (status.isFailure()) {
-        return 0;
-    }
-    int32_t reslen = result.length();
-    uprv_memcpy(language, result.data(), std::min(reslen, languageCapacity));
-    return reslen;
-}
-
 static CharString
 ulocimp_getScript(const char *localeID,
                   const char **pEnd,
@@ -1486,7 +1472,11 @@ uloc_openKeywords(const char* localeID,
     }
 
     /* Skip the language */
-    ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID);
+    ulocimp_getLanguage(tmpLocaleID, &tmpLocaleID, *status);
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+
     if(_isIDSeparator(*tmpLocaleID)) {
         const char *scriptID;
         /* Skip the script if available */
@@ -1745,7 +1735,6 @@ uloc_getLanguage(const char*    localeID,
          UErrorCode* err)
 {
     /* uloc_getLanguage will return a 2 character iso-639 code if one exists. *CWB*/
-    int32_t i=0;
 
     if (err==NULL || U_FAILURE(*err)) {
         return 0;
@@ -1755,8 +1744,16 @@ uloc_getLanguage(const char*    localeID,
         localeID=uloc_getDefault();
     }
 
-    i=ulocimp_getLanguage(localeID, language, languageCapacity, NULL);
-    return u_terminateChars(language, languageCapacity, i, err);
+    CharString result = ulocimp_getLanguage(localeID, NULL, *err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
+    int32_t reslen = result.length();
+    if (reslen <= languageCapacity) {
+        uprv_memcpy(language, result.data(), reslen);
+    }
+    return u_terminateChars(language, languageCapacity, reslen, err);
 }
 
 U_CAPI int32_t U_EXPORT2
@@ -1776,7 +1773,11 @@ uloc_getScript(const char*    localeID,
     }
 
     /* skip the language */
-    ulocimp_getLanguage(localeID, NULL, 0, &localeID);
+    ulocimp_getLanguage(localeID, &localeID, *err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
     if(_isIDSeparator(*localeID)) {
         i=ulocimp_getScript(localeID+1, script, scriptCapacity, NULL);
     }
@@ -1800,7 +1801,11 @@ uloc_getCountry(const char* localeID,
     }
 
     /* Skip the language */
-    ulocimp_getLanguage(localeID, NULL, 0, &localeID);
+    ulocimp_getLanguage(localeID, &localeID, *err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
     if(_isIDSeparator(*localeID)) {
         const char *scriptID;
         /* Skip the script if available */
@@ -1840,7 +1845,11 @@ uloc_getVariant(const char* localeID,
     }
 
     /* Skip the language */
-    ulocimp_getLanguage(tmpLocaleID, NULL, 0, &tmpLocaleID);
+    ulocimp_getLanguage(tmpLocaleID, &tmpLocaleID, *err);
+    if (U_FAILURE(*err)) {
+        return 0;
+    }
+
     if(_isIDSeparator(*tmpLocaleID)) {
         const char *scriptID;
         /* Skip the script if available */
index b9e2eb4bfeb003ddc5de1cfe2265c8e515d8a7e1..b4d64c55cfba89a8727d383b1128e26f6001746d 100644 (file)
@@ -13,6 +13,8 @@
 #include "unicode/bytestream.h"
 #include "unicode/uloc.h"
 
+#include "charstr.h"
+
 /**
  * Create an iterator over the specified keywords list
  * @param keywordList double-null terminated list. Will be copied.
@@ -47,10 +49,10 @@ uloc_getCurrentCountryID(const char* oldID);
 U_CFUNC const char* 
 uloc_getCurrentLanguageID(const char* oldID);
 
-U_CFUNC int32_t
+icu::CharString U_EXPORT2
 ulocimp_getLanguage(const char *localeID,
-                    char *language, int32_t languageCapacity,
-                    const char **pEnd);
+                    const char **pEnd,
+                    UErrorCode &status);
 
 U_CFUNC int32_t
 ulocimp_getScript(const char *localeID,