Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c98822f
Fix for Unicode characters above U+FFFF.
jonsimantov Jun 28, 2023
8f5df9b
Change more firebase::Move to std::move.
jonsimantov Jun 29, 2023
e85ecc0
Revert "Change more firebase::Move to std::move."
jonsimantov Jun 29, 2023
16a6816
Add error handling to time zone conversion.
jonsimantov Jun 29, 2023
cd25bed
Fix scoping error.
jonsimantov Jun 29, 2023
144e296
Convert Windows TZ environment variable from CP-1252 to Unicode.
jonsimantov Jun 29, 2023
d5d1d8a
Don't use a variable length array.
jonsimantov Jun 29, 2023
d7c4507
Fix compiler error.
jonsimantov Jun 29, 2023
95fd607
Modify readme.
jonsimantov Jun 29, 2023
3ebf0a3
Fix array lookup.
jonsimantov Jun 29, 2023
480579e
Update readme.
jonsimantov Jun 29, 2023
5b15bc1
Also fix the fallback daylight saving time string encoding.
jonsimantov Jun 29, 2023
88a56c2
Merge branch 'main' into fix-for-windows-time-zone-name
jonsimantov Jun 29, 2023
1b4ea64
Rephrase readme.
jonsimantov Jun 29, 2023
957f16e
Merge branch 'fix-for-windows-time-zone-name' of https://github.com/f…
jonsimantov Jun 29, 2023
dafc8ab
Add unit test for conversions on Windows.
jonsimantov Jun 30, 2023
e583195
Add test for CP1252 conversion and fix conversion function that we ha…
jonsimantov Jun 30, 2023
0639d00
Merge branch 'main' into fix-for-windows-time-zone-name
jonsimantov Jun 30, 2023
c2bff60
Remove duplicate code.
jonsimantov Jun 30, 2023
712dd02
Merge branch 'fix-for-windows-time-zone-name' of https://github.com/f…
jonsimantov Jun 30, 2023
d1bca11
Merge branch 'main' into fix-for-windows-time-zone-name
jonsimantov Jun 30, 2023
92106c1
Add missing platform header.
jonsimantov Jun 30, 2023
ff97153
Add additional characters to locale test.
jonsimantov Jun 30, 2023
c35e972
Let's go wild, even more characters. This should cover most of what we
jonsimantov Jun 30, 2023
e58bca1
Format code.
jonsimantov Jun 30, 2023
32e3572
Merge branch 'main' into fix-for-windows-time-zone-name
jonsimantov Jun 30, 2023
8b9493c
Merge branch 'main' into fix-for-windows-time-zone-name
jonsimantov Jul 5, 2023
a6f62a4
Modified locale test to work with Windows wchar_t.
jonsimantov Jul 5, 2023
bfe6d44
Format code.
jonsimantov Jul 5, 2023
18bb494
Format code 2
jonsimantov Jul 5, 2023
6bee85d
Merge branch 'main' into fix-for-windows-time-zone-name
jonsimantov Jul 5, 2023
12be58f
Format code 3
jonsimantov Jul 5, 2023
e1c2b68
Format
jonsimantov Jul 5, 2023
dfd8001
Set thread language to English and use Use GetTimeZoneInformation.
jonsimantov Jul 5, 2023
4fbc5bd
Merge branch 'fix-for-windows-time-zone-name' of https://github.com/f…
jonsimantov Jul 5, 2023
144a728
Merge branch 'fix-for-windows-time-zone-name' of https://github.com/f…
jonsimantov Jul 5, 2023
5d0c920
Format code.
jonsimantov Jul 5, 2023
1273867
Add a comment about why we don't use daylight savings time in one spot.
jonsimantov Jul 5, 2023
48c13a0
Merge branch 'main' into fix-for-windows-time-zone-name
jonsimantov Jul 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/heartbeat/heartbeat_storage_desktop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ std::string CreateFilename(const std::string& app_id, const Logger& logger) {
std::string final_path_utf8 =
app_dir + "/" + kHeartbeatFilenamePrefix + app_id_without_symbols;
#if FIREBASE_PLATFORM_WINDOWS
std::wstring_convert<std::codecvt_utf8<wchar_t>> final_path_w;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> final_path_w;
return final_path_w.from_bytes(final_path_utf8);
#else
return final_path_utf8;
Expand Down
89 changes: 64 additions & 25 deletions app/src/locale.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include <string>
#include <vector>

#include "app/src/thread.h"

namespace firebase {
namespace internal {

Expand Down Expand Up @@ -92,6 +94,27 @@ std::string GetLocale() {
#endif // platform selector
}

#if FIREBASE_PLATFORM_WINDOWS
std::wstring GetWindowsTimezoneInEnglish(int daylight) {
struct TzNames {
std::wstring standard;
std::wstring daylight;
} tz_names;
Thread thread(
[](TzNames* tz_names_ptr) {
SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
TIME_ZONE_INFORMATION tzi;
GetTimeZoneInformation(&tzi);
tz_names_ptr->standard = tzi.StandardName;
tz_names_ptr->daylight = tzi.DaylightName;
},
&tz_names);
thread.Join();

return daylight ? tz_names.daylight : tz_names.standard;
}
#endif // FIREBASE_PLATFORM_WINDOWS

// Get the current time zone, e.g. "US/Pacific"
std::string GetTimezone() {
#if FIREBASE_PLATFORM_WINDOWS
Expand All @@ -101,20 +124,17 @@ std::string GetTimezone() {
// settings or the TZ variable, as appropriate.
tz_was_set = true;
}
// Get the standard time zone name.

// Get the non-daylight time zone, as the IANA conversion below requires the
// name of the standard time zone. For example, "Central European Standard
// Time" which converts to "Europe/Warsaw" or similar.
std::wstring windows_tz_utf16 = GetWindowsTimezoneInEnglish(0);
std::string windows_tz_utf8;
{
size_t length = 0; // get the needed string length
if (_get_tzname(&length, nullptr, 0, 0) != 0) return "";
std::vector<char> namebuf(length);
if (_get_tzname(&length, &namebuf[0], length, 0) != 0) return "";
windows_tz_utf8 = std::string(&namebuf[0]);
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> to_utf8;
windows_tz_utf8 = to_utf8.to_bytes(windows_tz_utf16);
}

// Convert time zone name to wide string
std::wstring_convert<std::codecvt_utf8<wchar_t>> to_utf16;
std::wstring windows_tz_utf16 = to_utf16.from_bytes(windows_tz_utf8);

std::string locale_name = GetLocale();
wchar_t iana_time_zone_buffer[128];
bool got_time_zone = false;
Expand Down Expand Up @@ -157,28 +177,47 @@ std::string GetTimezone() {
windows_tz_utf8.c_str(), u_errorName(error_code), error_code);
}
}
if (got_time_zone) {
// One of the above two succeeded, convert the new time zone name back to
// UTF-8.
std::wstring iana_tz_utf16(iana_time_zone_buffer);
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> to_utf8;
std::string iana_tz_utf8;
try {
iana_tz_utf8 = to_utf8.to_bytes(iana_tz_utf16);
} catch (std::range_error& ex) {
LogError("Failed to convert IANA time zone to UTF-8: %s", ex.what());
got_time_zone = false;
}
if (got_time_zone) {
return iana_tz_utf8;
}
}
if (!got_time_zone) {
// Return the Windows time zone ID as a backup.
// In this case, we need to get the correct daylight savings time
// setting to get the right name.
// Either the IANA time zone couldn't be determined, or couldn't be
// converted into UTF-8 for some reason (the std::range_error above).
//
// In any case, return the Windows time zone ID as a backup. We now need to
// get the correct daylight saving time setting to get the right name.
//
// Also, note as above that _get_tzname() doesn't return a UTF-8 name,
// rather CP-1252, so convert it to UTF-8 (via UTF-16) before returning.

int daylight = 0; // daylight savings time?
if (_get_daylight(&daylight) != 0) return windows_tz_utf8;
if (_get_daylight(&daylight) != 0) {
// Couldn't determine daylight saving time, return the old name.
return windows_tz_utf8;
}
if (daylight) {
size_t length = 0; // get the needed string length
if (_get_tzname(&length, nullptr, 0, 1) != 0) return windows_tz_utf8;
std::vector<char> namebuf(length);
if (_get_tzname(&length, &namebuf[0], length, 1) != 0)
return windows_tz_utf8;
windows_tz_utf8 = std::string(&namebuf[0]);
windows_tz_utf16 = GetWindowsTimezoneInEnglish(daylight);
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> to_utf8;
windows_tz_utf8 = to_utf8.to_bytes(windows_tz_utf16);
}
}
return windows_tz_utf8;
}

std::wstring iana_tz_utf16(iana_time_zone_buffer);
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> to_utf8;
std::string iana_tz_utf8 = to_utf8.to_bytes(iana_tz_utf16);
return iana_tz_utf8;

#elif FIREBASE_PLATFORM_LINUX
// If TZ environment variable is defined and not empty, use it, else use
// tzname.
Expand Down
2 changes: 2 additions & 0 deletions app/src/locale.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#include <string>

#include "app/src/include/firebase/internal/platform.h"

namespace firebase {
namespace internal {

Expand Down
21 changes: 20 additions & 1 deletion app/tests/locale_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "app/src/locale.h"

#include <codecvt>
#include <string>

#include "app/src/include/firebase/internal/platform.h"
Expand All @@ -24,7 +25,7 @@
#include "gtest/gtest.h"

#if FIREBASE_PLATFORM_WINDOWS

#include <windows.h>
#else
#include <clocale>
#endif // FIREBASE_PLATFORM_WINDOWS
Expand Down Expand Up @@ -52,5 +53,23 @@ TEST_F(LocaleTest, TestGetLocale) {
EXPECT_NE(loc.find('_'), std::string::npos);
}

#if FIREBASE_PLATFORM_WINDOWS

TEST_F(LocaleTest, TestTimeZoneNameInEnglish) {
LANGID prev_lang = GetThreadUILanguage();

SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
std::string timezone_english = GetTimezone();

SetThreadUILanguage(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN));
std::string timezone_german = GetTimezone();

EXPECT_EQ(timezone_english, timezone_german);

SetThreadUILanguage(prev_lang);
}

#endif // FIREBASE_PLATFORM_WINDOWS

} // namespace internal
} // namespace firebase
2 changes: 2 additions & 0 deletions release_build_files/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,8 @@ code.
- Changes
- Auth (Android): Fixed an issue where VerifyPhoneNumber's internal
builder failed to create PhoneAuthOptions with certain compiler settings.
- Remote Config (Desktop): Additional fix for handling of non-English time
zone names on Windows.

### 11.2.0
- Changes
Expand Down
2 changes: 1 addition & 1 deletion remote_config/src/desktop/file_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ RemoteConfigFileManager::RemoteConfigFileManager(const std::string& filename,
AppDataDir(app_data_prefix.c_str(), /*should_create=*/true) + "/" +
filename;
#if FIREBASE_PLATFORM_WINDOWS
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_to_wstring;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> utf8_to_wstring;
file_path_ = utf8_to_wstring.from_bytes(file_path);
#else
file_path_ = file_path;
Expand Down