From e8bc04d5dfd4a463608ccbb47efca7de222d66a5 Mon Sep 17 00:00:00 2001 From: Rob De Reycke Date: Fri, 24 Feb 2023 14:11:31 +0000 Subject: [PATCH] ICU-21386 uprv_tzname() should find the correct Olson ID when /etc/localtime is a "double" link See #2323 --- icu4c/source/common/putil.cpp | 20 ++++++++++---------- icu4c/source/common/uposixdefs.h | 2 +- icu4c/source/test/depstest/dependencies.txt | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/icu4c/source/common/putil.cpp b/icu4c/source/common/putil.cpp index 747d37efa3d..b8cbb9f10a2 100644 --- a/icu4c/source/common/putil.cpp +++ b/icu4c/source/common/putil.cpp @@ -722,7 +722,7 @@ extern U_IMPORT char *U_TZNAME[]; #include /* 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) diff --git a/icu4c/source/common/uposixdefs.h b/icu4c/source/common/uposixdefs.h index 23c3f6d4667..826c9bb47a2 100644 --- a/icu4c/source/common/uposixdefs.h +++ b/icu4c/source/common/uposixdefs.h @@ -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. * diff --git a/icu4c/source/test/depstest/dependencies.txt b/icu4c/source/test/depstest/dependencies.txt index 28a2dc705ff..d95e4de3374 100644 --- a/icu4c/source/test/depstest/dependencies.txt +++ b/icu4c/source/test/depstest/dependencies.txt @@ -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