Fix timezone detection on Japanese/Korean Windows
ICU's Windows timezone detection is broken on Japanese/Korean
(and potentially other non-English) Windows.
Cherrypick the upstream fix.
See http://bugs.icu-project.org/trac/ticket/13826 .
TBR=gsathya@chromium.org
Bug: 849724
Test: Set the timezone to Tokyo on Japanese Windows
Test: In JS console, 'new Date()' outputs 'Japan Standard Time' in parens.
Change-Id: Ie76c1e97ee2e965825f2fe99442c55e797b45f41
Reviewed-on: https://chromium-review.googlesource.com/1094322
Reviewed-by: Jungshik Shin <jshin@chromium.org>
diff --git a/README.chromium b/README.chromium
index 4f00970..d54d58e 100644
--- a/README.chromium
+++ b/README.chromium
@@ -290,3 +290,11 @@
- patches/msvc_numgroup.patch (fixed in 62-to-be)
- upstream bug:
https://ssl.icu-project.org/trac/ticket/13752
+
+11. Fix the Windows timezone detection on Japanese/Korean Windows
+
+ - patches/wintz.patch
+ - upstream bug:
+ https://ssl.icu-project.org/trac/ticket/13826
+
+
diff --git a/patches/wintz.patch b/patches/wintz.patch
new file mode 100644
index 0000000..08d110a
--- /dev/null
+++ b/patches/wintz.patch
@@ -0,0 +1,60 @@
+diff --git a/source/common/wintz.cpp b/source/common/wintz.cpp
+index 10e69ca5..3aaa36a0 100644
+--- a/source/common/wintz.cpp
++++ b/source/common/wintz.cpp
+@@ -49,7 +49,7 @@ typedef struct
+ /**
+ * Various registry keys and key fragments.
+ */
+-static const char CURRENT_ZONE_REGKEY[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation\\";
++static const wchar_t CURRENT_ZONE_REGKEY[] = L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation\\";
+ static const char STANDARD_TIME_REGKEY[] = " Standard Time";
+ static const char TZI_REGKEY[] = "TZI";
+ static const char STD_REGKEY[] = "Std";
+@@ -121,27 +121,39 @@ static LONG getSTDName(const char *winid, char *regStdName, int32_t length)
+ return result;
+ }
+
+-static LONG getTZKeyName(char* tzKeyName, int32_t length)
++static LONG getTZKeyName(char* tzKeyName, int32_t tzKeyNamelength)
+ {
+ HKEY hkey;
+ LONG result = FALSE;
+- DWORD cbData = length;
++ WCHAR timeZoneKeyNameData[128];
++ DWORD timeZoneKeyNameLength = static_cast<DWORD>(sizeof(timeZoneKeyNameData));
+
+- if(ERROR_SUCCESS == RegOpenKeyExA(
++ if(ERROR_SUCCESS == RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE,
+ CURRENT_ZONE_REGKEY,
+ 0,
+ KEY_QUERY_VALUE,
+ &hkey))
+ {
+- result = RegQueryValueExA(
++ if (ERROR_SUCCESS == RegQueryValueExW(
+ hkey,
+- "TimeZoneKeyName",
++ L"TimeZoneKeyName",
+ NULL,
+ NULL,
+- (LPBYTE)tzKeyName,
+- &cbData);
++ (LPBYTE)timeZoneKeyNameData,
++ &timeZoneKeyNameLength))
++ {
++ // Ensure null termination.
++ timeZoneKeyNameData[UPRV_LENGTHOF(timeZoneKeyNameData) - 1] = L'\0';
+
++ // Convert the UTF-16 string to UTF-8.
++ UErrorCode status = U_ZERO_ERROR;
++ u_strToUTF8(tzKeyName, tzKeyNamelength, NULL, reinterpret_cast<const UChar *>(timeZoneKeyNameData), -1, &status);
++ if (U_ZERO_ERROR == status)
++ {
++ result = ERROR_SUCCESS;
++ }
++ }
+ RegCloseKey(hkey);
+ }
+
diff --git a/source/common/wintz.cpp b/source/common/wintz.cpp
index 10e69ca..3aaa36a 100644
--- a/source/common/wintz.cpp
+++ b/source/common/wintz.cpp
@@ -49,7 +49,7 @@
/**
* Various registry keys and key fragments.
*/
-static const char CURRENT_ZONE_REGKEY[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation\\";
+static const wchar_t CURRENT_ZONE_REGKEY[] = L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation\\";
static const char STANDARD_TIME_REGKEY[] = " Standard Time";
static const char TZI_REGKEY[] = "TZI";
static const char STD_REGKEY[] = "Std";
@@ -121,27 +121,39 @@
return result;
}
-static LONG getTZKeyName(char* tzKeyName, int32_t length)
+static LONG getTZKeyName(char* tzKeyName, int32_t tzKeyNamelength)
{
HKEY hkey;
LONG result = FALSE;
- DWORD cbData = length;
+ WCHAR timeZoneKeyNameData[128];
+ DWORD timeZoneKeyNameLength = static_cast<DWORD>(sizeof(timeZoneKeyNameData));
- if(ERROR_SUCCESS == RegOpenKeyExA(
+ if(ERROR_SUCCESS == RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
CURRENT_ZONE_REGKEY,
0,
KEY_QUERY_VALUE,
&hkey))
{
- result = RegQueryValueExA(
+ if (ERROR_SUCCESS == RegQueryValueExW(
hkey,
- "TimeZoneKeyName",
+ L"TimeZoneKeyName",
NULL,
NULL,
- (LPBYTE)tzKeyName,
- &cbData);
+ (LPBYTE)timeZoneKeyNameData,
+ &timeZoneKeyNameLength))
+ {
+ // Ensure null termination.
+ timeZoneKeyNameData[UPRV_LENGTHOF(timeZoneKeyNameData) - 1] = L'\0';
+ // Convert the UTF-16 string to UTF-8.
+ UErrorCode status = U_ZERO_ERROR;
+ u_strToUTF8(tzKeyName, tzKeyNamelength, NULL, reinterpret_cast<const UChar *>(timeZoneKeyNameData), -1, &status);
+ if (U_ZERO_ERROR == status)
+ {
+ result = ERROR_SUCCESS;
+ }
+ }
RegCloseKey(hkey);
}