]> granicus.if.org Git - icu/commitdiff
ICU-21386 uprv_tzname() should find the correct Olson ID when /etc/localtime is a...
authorRob De Reycke <rob_dereycke@hotmail.com>
Fri, 24 Feb 2023 14:11:31 +0000 (14:11 +0000)
committerYoshito Umaoka <yumaoka@users.noreply.github.com>
Sat, 25 Feb 2023 21:48:43 +0000 (16:48 -0500)
See #2323

icu4c/source/common/putil.cpp
icu4c/source/common/uposixdefs.h
icu4c/source/test/depstest/dependencies.txt

index 747d37efa3d493418ed37d9c3b8290b6d426351f..b8cbb9f10a28e5ac1f59cd2d1e3ef379544f193a 100644 (file)
@@ -722,7 +722,7 @@ extern U_IMPORT char *U_TZNAME[];
 #include <dirent.h>  /* Needed to search through system timezone files */
 #endif
 static char gTimeZoneBuffer[PATH_MAX];
-static char *gTimeZoneBufferPtr = nullptr;
+static const char *gTimeZoneBufferPtr = nullptr;
 #endif
 
 #if !U_PLATFORM_USES_ONLY_WIN32_API
@@ -1171,16 +1171,16 @@ uprv_tzname(int n)
         because the tzfile contents is underspecified.
         This isn't guaranteed to work because it may not be a symlink.
         */
-        int32_t ret = (int32_t)readlink(TZDEFAULT, gTimeZoneBuffer, sizeof(gTimeZoneBuffer)-1);
-        if (0 < ret) {
+        char *ret = realpath(TZDEFAULT, gTimeZoneBuffer);
+        if (ret != nullptr && uprv_strcmp(TZDEFAULT, gTimeZoneBuffer) != 0) {
             int32_t tzZoneInfoTailLen = uprv_strlen(TZZONEINFOTAIL);
-            gTimeZoneBuffer[ret] = 0;
-            char *  tzZoneInfoTailPtr = uprv_strstr(gTimeZoneBuffer, TZZONEINFOTAIL);
-
-            if (tzZoneInfoTailPtr != nullptr
-                && isValidOlsonID(tzZoneInfoTailPtr + tzZoneInfoTailLen))
-            {
-                return (gTimeZoneBufferPtr = tzZoneInfoTailPtr + tzZoneInfoTailLen);
+            const char *tzZoneInfoTailPtr = uprv_strstr(gTimeZoneBuffer, TZZONEINFOTAIL);
+            if (tzZoneInfoTailPtr != nullptr) {
+                tzZoneInfoTailPtr += tzZoneInfoTailLen;
+                skipZoneIDPrefix(&tzZoneInfoTailPtr);
+                if (isValidOlsonID(tzZoneInfoTailPtr)) {
+                    return (gTimeZoneBufferPtr = tzZoneInfoTailPtr);
+                }
             }
         } else {
 #if defined(SEARCH_TZFILE)
index 23c3f6d466700c7984631205135d823d6a63faac..826c9bb47a207be847abaedc28aceb1c03e86643 100644 (file)
@@ -48,7 +48,7 @@
 #endif
 
 /*
- * Make sure things like readlink and such functions work.
+ * Make sure things like realpath and such functions work.
  * Poorly upgraded Solaris machines can't have this defined.
  * Cleanly installed Solaris can use this #define.
  *
index 28a2dc705ff326125c40e10b30cdc3700e943589..d95e4de3374e345e60a11e5c3df0742e34bd154a 100644 (file)
@@ -22,7 +22,7 @@ system_symbols:
     exp_and_tanhf
     stdlib_qsort
     system_locale
-    stdio_input stdio_output file_io readlink_function dir_io mmap_functions dlfcn
+    stdio_input stdio_output file_io realpath_function dir_io mmap_functions dlfcn
     # C++
     cplusplus iostream
     std_mutex
@@ -110,8 +110,8 @@ group: file_io
     # Additional symbols in an optimized build.
     __xstat
 
-group: readlink_function
-    readlink  # putil.cpp uprv_tzname() calls this in a hack to get the time zone name
+group: realpath_function
+    realpath  # putil.cpp uprv_tzname() calls this in a hack to get the time zone name
 
 group: dir_io
     opendir closedir readdir  # for a hack to get the time zone name
@@ -869,7 +869,7 @@ group: platform
     PIC system_misc system_debug malloc_functions ubsan
     c_strings c_string_formatting
     floating_point system_locale
-    stdio_input readlink_function dir_io
+    stdio_input realpath_function dir_io
     dlfcn  # Move related code into icuplug.c?
     cplusplus
     std_mutex