Skip to content

Commit e44c994

Browse files
authored
Modify heartbeat local storage to use wide strings on Windows. (#1313)
* Modify heartbeat local storage to use wide strings on Windows. * Fix macro. * Fix heartbeat test that uses filename. * Format code. * More format. * Fix build error. * Clean up GetFilename code. * For debugging, add an international path to Windows runs. * Fix Mkdir. * Disable the i18n characters. * Change codecvt use. * Move heartbeats to a unique subdirectory. * Move international characters. * Ensure that the bug actually happens without the fix. * Fix heartbeat path - and undo the international characters. * Revert "Ensure that the bug actually happens without the fix." This reverts commit cc6c164. * Format code.
1 parent 68bc894 commit e44c994

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

app/src/app_desktop.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,12 @@ App* App::Create(const AppOptions& options, const char* name) { // NOLINT
143143
app = new App();
144144
app->name_ = name;
145145
app->options_ = options_with_defaults;
146+
std::string unique_name =
147+
std::string(app->options_.package_name()) + "." + app->name_;
146148
app = app_common::AddApp(app, &app->init_results_);
147149
app->internal_->heartbeat_controller_ =
148150
std::make_shared<heartbeat::HeartbeatController>(
149-
name, *app_common::FindAppLoggerByName(name),
151+
unique_name, *app_common::FindAppLoggerByName(name),
150152
app->internal_->date_provider_);
151153
#ifndef SWIG
152154
// Log a heartbeat after creating an App. In the Unity SDK this will happen

app/src/heartbeat/heartbeat_storage_desktop.cc

+25-7
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
#include "app/src/heartbeat/heartbeat_storage_desktop.h"
1818

19+
#include <codecvt>
1920
#include <fstream>
21+
#include <locale>
2022
#include <regex>
23+
#include <string>
2124
#include <vector>
2225

2326
#include "app/logged_heartbeats_generated.h"
@@ -41,23 +44,36 @@ namespace {
4144
const char kHeartbeatDir[] = "firebase-heartbeat";
4245
const char kHeartbeatFilenamePrefix[] = "heartbeats-";
4346

47+
#if FIREBASE_PLATFORM_WINDOWS
48+
std::wstring CreateFilename(const std::string& app_id, const Logger& logger) {
49+
const std::wstring empty_string;
50+
#else
4451
std::string CreateFilename(const std::string& app_id, const Logger& logger) {
52+
const std::string empty_string;
53+
#endif // FIREBASE_PLATFORM_WINDOWS
4554
std::string error;
4655
std::string app_dir =
4756
AppDataDir(kHeartbeatDir, /*should_create=*/true, &error);
4857
if (!error.empty()) {
4958
logger.LogError(error.c_str());
50-
return "";
59+
return empty_string;
5160
}
5261
if (app_dir.empty()) {
53-
return "";
62+
return empty_string;
5463
}
5564

5665
// Remove any symbols from app_id that might not be allowed in filenames.
5766
auto app_id_without_symbols =
5867
std::regex_replace(app_id, std::regex("[/\\\\?%*:|\"<>.,;=]"), "");
5968
// Note: fstream will convert / to \ if needed on windows.
60-
return app_dir + "/" + kHeartbeatFilenamePrefix + app_id_without_symbols;
69+
std::string final_path_utf8 =
70+
app_dir + "/" + kHeartbeatFilenamePrefix + app_id_without_symbols;
71+
#if FIREBASE_PLATFORM_WINDOWS
72+
std::wstring_convert<std::codecvt_utf8<wchar_t>> final_path_w;
73+
return final_path_w.from_bytes(final_path_utf8);
74+
#else
75+
return final_path_utf8;
76+
#endif
6177
}
6278

6379
} // namespace
@@ -113,6 +129,12 @@ bool HeartbeatStorageDesktop::ReadTo(LoggedHeartbeats& heartbeats_output) {
113129
return true;
114130
}
115131

132+
#if FIREBASE_PLATFORM_WINDOWS
133+
std::wstring HeartbeatStorageDesktop::GetFilename() const { return filename_; }
134+
#else
135+
std::string HeartbeatStorageDesktop::GetFilename() const { return filename_; }
136+
#endif // FIREBASE_PLATFORM_WINDOWS
137+
116138
bool HeartbeatStorageDesktop::Write(const LoggedHeartbeats& heartbeats) const {
117139
// Clear the file before writing.
118140
std::ofstream file(filename_, std::ios_base::trunc | std::ios_base::binary);
@@ -127,10 +149,6 @@ bool HeartbeatStorageDesktop::Write(const LoggedHeartbeats& heartbeats) const {
127149
return !file.fail();
128150
}
129151

130-
const char* HeartbeatStorageDesktop::GetFilename() const {
131-
return filename_.c_str();
132-
}
133-
134152
LoggedHeartbeats HeartbeatStorageDesktop::LoggedHeartbeatsFromFlatbuffer(
135153
const LoggedHeartbeatsFlatbuffer& heartbeats_fb) const {
136154
LoggedHeartbeats heartbeats_struct;

app/src/heartbeat/heartbeat_storage_desktop.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <vector>
2424

2525
#include "app/logged_heartbeats_generated.h"
26+
#include "app/src/include/firebase/internal/platform.h"
2627
#include "app/src/logger.h"
2728

2829
namespace firebase {
@@ -52,7 +53,13 @@ class HeartbeatStorageDesktop {
5253
// write operation fails.
5354
bool Write(const LoggedHeartbeats& heartbeats) const;
5455

55-
const char* GetFilename() const;
56+
#if FIREBASE_PLATFORM_WINDOWS
57+
// Use a wide string on Windows, to support international characters in the
58+
// path.
59+
std::wstring GetFilename() const;
60+
#else
61+
std::string GetFilename() const;
62+
#endif // FIREBASE_PLATFORM_WINDOWS
5663

5764
private:
5865
LoggedHeartbeats LoggedHeartbeatsFromFlatbuffer(
@@ -61,7 +68,13 @@ class HeartbeatStorageDesktop {
6168
const LoggedHeartbeats& heartbeats_struct) const;
6269

6370
// local variables for state
71+
#if FIREBASE_PLATFORM_WINDOWS
72+
// Use a wide string on Windows, to support international characters in the
73+
// path.
74+
std::wstring filename_;
75+
#else
6476
std::string filename_;
77+
#endif // FIREBASE_PLATFORM_WINDOWS
6578
const Logger& logger_;
6679
};
6780

app/tests/heartbeat_storage_desktop_test.cc

+8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "app/logged_heartbeats_generated.h"
2424
#include "app/src/filesystem.h"
25+
#include "app/src/include/firebase/internal/platform.h"
2526
#include "gtest/gtest.h"
2627

2728
namespace firebase {
@@ -129,10 +130,17 @@ TEST_F(HeartbeatStorageDesktopTest, ReadNonexistentFile) {
129130
TEST_F(HeartbeatStorageDesktopTest, FilenameIgnoresSymbolsInAppId) {
130131
std::string app_id = "idstart/\\?%*:|\"<>.,;=idend";
131132
HeartbeatStorageDesktop storage = HeartbeatStorageDesktop(app_id, logger_);
133+
#if FIREBASE_PLATFORM_WINDOWS
134+
std::wstring filename = storage.GetFilename();
135+
// Verify that the actual filename contains the non-symbol characters in
136+
// app_id.
137+
EXPECT_TRUE(filename.find(L"idstartidend") != std::string::npos) << filename;
138+
#else
132139
std::string filename = storage.GetFilename();
133140
// Verify that the actual filename contains the non-symbol characters in
134141
// app_id.
135142
EXPECT_TRUE(filename.find("idstartidend") != std::string::npos) << filename;
143+
#endif
136144
}
137145

138146
TEST_F(HeartbeatStorageDesktopTest, ReadCorruptedData) {

0 commit comments

Comments
 (0)