From c98822ff4bbc0d20949a98a4a108df18af79c16a Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 28 Jun 2023 16:19:11 -0700 Subject: [PATCH 01/28] Fix for Unicode characters above U+FFFF. --- app/src/heartbeat/heartbeat_storage_desktop.cc | 2 +- app/src/locale.cc | 4 ++-- release_build_files/readme.md | 6 ++++++ remote_config/src/desktop/file_manager.cc | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/src/heartbeat/heartbeat_storage_desktop.cc b/app/src/heartbeat/heartbeat_storage_desktop.cc index ed94073b5f..8b2f6389f3 100644 --- a/app/src/heartbeat/heartbeat_storage_desktop.cc +++ b/app/src/heartbeat/heartbeat_storage_desktop.cc @@ -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> final_path_w; + std::wstring_convert> final_path_w; return final_path_w.from_bytes(final_path_utf8); #else return final_path_utf8; diff --git a/app/src/locale.cc b/app/src/locale.cc index 77e1b80db2..d26e51a263 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -112,7 +112,7 @@ std::string GetTimezone() { } // Convert time zone name to wide string - std::wstring_convert> to_utf16; + std::wstring_convert> to_utf16; std::wstring windows_tz_utf16 = to_utf16.from_bytes(windows_tz_utf8); std::string locale_name = GetLocale(); @@ -175,7 +175,7 @@ std::string GetTimezone() { } std::wstring iana_tz_utf16(iana_time_zone_buffer); - std::wstring_convert, wchar_t> to_utf8; + std::wstring_convert, wchar_t> to_utf8; std::string iana_tz_utf8 = to_utf8.to_bytes(iana_tz_utf16); return iana_tz_utf8; diff --git a/release_build_files/readme.md b/release_build_files/readme.md index cc162d6479..d8c701ebb5 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -631,6 +631,12 @@ code. - Changes - Auth (Android): Fixed an issue where VerifyPhoneNumber's internal builder failed to create PhoneAuthOptions with certain compiler settings. + - Remote Config (Desktop): Fix handling of time zones on Windows when + the time zone name in the current system language contains a high-numbered + Unicode code point that cannot be represented in a single UTF-16 + character. + - Storage (Desktop): Fixed a crash on Windows when uploading files from a + path containing a high-numbered Unicode code point (above U+FFFF). ### 11.2.0 - Changes diff --git a/remote_config/src/desktop/file_manager.cc b/remote_config/src/desktop/file_manager.cc index 3240c40cf4..f4cf5aeb5f 100644 --- a/remote_config/src/desktop/file_manager.cc +++ b/remote_config/src/desktop/file_manager.cc @@ -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> utf8_to_wstring; + std::wstring_convert> utf8_to_wstring; file_path_ = utf8_to_wstring.from_bytes(file_path); #else file_path_ = file_path; From 8f5df9b3cfc1e9cb6be48b8ef2f6ff2ac6f4c2c1 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 28 Jun 2023 17:37:49 -0700 Subject: [PATCH 02/28] Change more firebase::Move to std::move. --- firestore/src/android/document_reference_android.cc | 2 +- firestore/src/android/field_path_portable.cc | 2 +- firestore/src/android/field_path_portable.h | 2 +- firestore/src/android/field_value_android.cc | 2 +- firestore/src/android/firestore_android.cc | 2 +- firestore/src/android/jni_runnable_android.h | 4 ++-- firestore/src/android/lambda_event_listener.h | 4 ++-- firestore/src/android/lambda_transaction_function.h | 2 +- firestore/src/android/query_android.cc | 2 +- firestore/src/android/transaction_android.h | 2 +- firestore/src/common/collection_reference.cc | 4 ++-- firestore/src/common/document_reference.cc | 4 ++-- firestore/src/common/field_value.cc | 12 ++++++------ firestore/src/common/firestore.cc | 4 ++-- firestore/src/common/query.cc | 4 ++-- firestore/src/common/set_options.cc | 4 ++-- firestore/src/common/settings.cc | 2 +- remote_config/src/android/remote_config_android.h | 2 +- 18 files changed, 30 insertions(+), 30 deletions(-) diff --git a/firestore/src/android/document_reference_android.cc b/firestore/src/android/document_reference_android.cc index f62e7f7407..d5259d0d9d 100644 --- a/firestore/src/android/document_reference_android.cc +++ b/firestore/src/android/document_reference_android.cc @@ -182,7 +182,7 @@ ListenerRegistration DocumentReferenceInternal::AddSnapshotListener( std::function callback) { LambdaEventListener* listener = - new LambdaEventListener(firebase::Move(callback)); + new LambdaEventListener(std::move(callback)); return AddSnapshotListener(metadata_changes, listener, /*passing_listener_ownership=*/true); } diff --git a/firestore/src/android/field_path_portable.cc b/firestore/src/android/field_path_portable.cc index d8fe069979..7019f0d4dc 100644 --- a/firestore/src/android/field_path_portable.cc +++ b/firestore/src/android/field_path_portable.cc @@ -100,7 +100,7 @@ std::vector SplitOnDots(const std::string& input) { fail_validation(); } - result.push_back(firebase::Move(current_segment)); + result.push_back(std::move(current_segment)); } return result; diff --git a/firestore/src/android/field_path_portable.h b/firestore/src/android/field_path_portable.h index 1f10c76b6c..cc87676d4d 100644 --- a/firestore/src/android/field_path_portable.h +++ b/firestore/src/android/field_path_portable.h @@ -39,7 +39,7 @@ class FieldPathPortable { static constexpr const char* kDocumentKeyPath = "__name__"; explicit FieldPathPortable(std::vector&& segments) - : segments_(firebase::Move(segments)) {} + : segments_(std::move(segments)) {} /** Returns i-th segment of the path. */ const std::string& operator[](const size_t i) const { diff --git a/firestore/src/android/field_value_android.cc b/firestore/src/android/field_value_android.cc index 071188a726..083e1a7f3b 100644 --- a/firestore/src/android/field_value_android.cc +++ b/firestore/src/android/field_value_android.cc @@ -343,7 +343,7 @@ MapFieldValue FieldValueInternal::map_value() const { Local java_value = map.Get(env, java_key); FieldValue value = FieldValueInternal::Create(env, java_value); - result.insert(std::make_pair(firebase::Move(key), firebase::Move(value))); + result.insert(std::make_pair(std::move(key), firebase::Move(value))); } if (!env.ok()) return MapFieldValue(); diff --git a/firestore/src/android/firestore_android.cc b/firestore/src/android/firestore_android.cc index e3317b6fe7..8933ecb097 100644 --- a/firestore/src/android/firestore_android.cc +++ b/firestore/src/android/firestore_android.cc @@ -539,7 +539,7 @@ ListenerRegistration FirestoreInternal::AddSnapshotsInSyncListener( ListenerRegistration FirestoreInternal::AddSnapshotsInSyncListener( std::function callback) { - auto* listener = new LambdaEventListener(firebase::Move(callback)); + auto* listener = new LambdaEventListener(std::move(callback)); return AddSnapshotsInSyncListener(listener, /*passing_listener_ownership=*/true); } diff --git a/firestore/src/android/jni_runnable_android.h b/firestore/src/android/jni_runnable_android.h index d64d63f1c7..5ce439a439 100644 --- a/firestore/src/android/jni_runnable_android.h +++ b/firestore/src/android/jni_runnable_android.h @@ -132,7 +132,7 @@ template class JniRunnable : public JniRunnableBase { public: JniRunnable(jni::Env& env, CallbackT callback) - : JniRunnableBase(env), callback_(firebase::Move(callback)) {} + : JniRunnableBase(env), callback_(std::move(callback)) {} void Run() override { Run(*this, callback_); } @@ -164,7 +164,7 @@ class JniRunnable : public JniRunnableBase { */ template JniRunnable MakeJniRunnable(jni::Env& env, CallbackT callback) { - return JniRunnable(env, firebase::Move(callback)); + return JniRunnable(env, std::move(callback)); } } // namespace firestore diff --git a/firestore/src/android/lambda_event_listener.h b/firestore/src/android/lambda_event_listener.h index 5cb6d994f5..06f6e087fa 100644 --- a/firestore/src/android/lambda_event_listener.h +++ b/firestore/src/android/lambda_event_listener.h @@ -35,7 +35,7 @@ class LambdaEventListener : public EventListener { public: LambdaEventListener( std::function callback) - : callback_(firebase::Move(callback)) { + : callback_(std::move(callback)) { FIREBASE_ASSERT(callback_); } @@ -53,7 +53,7 @@ template <> class LambdaEventListener : public EventListener { public: LambdaEventListener(std::function callback) - : callback_(firebase::Move(callback)) { + : callback_(std::move(callback)) { FIREBASE_ASSERT(callback_); } diff --git a/firestore/src/android/lambda_transaction_function.h b/firestore/src/android/lambda_transaction_function.h index bd266986a0..c67aef19e1 100644 --- a/firestore/src/android/lambda_transaction_function.h +++ b/firestore/src/android/lambda_transaction_function.h @@ -44,7 +44,7 @@ class LambdaTransactionFunction public: LambdaTransactionFunction( std::function update) - : update_(firebase::Move(update)) { + : update_(std::move(update)) { FIREBASE_ASSERT(update_); } diff --git a/firestore/src/android/query_android.cc b/firestore/src/android/query_android.cc index 81fdd418e0..9b1d89b0a9 100644 --- a/firestore/src/android/query_android.cc +++ b/firestore/src/android/query_android.cc @@ -320,7 +320,7 @@ ListenerRegistration QueryInternal::AddSnapshotListener( std::function callback) { auto* listener = - new LambdaEventListener(firebase::Move(callback)); + new LambdaEventListener(std::move(callback)); return AddSnapshotListener(metadata_changes, listener, /*passing_listener_ownership=*/true); } diff --git a/firestore/src/android/transaction_android.h b/firestore/src/android/transaction_android.h index 450bedc1b2..8dc4152638 100644 --- a/firestore/src/android/transaction_android.h +++ b/firestore/src/android/transaction_android.h @@ -47,7 +47,7 @@ class TransactionInternal : public Wrapper { : Wrapper(rhs), first_exception_(rhs.first_exception_) {} TransactionInternal(TransactionInternal&& rhs) - : Wrapper(firebase::Move(rhs)), + : Wrapper(std::move(rhs)), first_exception_(std::move(rhs.first_exception_)) {} void Set(const DocumentReference& document, diff --git a/firestore/src/common/collection_reference.cc b/firestore/src/common/collection_reference.cc index ff8fc81280..e4cf635d5d 100644 --- a/firestore/src/common/collection_reference.cc +++ b/firestore/src/common/collection_reference.cc @@ -48,7 +48,7 @@ CollectionReference::CollectionReference(const CollectionReference& reference) : nullptr) {} CollectionReference::CollectionReference(CollectionReference&& reference) - : Query(firebase::Move(reference)) {} + : Query(std::move(reference)) {} CollectionReference::CollectionReference(CollectionReferenceInternal* internal) : Query(internal) {} @@ -61,7 +61,7 @@ CollectionReference& CollectionReference::operator=( CollectionReference& CollectionReference::operator=( CollectionReference&& reference) { - Query::operator=(firebase::Move(reference)); + Query::operator=(std::move(reference)); return *this; } diff --git a/firestore/src/common/document_reference.cc b/firestore/src/common/document_reference.cc index 9e74b1bed2..05a5b32cbe 100644 --- a/firestore/src/common/document_reference.cc +++ b/firestore/src/common/document_reference.cc @@ -179,7 +179,7 @@ ListenerRegistration DocumentReference::AddSnapshotListener( std::function callback) { return AddSnapshotListener(MetadataChanges::kExclude, - firebase::Move(callback)); + std::move(callback)); } ListenerRegistration DocumentReference::AddSnapshotListener( @@ -192,7 +192,7 @@ ListenerRegistration DocumentReference::AddSnapshotListener( if (!internal_) return {}; return internal_->AddSnapshotListener(metadata_changes, - firebase::Move(callback)); + std::move(callback)); } std::string DocumentReference::ToString() const { diff --git a/firestore/src/common/field_value.cc b/firestore/src/common/field_value.cc index b64b38cdfb..482748f6bc 100644 --- a/firestore/src/common/field_value.cc +++ b/firestore/src/common/field_value.cc @@ -157,7 +157,7 @@ FieldValue FieldValue::Timestamp(class Timestamp value) { /* static */ FieldValue FieldValue::String(std::string value) { - return FieldValue{new FieldValueInternal(firebase::Move(value))}; + return FieldValue{new FieldValueInternal(std::move(value))}; } /* static */ @@ -167,7 +167,7 @@ FieldValue FieldValue::Blob(const uint8_t* value, size_t size) { /* static */ FieldValue FieldValue::Reference(DocumentReference value) { - return FieldValue{new FieldValueInternal(firebase::Move(value))}; + return FieldValue{new FieldValueInternal(std::move(value))}; } /* static */ @@ -177,12 +177,12 @@ FieldValue FieldValue::GeoPoint(class GeoPoint value) { /* static */ FieldValue FieldValue::Array(std::vector value) { - return FieldValue{new FieldValueInternal(firebase::Move(value))}; + return FieldValue{new FieldValueInternal(std::move(value))}; } /* static */ FieldValue FieldValue::Map(MapFieldValue value) { - return FieldValue{new FieldValueInternal(firebase::Move(value))}; + return FieldValue{new FieldValueInternal(std::move(value))}; } Type FieldValue::type() const { @@ -262,12 +262,12 @@ FieldValue FieldValue::ServerTimestamp() { /* static */ FieldValue FieldValue::ArrayUnion(std::vector elements) { - return FieldValueInternal::ArrayUnion(firebase::Move(elements)); + return FieldValueInternal::ArrayUnion(std::move(elements)); } /* static */ FieldValue FieldValue::ArrayRemove(std::vector elements) { - return FieldValueInternal::ArrayRemove(firebase::Move(elements)); + return FieldValueInternal::ArrayRemove(std::move(elements)); } /* static */ diff --git a/firestore/src/common/firestore.cc b/firestore/src/common/firestore.cc index b5484c6848..cf64630847 100644 --- a/firestore/src/common/firestore.cc +++ b/firestore/src/common/firestore.cc @@ -344,7 +344,7 @@ Settings Firestore::settings() const { void Firestore::set_settings(Settings settings) { if (!internal_) return; - internal_->set_settings(firebase::Move(settings)); + internal_->set_settings(std::move(settings)); } WriteBatch Firestore::batch() const { @@ -366,7 +366,7 @@ Future Firestore::RunTransaction( } if (!internal_) return FailedFuture(); - return internal_->RunTransaction(firebase::Move(update), + return internal_->RunTransaction(std::move(update), options.max_attempts()); } diff --git a/firestore/src/common/query.cc b/firestore/src/common/query.cc index 7edbdd7602..1f975d2400 100644 --- a/firestore/src/common/query.cc +++ b/firestore/src/common/query.cc @@ -293,7 +293,7 @@ ListenerRegistration Query::AddSnapshotListener( std::function callback) { return AddSnapshotListener(MetadataChanges::kExclude, - firebase::Move(callback)); + std::move(callback)); } ListenerRegistration Query::AddSnapshotListener( @@ -305,7 +305,7 @@ ListenerRegistration Query::AddSnapshotListener( if (!internal_) return {}; return internal_->AddSnapshotListener(metadata_changes, - firebase::Move(callback)); + std::move(callback)); } size_t Query::Hash() const { diff --git a/firestore/src/common/set_options.cc b/firestore/src/common/set_options.cc index 6a0e2e05dc..a291d91cd3 100644 --- a/firestore/src/common/set_options.cc +++ b/firestore/src/common/set_options.cc @@ -22,7 +22,7 @@ namespace firebase { namespace firestore { SetOptions::SetOptions(Type type, std::unordered_set fields) - : type_(type), fields_(firebase::Move(fields)) {} + : type_(type), fields_(std::move(fields)) {} SetOptions::~SetOptions() {} @@ -38,7 +38,7 @@ SetOptions SetOptions::MergeFields(const std::vector& fields) { for (const std::string& field : fields) { field_paths.insert(FieldPath::FromDotSeparatedString(field)); } - return SetOptions{Type::kMergeSpecific, firebase::Move(field_paths)}; + return SetOptions{Type::kMergeSpecific, std::move(field_paths)}; } /* static */ diff --git a/firestore/src/common/settings.cc b/firestore/src/common/settings.cc index 3e1bfeebfb..ba7daa0b83 100644 --- a/firestore/src/common/settings.cc +++ b/firestore/src/common/settings.cc @@ -47,7 +47,7 @@ std::string ToStr(int64_t v) { Settings::Settings() : host_(kDefaultHost) {} #endif -void Settings::set_host(std::string host) { host_ = firebase::Move(host); } +void Settings::set_host(std::string host) { host_ = std::move(host); } void Settings::set_ssl_enabled(bool enabled) { ssl_enabled_ = enabled; } diff --git a/remote_config/src/android/remote_config_android.h b/remote_config/src/android/remote_config_android.h index c286002af4..c3af593b97 100644 --- a/remote_config/src/android/remote_config_android.h +++ b/remote_config/src/android/remote_config_android.h @@ -101,7 +101,7 @@ class RemoteConfigInternal { void SaveTmpKeysToDefault(std::vector tmp_default_keys) { MutexLock lock(default_key_mutex_); #if defined(FIREBASE_USE_MOVE_OPERATORS) - default_keys_ = firebase::Move(tmp_default_keys); + default_keys_ = std::move(tmp_default_keys); #else default_keys_ = tmp_default_keys; #endif // FIREBASE_USE_MOVE_OPERATORS From e85ecc02843ddf31727fb8a0a34611be0649e3c3 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 28 Jun 2023 17:38:18 -0700 Subject: [PATCH 03/28] Revert "Change more firebase::Move to std::move." This reverts commit 8f5df9b3cfc1e9cb6be48b8ef2f6ff2ac6f4c2c1. --- firestore/src/android/document_reference_android.cc | 2 +- firestore/src/android/field_path_portable.cc | 2 +- firestore/src/android/field_path_portable.h | 2 +- firestore/src/android/field_value_android.cc | 2 +- firestore/src/android/firestore_android.cc | 2 +- firestore/src/android/jni_runnable_android.h | 4 ++-- firestore/src/android/lambda_event_listener.h | 4 ++-- firestore/src/android/lambda_transaction_function.h | 2 +- firestore/src/android/query_android.cc | 2 +- firestore/src/android/transaction_android.h | 2 +- firestore/src/common/collection_reference.cc | 4 ++-- firestore/src/common/document_reference.cc | 4 ++-- firestore/src/common/field_value.cc | 12 ++++++------ firestore/src/common/firestore.cc | 4 ++-- firestore/src/common/query.cc | 4 ++-- firestore/src/common/set_options.cc | 4 ++-- firestore/src/common/settings.cc | 2 +- remote_config/src/android/remote_config_android.h | 2 +- 18 files changed, 30 insertions(+), 30 deletions(-) diff --git a/firestore/src/android/document_reference_android.cc b/firestore/src/android/document_reference_android.cc index d5259d0d9d..f62e7f7407 100644 --- a/firestore/src/android/document_reference_android.cc +++ b/firestore/src/android/document_reference_android.cc @@ -182,7 +182,7 @@ ListenerRegistration DocumentReferenceInternal::AddSnapshotListener( std::function callback) { LambdaEventListener* listener = - new LambdaEventListener(std::move(callback)); + new LambdaEventListener(firebase::Move(callback)); return AddSnapshotListener(metadata_changes, listener, /*passing_listener_ownership=*/true); } diff --git a/firestore/src/android/field_path_portable.cc b/firestore/src/android/field_path_portable.cc index 7019f0d4dc..d8fe069979 100644 --- a/firestore/src/android/field_path_portable.cc +++ b/firestore/src/android/field_path_portable.cc @@ -100,7 +100,7 @@ std::vector SplitOnDots(const std::string& input) { fail_validation(); } - result.push_back(std::move(current_segment)); + result.push_back(firebase::Move(current_segment)); } return result; diff --git a/firestore/src/android/field_path_portable.h b/firestore/src/android/field_path_portable.h index cc87676d4d..1f10c76b6c 100644 --- a/firestore/src/android/field_path_portable.h +++ b/firestore/src/android/field_path_portable.h @@ -39,7 +39,7 @@ class FieldPathPortable { static constexpr const char* kDocumentKeyPath = "__name__"; explicit FieldPathPortable(std::vector&& segments) - : segments_(std::move(segments)) {} + : segments_(firebase::Move(segments)) {} /** Returns i-th segment of the path. */ const std::string& operator[](const size_t i) const { diff --git a/firestore/src/android/field_value_android.cc b/firestore/src/android/field_value_android.cc index 083e1a7f3b..071188a726 100644 --- a/firestore/src/android/field_value_android.cc +++ b/firestore/src/android/field_value_android.cc @@ -343,7 +343,7 @@ MapFieldValue FieldValueInternal::map_value() const { Local java_value = map.Get(env, java_key); FieldValue value = FieldValueInternal::Create(env, java_value); - result.insert(std::make_pair(std::move(key), firebase::Move(value))); + result.insert(std::make_pair(firebase::Move(key), firebase::Move(value))); } if (!env.ok()) return MapFieldValue(); diff --git a/firestore/src/android/firestore_android.cc b/firestore/src/android/firestore_android.cc index 8933ecb097..e3317b6fe7 100644 --- a/firestore/src/android/firestore_android.cc +++ b/firestore/src/android/firestore_android.cc @@ -539,7 +539,7 @@ ListenerRegistration FirestoreInternal::AddSnapshotsInSyncListener( ListenerRegistration FirestoreInternal::AddSnapshotsInSyncListener( std::function callback) { - auto* listener = new LambdaEventListener(std::move(callback)); + auto* listener = new LambdaEventListener(firebase::Move(callback)); return AddSnapshotsInSyncListener(listener, /*passing_listener_ownership=*/true); } diff --git a/firestore/src/android/jni_runnable_android.h b/firestore/src/android/jni_runnable_android.h index 5ce439a439..d64d63f1c7 100644 --- a/firestore/src/android/jni_runnable_android.h +++ b/firestore/src/android/jni_runnable_android.h @@ -132,7 +132,7 @@ template class JniRunnable : public JniRunnableBase { public: JniRunnable(jni::Env& env, CallbackT callback) - : JniRunnableBase(env), callback_(std::move(callback)) {} + : JniRunnableBase(env), callback_(firebase::Move(callback)) {} void Run() override { Run(*this, callback_); } @@ -164,7 +164,7 @@ class JniRunnable : public JniRunnableBase { */ template JniRunnable MakeJniRunnable(jni::Env& env, CallbackT callback) { - return JniRunnable(env, std::move(callback)); + return JniRunnable(env, firebase::Move(callback)); } } // namespace firestore diff --git a/firestore/src/android/lambda_event_listener.h b/firestore/src/android/lambda_event_listener.h index 06f6e087fa..5cb6d994f5 100644 --- a/firestore/src/android/lambda_event_listener.h +++ b/firestore/src/android/lambda_event_listener.h @@ -35,7 +35,7 @@ class LambdaEventListener : public EventListener { public: LambdaEventListener( std::function callback) - : callback_(std::move(callback)) { + : callback_(firebase::Move(callback)) { FIREBASE_ASSERT(callback_); } @@ -53,7 +53,7 @@ template <> class LambdaEventListener : public EventListener { public: LambdaEventListener(std::function callback) - : callback_(std::move(callback)) { + : callback_(firebase::Move(callback)) { FIREBASE_ASSERT(callback_); } diff --git a/firestore/src/android/lambda_transaction_function.h b/firestore/src/android/lambda_transaction_function.h index c67aef19e1..bd266986a0 100644 --- a/firestore/src/android/lambda_transaction_function.h +++ b/firestore/src/android/lambda_transaction_function.h @@ -44,7 +44,7 @@ class LambdaTransactionFunction public: LambdaTransactionFunction( std::function update) - : update_(std::move(update)) { + : update_(firebase::Move(update)) { FIREBASE_ASSERT(update_); } diff --git a/firestore/src/android/query_android.cc b/firestore/src/android/query_android.cc index 9b1d89b0a9..81fdd418e0 100644 --- a/firestore/src/android/query_android.cc +++ b/firestore/src/android/query_android.cc @@ -320,7 +320,7 @@ ListenerRegistration QueryInternal::AddSnapshotListener( std::function callback) { auto* listener = - new LambdaEventListener(std::move(callback)); + new LambdaEventListener(firebase::Move(callback)); return AddSnapshotListener(metadata_changes, listener, /*passing_listener_ownership=*/true); } diff --git a/firestore/src/android/transaction_android.h b/firestore/src/android/transaction_android.h index 8dc4152638..450bedc1b2 100644 --- a/firestore/src/android/transaction_android.h +++ b/firestore/src/android/transaction_android.h @@ -47,7 +47,7 @@ class TransactionInternal : public Wrapper { : Wrapper(rhs), first_exception_(rhs.first_exception_) {} TransactionInternal(TransactionInternal&& rhs) - : Wrapper(std::move(rhs)), + : Wrapper(firebase::Move(rhs)), first_exception_(std::move(rhs.first_exception_)) {} void Set(const DocumentReference& document, diff --git a/firestore/src/common/collection_reference.cc b/firestore/src/common/collection_reference.cc index e4cf635d5d..ff8fc81280 100644 --- a/firestore/src/common/collection_reference.cc +++ b/firestore/src/common/collection_reference.cc @@ -48,7 +48,7 @@ CollectionReference::CollectionReference(const CollectionReference& reference) : nullptr) {} CollectionReference::CollectionReference(CollectionReference&& reference) - : Query(std::move(reference)) {} + : Query(firebase::Move(reference)) {} CollectionReference::CollectionReference(CollectionReferenceInternal* internal) : Query(internal) {} @@ -61,7 +61,7 @@ CollectionReference& CollectionReference::operator=( CollectionReference& CollectionReference::operator=( CollectionReference&& reference) { - Query::operator=(std::move(reference)); + Query::operator=(firebase::Move(reference)); return *this; } diff --git a/firestore/src/common/document_reference.cc b/firestore/src/common/document_reference.cc index 05a5b32cbe..9e74b1bed2 100644 --- a/firestore/src/common/document_reference.cc +++ b/firestore/src/common/document_reference.cc @@ -179,7 +179,7 @@ ListenerRegistration DocumentReference::AddSnapshotListener( std::function callback) { return AddSnapshotListener(MetadataChanges::kExclude, - std::move(callback)); + firebase::Move(callback)); } ListenerRegistration DocumentReference::AddSnapshotListener( @@ -192,7 +192,7 @@ ListenerRegistration DocumentReference::AddSnapshotListener( if (!internal_) return {}; return internal_->AddSnapshotListener(metadata_changes, - std::move(callback)); + firebase::Move(callback)); } std::string DocumentReference::ToString() const { diff --git a/firestore/src/common/field_value.cc b/firestore/src/common/field_value.cc index 482748f6bc..b64b38cdfb 100644 --- a/firestore/src/common/field_value.cc +++ b/firestore/src/common/field_value.cc @@ -157,7 +157,7 @@ FieldValue FieldValue::Timestamp(class Timestamp value) { /* static */ FieldValue FieldValue::String(std::string value) { - return FieldValue{new FieldValueInternal(std::move(value))}; + return FieldValue{new FieldValueInternal(firebase::Move(value))}; } /* static */ @@ -167,7 +167,7 @@ FieldValue FieldValue::Blob(const uint8_t* value, size_t size) { /* static */ FieldValue FieldValue::Reference(DocumentReference value) { - return FieldValue{new FieldValueInternal(std::move(value))}; + return FieldValue{new FieldValueInternal(firebase::Move(value))}; } /* static */ @@ -177,12 +177,12 @@ FieldValue FieldValue::GeoPoint(class GeoPoint value) { /* static */ FieldValue FieldValue::Array(std::vector value) { - return FieldValue{new FieldValueInternal(std::move(value))}; + return FieldValue{new FieldValueInternal(firebase::Move(value))}; } /* static */ FieldValue FieldValue::Map(MapFieldValue value) { - return FieldValue{new FieldValueInternal(std::move(value))}; + return FieldValue{new FieldValueInternal(firebase::Move(value))}; } Type FieldValue::type() const { @@ -262,12 +262,12 @@ FieldValue FieldValue::ServerTimestamp() { /* static */ FieldValue FieldValue::ArrayUnion(std::vector elements) { - return FieldValueInternal::ArrayUnion(std::move(elements)); + return FieldValueInternal::ArrayUnion(firebase::Move(elements)); } /* static */ FieldValue FieldValue::ArrayRemove(std::vector elements) { - return FieldValueInternal::ArrayRemove(std::move(elements)); + return FieldValueInternal::ArrayRemove(firebase::Move(elements)); } /* static */ diff --git a/firestore/src/common/firestore.cc b/firestore/src/common/firestore.cc index cf64630847..b5484c6848 100644 --- a/firestore/src/common/firestore.cc +++ b/firestore/src/common/firestore.cc @@ -344,7 +344,7 @@ Settings Firestore::settings() const { void Firestore::set_settings(Settings settings) { if (!internal_) return; - internal_->set_settings(std::move(settings)); + internal_->set_settings(firebase::Move(settings)); } WriteBatch Firestore::batch() const { @@ -366,7 +366,7 @@ Future Firestore::RunTransaction( } if (!internal_) return FailedFuture(); - return internal_->RunTransaction(std::move(update), + return internal_->RunTransaction(firebase::Move(update), options.max_attempts()); } diff --git a/firestore/src/common/query.cc b/firestore/src/common/query.cc index 1f975d2400..7edbdd7602 100644 --- a/firestore/src/common/query.cc +++ b/firestore/src/common/query.cc @@ -293,7 +293,7 @@ ListenerRegistration Query::AddSnapshotListener( std::function callback) { return AddSnapshotListener(MetadataChanges::kExclude, - std::move(callback)); + firebase::Move(callback)); } ListenerRegistration Query::AddSnapshotListener( @@ -305,7 +305,7 @@ ListenerRegistration Query::AddSnapshotListener( if (!internal_) return {}; return internal_->AddSnapshotListener(metadata_changes, - std::move(callback)); + firebase::Move(callback)); } size_t Query::Hash() const { diff --git a/firestore/src/common/set_options.cc b/firestore/src/common/set_options.cc index a291d91cd3..6a0e2e05dc 100644 --- a/firestore/src/common/set_options.cc +++ b/firestore/src/common/set_options.cc @@ -22,7 +22,7 @@ namespace firebase { namespace firestore { SetOptions::SetOptions(Type type, std::unordered_set fields) - : type_(type), fields_(std::move(fields)) {} + : type_(type), fields_(firebase::Move(fields)) {} SetOptions::~SetOptions() {} @@ -38,7 +38,7 @@ SetOptions SetOptions::MergeFields(const std::vector& fields) { for (const std::string& field : fields) { field_paths.insert(FieldPath::FromDotSeparatedString(field)); } - return SetOptions{Type::kMergeSpecific, std::move(field_paths)}; + return SetOptions{Type::kMergeSpecific, firebase::Move(field_paths)}; } /* static */ diff --git a/firestore/src/common/settings.cc b/firestore/src/common/settings.cc index ba7daa0b83..3e1bfeebfb 100644 --- a/firestore/src/common/settings.cc +++ b/firestore/src/common/settings.cc @@ -47,7 +47,7 @@ std::string ToStr(int64_t v) { Settings::Settings() : host_(kDefaultHost) {} #endif -void Settings::set_host(std::string host) { host_ = std::move(host); } +void Settings::set_host(std::string host) { host_ = firebase::Move(host); } void Settings::set_ssl_enabled(bool enabled) { ssl_enabled_ = enabled; } diff --git a/remote_config/src/android/remote_config_android.h b/remote_config/src/android/remote_config_android.h index c3af593b97..c286002af4 100644 --- a/remote_config/src/android/remote_config_android.h +++ b/remote_config/src/android/remote_config_android.h @@ -101,7 +101,7 @@ class RemoteConfigInternal { void SaveTmpKeysToDefault(std::vector tmp_default_keys) { MutexLock lock(default_key_mutex_); #if defined(FIREBASE_USE_MOVE_OPERATORS) - default_keys_ = std::move(tmp_default_keys); + default_keys_ = firebase::Move(tmp_default_keys); #else default_keys_ = tmp_default_keys; #endif // FIREBASE_USE_MOVE_OPERATORS From 16a6816ec8d8fa59d1b52c4d3a8303a4d18479f7 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 28 Jun 2023 17:55:19 -0700 Subject: [PATCH 04/28] Add error handling to time zone conversion. --- app/src/locale.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index d26e51a263..b9442e9805 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -113,7 +113,13 @@ std::string GetTimezone() { // Convert time zone name to wide string std::wstring_convert> to_utf16; - std::wstring windows_tz_utf16 = to_utf16.from_bytes(windows_tz_utf8); + try { + std::wstring windows_tz_utf16 = to_utf16.from_bytes(windows_tz_utf8); + } catch (std::range_error& ex) { + LogError("Failed to convert UTF-8 time zone '%s' to UTF-16: %s", + windows_tz_utf8, ex.what()); + return ""; + } std::string locale_name = GetLocale(); wchar_t iana_time_zone_buffer[128]; @@ -176,7 +182,12 @@ std::string GetTimezone() { std::wstring iana_tz_utf16(iana_time_zone_buffer); std::wstring_convert, wchar_t> to_utf8; - std::string iana_tz_utf8 = to_utf8.to_bytes(iana_tz_utf16); + try { + std::string 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()); + return ""; + } return iana_tz_utf8; #elif FIREBASE_PLATFORM_LINUX From cd25bed09c9e351150c3475c5cddc4c7f65b936a Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 10:47:48 -0700 Subject: [PATCH 05/28] Fix scoping error. --- app/src/locale.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index b9442e9805..b5b406e1f6 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -113,8 +113,9 @@ std::string GetTimezone() { // Convert time zone name to wide string std::wstring_convert> to_utf16; + std::wstring windows_tz_utf16; try { - std::wstring windows_tz_utf16 = to_utf16.from_bytes(windows_tz_utf8); + windows_tz_utf16 = to_utf16.from_bytes(windows_tz_utf8); } catch (std::range_error& ex) { LogError("Failed to convert UTF-8 time zone '%s' to UTF-16: %s", windows_tz_utf8, ex.what()); @@ -182,8 +183,9 @@ std::string GetTimezone() { std::wstring iana_tz_utf16(iana_time_zone_buffer); std::wstring_convert, wchar_t> to_utf8; + std::string iana_tz_utf8; try { - std::string iana_tz_utf8 = to_utf8.to_bytes(iana_tz_utf16); + 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()); return ""; From 144e29699d7d55bb56f0e1304713770117ecd49d Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 11:10:31 -0700 Subject: [PATCH 06/28] Convert Windows TZ environment variable from CP-1252 to Unicode. --- app/src/locale.cc | 65 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index b5b406e1f6..0abe01f592 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -92,6 +92,52 @@ std::string GetLocale() { #endif // platform selector } +#if FIREBASE_PLATFORM_WINDOWS +// Conversion table from Windows CP-1252 (aka ISO-8859-1) 1-byte +// encoding to UTF-16. 0xFFFD (Unicode replacement character) is used +// for some values that have no UTF-16 equivalent. +static wchar_t lookup_cp1252_to_utf16[256] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, + 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, + 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, + 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x007E, 0x007F, 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, + 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD, + 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, + 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178, 0x00A0, 0x00A1, + 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, + 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, + 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, + 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, + 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, + 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, + 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, + 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, + 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, + 0x00FC, 0x00FD, 0x00FE, 0x00FF +}; + +static std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { + size_t len = strlen(str_cp1252); + wchar_t str_utf16[len + 1]; + for (int i = 0; i < len + 1; i++) { + str_utf16[i] = lookup_cp1252_to_utf16(str_cp1252[i]); + } + return std::wstring(str_utf16); +} +#endif // FIREBASE_PLATFORM_WINDOWS + // Get the current time zone, e.g. "US/Pacific" std::string GetTimezone() { #if FIREBASE_PLATFORM_WINDOWS @@ -102,24 +148,21 @@ std::string GetTimezone() { tz_was_set = true; } // Get the standard time zone name. - std::string windows_tz_utf8; + std::string windows_tz_cp1252; { size_t length = 0; // get the needed string length if (_get_tzname(&length, nullptr, 0, 0) != 0) return ""; std::vector namebuf(length); if (_get_tzname(&length, &namebuf[0], length, 0) != 0) return ""; - windows_tz_utf8 = std::string(&namebuf[0]); + windows_tz_cp1252 = std::string(&namebuf[0]); } - // Convert time zone name to wide string - std::wstring_convert> to_utf16; - std::wstring windows_tz_utf16; - try { - windows_tz_utf16 = to_utf16.from_bytes(windows_tz_utf8); - } catch (std::range_error& ex) { - LogError("Failed to convert UTF-8 time zone '%s' to UTF-16: %s", - windows_tz_utf8, ex.what()); - return ""; + // Convert time zone name to wide string, then into UTF-8. + std::wstring windows_tz_utf16 = convert_cp1252_to_utf16(windows_tz_cp1252); + std::string windows_tz_utf8; + { + std::wstring_convert, wchar_t> to_utf8; + windows_tz_utf8 = to_utf8.to_bytes(windows_tz_utf16); } std::string locale_name = GetLocale(); From d5d1d8a834657e933fe6bd74c4b8cb33b2e85996 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 11:34:24 -0700 Subject: [PATCH 07/28] Don't use a variable length array. --- app/src/locale.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index 0abe01f592..f91411e170 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -125,16 +125,15 @@ static wchar_t lookup_cp1252_to_utf16[256] = { 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, - 0x00FC, 0x00FD, 0x00FE, 0x00FF -}; + 0x00FC, 0x00FD, 0x00FE, 0x00FF}; static std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { size_t len = strlen(str_cp1252); - wchar_t str_utf16[len + 1]; + std::vector buf_utf16(len + 1); for (int i = 0; i < len + 1; i++) { - str_utf16[i] = lookup_cp1252_to_utf16(str_cp1252[i]); + buf_utf16[i] = lookup_cp1252_to_utf16(str_cp1252[i]); } - return std::wstring(str_utf16); + return std::wstring(&buf_utf16[0]); } #endif // FIREBASE_PLATFORM_WINDOWS From d7c4507218a3fe99c67fa0c5ae6cb4c5745c6563 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 11:35:01 -0700 Subject: [PATCH 08/28] Fix compiler error. --- app/src/locale.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index f91411e170..686dc3b373 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -157,7 +157,7 @@ std::string GetTimezone() { } // Convert time zone name to wide string, then into UTF-8. - std::wstring windows_tz_utf16 = convert_cp1252_to_utf16(windows_tz_cp1252); + std::wstring windows_tz_utf16 = convert_cp1252_to_utf16(windows_tz_cp1252.c_str()); std::string windows_tz_utf8; { std::wstring_convert, wchar_t> to_utf8; From 95fd607d074f8e2bfc9d49858b99cedb270a7377 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 11:37:34 -0700 Subject: [PATCH 09/28] Modify readme. --- release_build_files/readme.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/release_build_files/readme.md b/release_build_files/readme.md index d8c701ebb5..39dbd1f606 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -631,10 +631,7 @@ code. - Changes - Auth (Android): Fixed an issue where VerifyPhoneNumber's internal builder failed to create PhoneAuthOptions with certain compiler settings. - - Remote Config (Desktop): Fix handling of time zones on Windows when - the time zone name in the current system language contains a high-numbered - Unicode code point that cannot be represented in a single UTF-16 - character. + - Remote Config (Desktop): Fixed handling of time zones on Windows. - Storage (Desktop): Fixed a crash on Windows when uploading files from a path containing a high-numbered Unicode code point (above U+FFFF). From 3ebf0a35b56c700dd2fe674b7b6c9919ba4931d8 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 11:38:29 -0700 Subject: [PATCH 10/28] Fix array lookup. --- app/src/locale.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index 686dc3b373..182d73b3fa 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -131,7 +131,7 @@ static std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { size_t len = strlen(str_cp1252); std::vector buf_utf16(len + 1); for (int i = 0; i < len + 1; i++) { - buf_utf16[i] = lookup_cp1252_to_utf16(str_cp1252[i]); + buf_utf16[i] = lookup_cp1252_to_utf16[str_cp1252[i]]; } return std::wstring(&buf_utf16[0]); } From 480579e20325fb2bd522649dcdf1069f6e860b9c Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 12:32:57 -0700 Subject: [PATCH 11/28] Update readme. --- release_build_files/readme.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/release_build_files/readme.md b/release_build_files/readme.md index 39dbd1f606..cc6a52df7a 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -631,9 +631,7 @@ code. - Changes - Auth (Android): Fixed an issue where VerifyPhoneNumber's internal builder failed to create PhoneAuthOptions with certain compiler settings. - - Remote Config (Desktop): Fixed handling of time zones on Windows. - - Storage (Desktop): Fixed a crash on Windows when uploading files from a - path containing a high-numbered Unicode code point (above U+FFFF). + - Remote Config (Desktop): Fixed handling of time zones on Windows, again. ### 11.2.0 - Changes From 5b15bc1d6beb5e9ae66a926016231d6f36e810c3 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 12:52:42 -0700 Subject: [PATCH 12/28] Also fix the fallback daylight saving time string encoding. --- app/src/locale.cc | 65 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index 182d73b3fa..cf07980bd0 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -157,7 +157,8 @@ std::string GetTimezone() { } // Convert time zone name to wide string, then into UTF-8. - std::wstring windows_tz_utf16 = convert_cp1252_to_utf16(windows_tz_cp1252.c_str()); + std::wstring windows_tz_utf16 = + convert_cp1252_to_utf16(windows_tz_cp1252.c_str()); std::string windows_tz_utf8; { std::wstring_convert, wchar_t> to_utf8; @@ -206,34 +207,60 @@ 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, 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) { + // Daylight saving time is active, get a new tzname and convert to UTF-8. size_t length = 0; // get the needed string length - if (_get_tzname(&length, nullptr, 0, 1) != 0) return windows_tz_utf8; + if (_get_tzname(&length, nullptr, 0, 1) != 0) { + // Couldn't get tzname length, return the old name. + return windows_tz_utf8; + } std::vector namebuf(length); - if (_get_tzname(&length, &namebuf[0], length, 1) != 0) + if (_get_tzname(&length, &namebuf[0], length, 1) != 0) { + // Couldn't get tzname, return the old name. return windows_tz_utf8; - windows_tz_utf8 = std::string(&namebuf[0]); + } + windows_tz_cp1252 = std::string(&namebuf[0]); + // Convert time zone name to wide string, then into UTF-8. + windows_tz_utf16 = convert_cp1252_to_utf16(windows_tz_cp1252.c_str()); + { + std::wstring_convert, 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, 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()); - return ""; - } - return iana_tz_utf8; - #elif FIREBASE_PLATFORM_LINUX // If TZ environment variable is defined and not empty, use it, else use // tzname. From 1b4ea64e936795557ee298c6616726196a8d13f5 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 29 Jun 2023 13:38:11 -0700 Subject: [PATCH 13/28] Rephrase readme. --- release_build_files/readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release_build_files/readme.md b/release_build_files/readme.md index cc6a52df7a..06876e0e3e 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -631,7 +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): Fixed handling of time zones on Windows, again. + - Remote Config (Desktop): Additional fix for handling of non-English time + zone names on Windows. ### 11.2.0 - Changes From dafc8ab429f26c2e666eec490ad3f77b8f5e5784 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Fri, 30 Jun 2023 10:36:36 -0700 Subject: [PATCH 14/28] Add unit test for conversions on Windows. --- app/src/locale.cc | 3 ++- app/src/locale.h | 4 ++++ app/tests/locale_test.cc | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index cf07980bd0..294c839fc5 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -127,7 +127,7 @@ static wchar_t lookup_cp1252_to_utf16[256] = { 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF}; -static std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { +std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { size_t len = strlen(str_cp1252); std::vector buf_utf16(len + 1); for (int i = 0; i < len + 1; i++) { @@ -135,6 +135,7 @@ static std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { } return std::wstring(&buf_utf16[0]); } + #endif // FIREBASE_PLATFORM_WINDOWS // Get the current time zone, e.g. "US/Pacific" diff --git a/app/src/locale.h b/app/src/locale.h index bf904f4278..72ca76e1f5 100644 --- a/app/src/locale.h +++ b/app/src/locale.h @@ -30,6 +30,10 @@ std::string GetLocale(); // Get the current time zone, e.g. "US/Pacific" or "EDT". std::string GetTimezone(); +#if FIREBASE_PLATFORM_WINDOWS +std::wstring convert_cp1252_to_utf16(const char* str_cp1252); +#endif // FIREBASE_PLATFORM_WINDOWS + } // namespace internal } // namespace firebase diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index 012ca69523..774d8b4940 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -27,6 +27,7 @@ #else #include +#include #endif // FIREBASE_PLATFORM_WINDOWS namespace firebase { @@ -52,5 +53,41 @@ TEST_F(LocaleTest, TestGetLocale) { EXPECT_NE(loc.find('_'), std::string::npos); } +#if FIREBASE_PLATFORM_WINDOWS + +TEST_F(LocaleTest, TestConvertingStringEncodings) { + // "Mitteleuropäische Zeit €" + const char original_cp1252[] = { + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', + 'o', 'p', 0xe4, 'i', 's', 'c', 'h', 'e', ' ', + 'Z', 'e', 'i', 't', 0x80, '\0' + }; + std::string original_cp1252_str(original_cp1252); + const wchar_t original_utf16[] = L"Mitteleuropäische Zeit €"; + std::wstring original_utf16_str(original_utf16); + + std::wstring cp1252_converted_to_utf16 = + ::firebase::internal::convert_cp1252_to_utf16(original_cp1252_str.c_str()); + EXPECT_EQ(cp1252_converted_to_utf16, original_utf16_str); + + std::wstring_convert, wchar_t> to_utf8; + + const char original_utf8[] = { + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', + 'o', 'p', 0xc3, 0xa4, 'i', 's', 'c', 'h', 'e', ' ', + 'Z', 'e', 'i', 't', ' ', 0xe2, 0x82, 0xac, '\0' + }; + std::string original_utf8_str(original_utf8); + + utf16_converted_to_utf8 = to_utf8.to_bytes(cp1252_converted_to_utf16); + EXPECT_EQ(utf16_converted_to_utf8, original_utf8_str); + + utf8_converted_to_utf16 = to_utf8.from_bytes(utf16_converted_to_utf8); + EXPECT_EQ(utf8_converted_to_utf16, original_utf16_str); +} + +#endif // FIREBASE_PLATFORM_WINDOWS + + } // namespace internal } // namespace firebase From e583195c14d9d6ca7493d8a5a74a0dc24184e139 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Fri, 30 Jun 2023 10:55:03 -0700 Subject: [PATCH 15/28] Add test for CP1252 conversion and fix conversion function that we have a test for it. --- app/src/locale.cc | 41 +++++++++++++++++++++++++++--- app/src/locale.h | 4 +-- app/tests/locale_test.cc | 55 +++++++++++++++++++--------------------- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index 294c839fc5..1c4bb2d83a 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -92,7 +92,40 @@ std::string GetLocale() { #endif // platform selector } -#if FIREBASE_PLATFORM_WINDOWS +// Conversion table from Windows CP-1252 (aka ISO-8859-1) 1-byte +// encoding to UTF-16. 0xFFFD (Unicode replacement character) is used +// for some values that have no UTF-16 equivalent. +static wchar_t lookup_cp1252_to_utf16[256] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, + 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, + 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, + 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x007E, 0x007F, 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, + 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD, + 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, + 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178, 0x00A0, 0x00A1, + 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, + 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, + 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, + 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, + 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, + 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, + 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, + 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, + 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, + 0x00FC, 0x00FD, 0x00FE, 0x00FF}; + // Conversion table from Windows CP-1252 (aka ISO-8859-1) 1-byte // encoding to UTF-16. 0xFFFD (Unicode replacement character) is used // for some values that have no UTF-16 equivalent. @@ -130,14 +163,14 @@ static wchar_t lookup_cp1252_to_utf16[256] = { std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { size_t len = strlen(str_cp1252); std::vector buf_utf16(len + 1); + const unsigned char* unsigned_str_cp1252 = + reinterpret_cast(str_cp1252); for (int i = 0; i < len + 1; i++) { - buf_utf16[i] = lookup_cp1252_to_utf16[str_cp1252[i]]; + buf_utf16[i] = lookup_cp1252_to_utf16[unsigned_str_cp1252[i]]; } return std::wstring(&buf_utf16[0]); } -#endif // FIREBASE_PLATFORM_WINDOWS - // Get the current time zone, e.g. "US/Pacific" std::string GetTimezone() { #if FIREBASE_PLATFORM_WINDOWS diff --git a/app/src/locale.h b/app/src/locale.h index 72ca76e1f5..7b489edc1c 100644 --- a/app/src/locale.h +++ b/app/src/locale.h @@ -30,9 +30,9 @@ std::string GetLocale(); // Get the current time zone, e.g. "US/Pacific" or "EDT". std::string GetTimezone(); -#if FIREBASE_PLATFORM_WINDOWS +#if FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX std::wstring convert_cp1252_to_utf16(const char* str_cp1252); -#endif // FIREBASE_PLATFORM_WINDOWS +#endif // FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX } // namespace internal } // namespace firebase diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index 774d8b4940..74aac508cb 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -16,6 +16,7 @@ #include "app/src/locale.h" +#include #include #include "app/src/include/firebase/internal/platform.h" @@ -23,11 +24,8 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#if FIREBASE_PLATFORM_WINDOWS - -#else +#if !FIREBASE_PLATFORM_WINDOWS #include -#include #endif // FIREBASE_PLATFORM_WINDOWS namespace firebase { @@ -53,41 +51,40 @@ TEST_F(LocaleTest, TestGetLocale) { EXPECT_NE(loc.find('_'), std::string::npos); } -#if FIREBASE_PLATFORM_WINDOWS +#if FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX TEST_F(LocaleTest, TestConvertingStringEncodings) { - // "Mitteleuropäische Zeit €" - const char original_cp1252[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', - 'o', 'p', 0xe4, 'i', 's', 'c', 'h', 'e', ' ', - 'Z', 'e', 'i', 't', 0x80, '\0' - }; - std::string original_cp1252_str(original_cp1252); - const wchar_t original_utf16[] = L"Mitteleuropäische Zeit €"; - std::wstring original_utf16_str(original_utf16); + // "Mitteleuropäische Zeit €" in CP-1252 encoding + const unsigned char original_cp1252_array[] = { + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xe4, 'i', + 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0x80, '\0'}; + std::string original_cp1252( + reinterpret_cast(original_cp1252_array)); + + // "Mitteleuropäische Zeit €" in UTF-16 encoding + const wchar_t original_utf16_array[] = L"Mitteleuropäische Zeit €"; + std::wstring original_utf16(original_utf16_array); std::wstring cp1252_converted_to_utf16 = - ::firebase::internal::convert_cp1252_to_utf16(original_cp1252_str.c_str()); - EXPECT_EQ(cp1252_converted_to_utf16, original_utf16_str); + convert_cp1252_to_utf16(original_cp1252.c_str()); + EXPECT_EQ(cp1252_converted_to_utf16, original_utf16); + const unsigned char original_utf8_array[] = { + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xc3, 0xa4, 'i', + 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0xe2, 0x82, 0xac, '\0'}; + std::string original_utf8(reinterpret_cast(original_utf8_array)); std::wstring_convert, wchar_t> to_utf8; - const char original_utf8[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', - 'o', 'p', 0xc3, 0xa4, 'i', 's', 'c', 'h', 'e', ' ', - 'Z', 'e', 'i', 't', ' ', 0xe2, 0x82, 0xac, '\0' - }; - std::string original_utf8_str(original_utf8); + std::string utf16_converted_to_utf8 = + to_utf8.to_bytes(cp1252_converted_to_utf16); + EXPECT_EQ(utf16_converted_to_utf8, original_utf8); - utf16_converted_to_utf8 = to_utf8.to_bytes(cp1252_converted_to_utf16); - EXPECT_EQ(utf16_converted_to_utf8, original_utf8_str); - - utf8_converted_to_utf16 = to_utf8.from_bytes(utf16_converted_to_utf8); - EXPECT_EQ(utf8_converted_to_utf16, original_utf16_str); + std::wstring utf8_converted_to_utf16 = + to_utf8.from_bytes(utf16_converted_to_utf8); + EXPECT_EQ(utf8_converted_to_utf16, original_utf16); } -#endif // FIREBASE_PLATFORM_WINDOWS - +#endif // FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX } // namespace internal } // namespace firebase From c2bff60520bb7ea2dbfd4c006fdc060d0c1355cf Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Fri, 30 Jun 2023 11:03:22 -0700 Subject: [PATCH 16/28] Remove duplicate code. --- app/src/locale.cc | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index 1c4bb2d83a..ec9d1a54ac 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -92,40 +92,6 @@ std::string GetLocale() { #endif // platform selector } -// Conversion table from Windows CP-1252 (aka ISO-8859-1) 1-byte -// encoding to UTF-16. 0xFFFD (Unicode replacement character) is used -// for some values that have no UTF-16 equivalent. -static wchar_t lookup_cp1252_to_utf16[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, - 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, - 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, - 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, - 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, - 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, - 0x007E, 0x007F, 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, - 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD, - 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, - 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178, 0x00A0, 0x00A1, - 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, - 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, - 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, - 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, - 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, - 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, - 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, - 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, - 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, - 0x00FC, 0x00FD, 0x00FE, 0x00FF}; - // Conversion table from Windows CP-1252 (aka ISO-8859-1) 1-byte // encoding to UTF-16. 0xFFFD (Unicode replacement character) is used // for some values that have no UTF-16 equivalent. From 92106c1be129c8c967309a869db35bf6812449b0 Mon Sep 17 00:00:00 2001 From: jonsimantov Date: Fri, 30 Jun 2023 18:06:11 +0000 Subject: [PATCH 17/28] Add missing platform header. --- app/src/locale.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/locale.h b/app/src/locale.h index 7b489edc1c..e6251fe84d 100644 --- a/app/src/locale.h +++ b/app/src/locale.h @@ -20,6 +20,8 @@ #include +#include "app/src/include/firebase/internal/platform.h" + namespace firebase { namespace internal { From ff97153eb5c191cc3fa0979143b4418ccc2a5a90 Mon Sep 17 00:00:00 2001 From: jonsimantov Date: Fri, 30 Jun 2023 18:12:14 +0000 Subject: [PATCH 18/28] Add additional characters to locale test. --- app/tests/locale_test.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index 74aac508cb..b2ec8b66ec 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -54,15 +54,16 @@ TEST_F(LocaleTest, TestGetLocale) { #if FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX TEST_F(LocaleTest, TestConvertingStringEncodings) { - // "Mitteleuropäische Zeit €" in CP-1252 encoding + // "Mitteleuropäische Zeit € d'été" in CP-1252 encoding const unsigned char original_cp1252_array[] = { 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xe4, 'i', - 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0x80, '\0'}; + 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0x80, ' ', + 'd', '\'', 0xe9, 't', 0xe9, '\0'}; std::string original_cp1252( reinterpret_cast(original_cp1252_array)); // "Mitteleuropäische Zeit €" in UTF-16 encoding - const wchar_t original_utf16_array[] = L"Mitteleuropäische Zeit €"; + const wchar_t original_utf16_array[] = L"Mitteleuropäische Zeit € d'été"; std::wstring original_utf16(original_utf16_array); std::wstring cp1252_converted_to_utf16 = @@ -71,7 +72,8 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { const unsigned char original_utf8_array[] = { 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xc3, 0xa4, 'i', - 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0xe2, 0x82, 0xac, '\0'}; + 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0xe2, 0x82, 0xac, ' ', + 'd', '\'', 0xc3, 0xa9, 't', 0xc3, 0xa9, '\0'}; std::string original_utf8(reinterpret_cast(original_utf8_array)); std::wstring_convert, wchar_t> to_utf8; From c35e9725ddf0e57fb094e93ce45abf6e10366399 Mon Sep 17 00:00:00 2001 From: jonsimantov Date: Fri, 30 Jun 2023 18:18:05 +0000 Subject: [PATCH 19/28] Let's go wild, even more characters. This should cover most of what we need. --- app/tests/locale_test.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index b2ec8b66ec..ab69d9302c 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -54,16 +54,16 @@ TEST_F(LocaleTest, TestGetLocale) { #if FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX TEST_F(LocaleTest, TestConvertingStringEncodings) { - // "Mitteleuropäische Zeit € d'été" in CP-1252 encoding + // "Mitteleuropäische Zeit € d'été ‘Žœ’" in CP-1252 encoding const unsigned char original_cp1252_array[] = { 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xe4, 'i', 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0x80, ' ', - 'd', '\'', 0xe9, 't', 0xe9, '\0'}; + 'd', '\'', 0xe9, 't', 0xe9, ' ', 0x91, 0x8e, 0x9c, 0x92, '\0'}; std::string original_cp1252( reinterpret_cast(original_cp1252_array)); // "Mitteleuropäische Zeit €" in UTF-16 encoding - const wchar_t original_utf16_array[] = L"Mitteleuropäische Zeit € d'été"; + const wchar_t original_utf16_array[] = L"Mitteleuropäische Zeit € d'été ‘Žœ’"; std::wstring original_utf16(original_utf16_array); std::wstring cp1252_converted_to_utf16 = @@ -73,7 +73,8 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { const unsigned char original_utf8_array[] = { 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xc3, 0xa4, 'i', 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0xe2, 0x82, 0xac, ' ', - 'd', '\'', 0xc3, 0xa9, 't', 0xc3, 0xa9, '\0'}; + 'd', '\'', 0xc3, 0xa9, 't', 0xc3, 0xa9, ' ', 0xe2, 0x80, 0x98, + 0xc5, 0xbd, 0xc5, 0x93, 0xe2, 0x80, 0x99, '\0'}; std::string original_utf8(reinterpret_cast(original_utf8_array)); std::wstring_convert, wchar_t> to_utf8; From e58bca112d034b4c5829b70d82d852b2e21b4356 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Fri, 30 Jun 2023 11:54:59 -0700 Subject: [PATCH 20/28] Format code. --- app/tests/locale_test.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index ab69d9302c..2635ae6ac1 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -56,9 +56,9 @@ TEST_F(LocaleTest, TestGetLocale) { TEST_F(LocaleTest, TestConvertingStringEncodings) { // "Mitteleuropäische Zeit € d'été ‘Žœ’" in CP-1252 encoding const unsigned char original_cp1252_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xe4, 'i', - 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0x80, ' ', - 'd', '\'', 0xe9, 't', 0xe9, ' ', 0x91, 0x8e, 0x9c, 0x92, '\0'}; + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xe4, + 'i', 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0x80, + ' ', 'd', '\'', 0xe9, 't', 0xe9, ' ', 0x91, 0x8e, 0x9c, 0x92, '\0'}; std::string original_cp1252( reinterpret_cast(original_cp1252_array)); @@ -71,10 +71,10 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { EXPECT_EQ(cp1252_converted_to_utf16, original_utf16); const unsigned char original_utf8_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xc3, 0xa4, 'i', - 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0xe2, 0x82, 0xac, ' ', - 'd', '\'', 0xc3, 0xa9, 't', 0xc3, 0xa9, ' ', 0xe2, 0x80, 0x98, - 0xc5, 0xbd, 0xc5, 0x93, 0xe2, 0x80, 0x99, '\0'}; + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xc3, + 0xa4, 'i', 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', + 0xe2, 0x82, 0xac, ' ', 'd', '\'', 0xc3, 0xa9, 't', 0xc3, 0xa9, ' ', + 0xe2, 0x80, 0x98, 0xc5, 0xbd, 0xc5, 0x93, 0xe2, 0x80, 0x99, '\0'}; std::string original_utf8(reinterpret_cast(original_utf8_array)); std::wstring_convert, wchar_t> to_utf8; From a6f62a4f1f26ad7f588e1bf333fa9fd58f97f985 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 5 Jul 2023 14:11:19 -0700 Subject: [PATCH 21/28] Modified locale test to work with Windows wchar_t. --- app/tests/locale_test.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index 2635ae6ac1..a714a7b109 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -63,8 +63,13 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { reinterpret_cast(original_cp1252_array)); // "Mitteleuropäische Zeit €" in UTF-16 encoding - const wchar_t original_utf16_array[] = L"Mitteleuropäische Zeit € d'été ‘Žœ’"; - std::wstring original_utf16(original_utf16_array); + const wchar_t original_utf16_array[] = { + 'M','i','t','t','e','l','e','u','r','o','p',0x00E4, + 'i','s','c','h','e',' ','Z','e','i','t',' ',0x20AC, + ' ','d','\'',0x00E9,'t',0x00E9,' ',0x2018,0x17D,0x153,0x2019, + '\0'}; + std::wstring original_utf16(reinterpret_cast(original_utf16_array)); + std::wstring cp1252_converted_to_utf16 = convert_cp1252_to_utf16(original_cp1252.c_str()); From bfe6d44c54344361149ba0653c79ecc312ec36e2 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 5 Jul 2023 14:12:16 -0700 Subject: [PATCH 22/28] Format code. --- app/tests/locale_test.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index a714a7b109..06765e3dba 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -63,13 +63,13 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { reinterpret_cast(original_cp1252_array)); // "Mitteleuropäische Zeit €" in UTF-16 encoding - const wchar_t original_utf16_array[] = { - 'M','i','t','t','e','l','e','u','r','o','p',0x00E4, - 'i','s','c','h','e',' ','Z','e','i','t',' ',0x20AC, - ' ','d','\'',0x00E9,'t',0x00E9,' ',0x2018,0x17D,0x153,0x2019, - '\0'}; - std::wstring original_utf16(reinterpret_cast(original_utf16_array)); - + const wchar_t original_utf16_array[] = { + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', + 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', + 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', + 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x17D, 0x153, 0x2019, '\0'}; + std::wstring original_utf16( + reinterpret_cast(original_utf16_array)); std::wstring cp1252_converted_to_utf16 = convert_cp1252_to_utf16(original_cp1252.c_str()); From 18bb49476ede8f15fcfe74a4c9f7334655de3f04 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 5 Jul 2023 14:13:13 -0700 Subject: [PATCH 23/28] Format code 2 --- app/tests/locale_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index 06765e3dba..e519c60440 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -64,10 +64,10 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { // "Mitteleuropäische Zeit €" in UTF-16 encoding const wchar_t original_utf16_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', - 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', - 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', - 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x17D, 0x153, 0x2019, '\0'}; + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', + 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', + 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', + 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x017D, 0x0153, 0x2019, '\0'}; std::wstring original_utf16( reinterpret_cast(original_utf16_array)); From 12be58fdaf99fa3a8b52253ea4789e0152f80b0c Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 5 Jul 2023 14:20:03 -0700 Subject: [PATCH 24/28] Format code 3 --- app/tests/locale_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index e519c60440..b4ac5906bb 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -64,10 +64,10 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { // "Mitteleuropäische Zeit €" in UTF-16 encoding const wchar_t original_utf16_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', - 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', - 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', - 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x017D, 0x0153, 0x2019, '\0'}; + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', + 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', + 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', + 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x017D, 0x0153, 0x2019, '\0'}; std::wstring original_utf16( reinterpret_cast(original_utf16_array)); From e1c2b688e6b0e8dde2064676ad0d65b412d3d081 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 5 Jul 2023 15:25:27 -0700 Subject: [PATCH 25/28] Format --- app/tests/locale_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index e519c60440..b4ac5906bb 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -64,10 +64,10 @@ TEST_F(LocaleTest, TestConvertingStringEncodings) { // "Mitteleuropäische Zeit €" in UTF-16 encoding const wchar_t original_utf16_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', - 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', - 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', - 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x017D, 0x0153, 0x2019, '\0'}; + 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', + 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', + 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', + 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x017D, 0x0153, 0x2019, '\0'}; std::wstring original_utf16( reinterpret_cast(original_utf16_array)); From dfd800122d54a60e9fd447e2946f335ea021b608 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Thu, 6 Jul 2023 01:08:53 +0200 Subject: [PATCH 26/28] Set thread language to English and use Use GetTimeZoneInformation. --- app/src/locale.cc | 94 ++++++++++------------------------------ app/src/locale.h | 4 -- app/tests/locale_test.cc | 55 +++++++---------------- 3 files changed, 38 insertions(+), 115 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index ec9d1a54ac..8d25ab116c 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -42,6 +42,8 @@ #include #include +#include "app/src/thread.h" + namespace firebase { namespace internal { @@ -92,73 +94,34 @@ std::string GetLocale() { #endif // platform selector } -// Conversion table from Windows CP-1252 (aka ISO-8859-1) 1-byte -// encoding to UTF-16. 0xFFFD (Unicode replacement character) is used -// for some values that have no UTF-16 equivalent. -static wchar_t lookup_cp1252_to_utf16[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, - 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, - 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, - 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, - 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, - 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, - 0x007E, 0x007F, 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, - 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD, - 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, - 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178, 0x00A0, 0x00A1, - 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, - 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, - 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, - 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, - 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, - 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, - 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, - 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, - 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, - 0x00FC, 0x00FD, 0x00FE, 0x00FF}; - -std::wstring convert_cp1252_to_utf16(const char* str_cp1252) { - size_t len = strlen(str_cp1252); - std::vector buf_utf16(len + 1); - const unsigned char* unsigned_str_cp1252 = - reinterpret_cast(str_cp1252); - for (int i = 0; i < len + 1; i++) { - buf_utf16[i] = lookup_cp1252_to_utf16[unsigned_str_cp1252[i]]; - } - return std::wstring(&buf_utf16[0]); +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; } // Get the current time zone, e.g. "US/Pacific" std::string GetTimezone() { #if FIREBASE_PLATFORM_WINDOWS static bool tz_was_set = false; - if (!tz_was_set) { +if (!tz_was_set) { _tzset(); // Set the time zone used by the below functions, based on OS // settings or the TZ variable, as appropriate. tz_was_set = true; } - // Get the standard time zone name. - std::string windows_tz_cp1252; - { - size_t length = 0; // get the needed string length - if (_get_tzname(&length, nullptr, 0, 0) != 0) return ""; - std::vector namebuf(length); - if (_get_tzname(&length, &namebuf[0], length, 0) != 0) return ""; - windows_tz_cp1252 = std::string(&namebuf[0]); - } - - // Convert time zone name to wide string, then into UTF-8. - std::wstring windows_tz_utf16 = - convert_cp1252_to_utf16(windows_tz_cp1252.c_str()); + + std::wstring windows_tz_utf16 = GetWindowsTimezoneInEnglish(0); std::string windows_tz_utf8; { std::wstring_convert, wchar_t> to_utf8; @@ -238,21 +201,8 @@ std::string GetTimezone() { // Couldn't determine daylight saving time, return the old name. return windows_tz_utf8; } - if (daylight) { - // Daylight saving time is active, get a new tzname and convert to UTF-8. - size_t length = 0; // get the needed string length - if (_get_tzname(&length, nullptr, 0, 1) != 0) { - // Couldn't get tzname length, return the old name. - return windows_tz_utf8; - } - std::vector namebuf(length); - if (_get_tzname(&length, &namebuf[0], length, 1) != 0) { - // Couldn't get tzname, return the old name. - return windows_tz_utf8; - } - windows_tz_cp1252 = std::string(&namebuf[0]); - // Convert time zone name to wide string, then into UTF-8. - windows_tz_utf16 = convert_cp1252_to_utf16(windows_tz_cp1252.c_str()); + if (daylight) { + windows_tz_utf16 = GetWindowsTimezoneInEnglish(daylight); { std::wstring_convert, wchar_t> to_utf8; windows_tz_utf8 = to_utf8.to_bytes(windows_tz_utf16); diff --git a/app/src/locale.h b/app/src/locale.h index e6251fe84d..4cf6b4240f 100644 --- a/app/src/locale.h +++ b/app/src/locale.h @@ -32,10 +32,6 @@ std::string GetLocale(); // Get the current time zone, e.g. "US/Pacific" or "EDT". std::string GetTimezone(); -#if FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX -std::wstring convert_cp1252_to_utf16(const char* str_cp1252); -#endif // FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX - } // namespace internal } // namespace firebase diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index e519c60440..efffb4a75f 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -24,7 +24,9 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#if !FIREBASE_PLATFORM_WINDOWS +#if FIREBASE_PLATFORM_WINDOWS +#include +#else #include #endif // FIREBASE_PLATFORM_WINDOWS @@ -51,48 +53,23 @@ TEST_F(LocaleTest, TestGetLocale) { EXPECT_NE(loc.find('_'), std::string::npos); } -#if FIREBASE_PLATFORM_WINDOWS || FIREBASE_PLATFORM_LINUX +#if FIREBASE_PLATFORM_WINDOWS -TEST_F(LocaleTest, TestConvertingStringEncodings) { - // "Mitteleuropäische Zeit € d'été ‘Žœ’" in CP-1252 encoding - const unsigned char original_cp1252_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xe4, - 'i', 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', 0x80, - ' ', 'd', '\'', 0xe9, 't', 0xe9, ' ', 0x91, 0x8e, 0x9c, 0x92, '\0'}; - std::string original_cp1252( - reinterpret_cast(original_cp1252_array)); +TEST_F(LocaleTest, TestTimeZoneNameInEnglish) { + LANGID prev_lang = GetThreadUILanguage(); - // "Mitteleuropäische Zeit €" in UTF-16 encoding - const wchar_t original_utf16_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', - 'o', 'p', 0x00E4, 'i', 's', 'c', 'h', 'e', ' ', - 'Z', 'e', 'i', 't', ' ', 0x20AC, ' ', 'd', '\'', - 0x00E9, 't', 0x00E9, ' ', 0x2018, 0x017D, 0x0153, 0x2019, '\0'}; - std::wstring original_utf16( - reinterpret_cast(original_utf16_array)); - - std::wstring cp1252_converted_to_utf16 = - convert_cp1252_to_utf16(original_cp1252.c_str()); - EXPECT_EQ(cp1252_converted_to_utf16, original_utf16); - - const unsigned char original_utf8_array[] = { - 'M', 'i', 't', 't', 'e', 'l', 'e', 'u', 'r', 'o', 'p', 0xc3, - 0xa4, 'i', 's', 'c', 'h', 'e', ' ', 'Z', 'e', 'i', 't', ' ', - 0xe2, 0x82, 0xac, ' ', 'd', '\'', 0xc3, 0xa9, 't', 0xc3, 0xa9, ' ', - 0xe2, 0x80, 0x98, 0xc5, 0xbd, 0xc5, 0x93, 0xe2, 0x80, 0x99, '\0'}; - std::string original_utf8(reinterpret_cast(original_utf8_array)); - std::wstring_convert, wchar_t> to_utf8; - - std::string utf16_converted_to_utf8 = - to_utf8.to_bytes(cp1252_converted_to_utf16); - EXPECT_EQ(utf16_converted_to_utf8, original_utf8); - - std::wstring utf8_converted_to_utf16 = - to_utf8.from_bytes(utf16_converted_to_utf8); - EXPECT_EQ(utf8_converted_to_utf16, original_utf16); + 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 || FIREBASE_PLATFORM_LINUX +#endif // FIREBASE_PLATFORM_WINDOWS } // namespace internal } // namespace firebase From 5d0c920668abb42d15329b3efad3a4201c1909ce Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 5 Jul 2023 16:11:09 -0700 Subject: [PATCH 27/28] Format code. --- app/src/locale.cc | 30 ++++++++++++++++-------------- app/tests/locale_test.cc | 8 ++++---- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/app/src/locale.cc b/app/src/locale.cc index 8d25ab116c..94accb96d5 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -96,18 +96,20 @@ std::string GetLocale() { std::wstring GetWindowsTimezoneInEnglish(int daylight) { struct TzNames { - std::wstring standard; - std::wstring daylight; + 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 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; } @@ -115,12 +117,12 @@ std::wstring GetWindowsTimezoneInEnglish(int daylight) { std::string GetTimezone() { #if FIREBASE_PLATFORM_WINDOWS static bool tz_was_set = false; -if (!tz_was_set) { + if (!tz_was_set) { _tzset(); // Set the time zone used by the below functions, based on OS // settings or the TZ variable, as appropriate. tz_was_set = true; } - + std::wstring windows_tz_utf16 = GetWindowsTimezoneInEnglish(0); std::string windows_tz_utf8; { @@ -201,8 +203,8 @@ if (!tz_was_set) { // Couldn't determine daylight saving time, return the old name. return windows_tz_utf8; } - if (daylight) { - windows_tz_utf16 = GetWindowsTimezoneInEnglish(daylight); + if (daylight) { + windows_tz_utf16 = GetWindowsTimezoneInEnglish(daylight); { std::wstring_convert, wchar_t> to_utf8; windows_tz_utf8 = to_utf8.to_bytes(windows_tz_utf16); diff --git a/app/tests/locale_test.cc b/app/tests/locale_test.cc index efffb4a75f..ce809afc40 100644 --- a/app/tests/locale_test.cc +++ b/app/tests/locale_test.cc @@ -59,13 +59,13 @@ TEST_F(LocaleTest, TestTimeZoneNameInEnglish) { LANGID prev_lang = GetThreadUILanguage(); SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); - std::string timezone_english = GetTimezone(); - + 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); } From 127386774f1642c2c8ee281f754177ca1f3a59e2 Mon Sep 17 00:00:00 2001 From: Jon Simantov Date: Wed, 5 Jul 2023 16:32:13 -0700 Subject: [PATCH 28/28] Add a comment about why we don't use daylight savings time in one spot. --- app/src/locale.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/locale.cc b/app/src/locale.cc index 94accb96d5..887733268b 100644 --- a/app/src/locale.cc +++ b/app/src/locale.cc @@ -94,6 +94,7 @@ std::string GetLocale() { #endif // platform selector } +#if FIREBASE_PLATFORM_WINDOWS std::wstring GetWindowsTimezoneInEnglish(int daylight) { struct TzNames { std::wstring standard; @@ -112,6 +113,7 @@ std::wstring GetWindowsTimezoneInEnglish(int daylight) { return daylight ? tz_names.daylight : tz_names.standard; } +#endif // FIREBASE_PLATFORM_WINDOWS // Get the current time zone, e.g. "US/Pacific" std::string GetTimezone() { @@ -123,6 +125,9 @@ std::string GetTimezone() { tz_was_set = true; } + // 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; {