Skip to content

Commit 24398f9

Browse files
committed
Merge remote-tracking branch 'origin/rename-libraryPath-param' into analytics-dll-secure
2 parents 619224f + 903d0ef commit 24398f9

File tree

1 file changed

+66
-10
lines changed

1 file changed

+66
-10
lines changed

analytics/src/analytics_windows.cc

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,60 @@
2121
#include <cstring> // For memcmp
2222
#include <string> // Required for std::wstring
2323
#include <vector>
24-
25-
#include "app/src/log.h"
24+
#include <string> // Required for std::wstring
25+
#include <cstdlib> // Required for _wpgmptr
26+
#include <cstring> // For memcmp
27+
#include "app/src/log.h" //NOLINT
2628

2729
namespace firebase {
2830
namespace analytics {
2931
namespace internal {
3032

33+
// Helper function to retrieve the full path of the current executable.
34+
// Returns an empty string on failure.
35+
static std::wstring GetExecutablePath() {
36+
std::wstring executable_path_str;
37+
wchar_t* wpgmptr_val = nullptr;
38+
39+
// Prefer _get_wpgmptr()
40+
errno_t err_w = _get_wpgmptr(&wpgmptr_val);
41+
if (err_w == 0 && wpgmptr_val != nullptr && wpgmptr_val[0] != L'\0') {
42+
executable_path_str = wpgmptr_val;
43+
} else {
44+
// Fallback to _get_pgmptr() and convert to wide string
45+
char* pgmptr_val = nullptr;
46+
errno_t err_c = _get_pgmptr(&pgmptr_val);
47+
if (err_c == 0 && pgmptr_val != nullptr && pgmptr_val[0] != '\0') {
48+
// Convert narrow string to wide string using CP_ACP (system default ANSI code page)
49+
int wide_char_count = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, pgmptr_val, -1, NULL, 0);
50+
if (wide_char_count == 0) { // Failure if count is 0
51+
DWORD conversion_error = GetLastError();
52+
LogError("GetExecutablePath: MultiByteToWideChar failed to calculate size for _get_pgmptr path. Error: %u", conversion_error);
53+
return L"";
54+
}
55+
56+
std::vector<wchar_t> wide_path_buffer(wide_char_count);
57+
if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, pgmptr_val, -1, wide_path_buffer.data(), wide_char_count) == 0) {
58+
DWORD conversion_error = GetLastError();
59+
LogError("GetExecutablePath: MultiByteToWideChar failed to convert _get_pgmptr path. Error: %u", conversion_error);
60+
return L"";
61+
}
62+
executable_path_str = wide_path_buffer.data();
63+
} else {
64+
// Both _get_wpgmptr and _get_pgmptr failed or returned empty/null
65+
LogError("GetExecutablePath: Failed to retrieve executable path using both _get_wpgmptr (err: %d) and _get_pgmptr (err: %d).", err_w, err_c);
66+
return L"";
67+
}
68+
}
69+
70+
// Safeguard if path somehow resolved to empty despite initial checks.
71+
if (executable_path_str.empty()) {
72+
LogError("GetExecutablePath: Executable path resolved to an empty string.");
73+
return L"";
74+
}
75+
return executable_path_str;
76+
}
77+
3178
// Helper function to calculate SHA256 hash of a file.
3279
static std::vector<BYTE> CalculateFileSha256(HANDLE hFile) {
3380
HCRYPTPROV hProv = 0;
@@ -129,13 +176,6 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
129176
LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
130177
}
131178

132-
// Get full path to the executable using _wpgmptr.
133-
// This global variable is provided by the CRT and is expected to be available
134-
// on Windows.
135-
if (_wpgmptr == nullptr || _wpgmptr[0] == L'\0') {
136-
LogError("VerifyAndLoadAnalyticsLibrary: Can't determine executable path.");
137-
return nullptr;
138-
}
139179
std::wstring executable_path_str(_wpgmptr);
140180

141181
size_t last_slash_pos = executable_path_str.find_last_of(L"\\");
@@ -145,7 +185,23 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
145185
return nullptr;
146186
}
147187

148-
std::wstring full_dll_path_str =
188+
std::wstring executable_path_str = GetExecutablePath();
189+
190+
if (executable_path_str.empty()) {
191+
// GetExecutablePath() is expected to log specific errors.
192+
// This log indicates the failure to proceed within this function.
193+
LogError("VerifyAndLoadAnalyticsLibrary: Failed to determine executable path via GetExecutablePath(), cannot proceed.");
194+
return nullptr;
195+
}
196+
197+
size_t last_slash_pos = executable_path_str.find_last_of(L"\\");
198+
if (last_slash_pos == std::wstring::npos) {
199+
// Log message updated to avoid using %ls for executable_path_str
200+
LogError("VerifyAndLoadAnalyticsLibrary: Could not determine executable directory from retrieved path (no backslash found).");
201+
return nullptr;
202+
}
203+
204+
std::wstring full_dll_path_str =
149205
executable_path_str.substr(0, last_slash_pos + 1);
150206
full_dll_path_str += library_filename; // library_filename is the filename
151207

0 commit comments

Comments
 (0)