From 608147484edc0c1eeb9e98427c82d4b34f64cc92 Mon Sep 17 00:00:00 2001 From: "dcamp%mozilla.com" Date: Wed, 25 Jul 2007 01:07:08 +0000 Subject: [PATCH] Handle non-ascii filenames in the crash reporter. b=382508, r=luser --- .../crashreporter/client/crashreporter.cpp | 31 ++++++++++---- toolkit/crashreporter/client/crashreporter.h | 6 +++ .../client/crashreporter_linux.cpp | 11 +++++ .../crashreporter/client/crashreporter_osx.mm | 10 +++++ .../client/crashreporter_win.cpp | 42 ++++++++++++++++++- 5 files changed, 90 insertions(+), 10 deletions(-) diff --git a/toolkit/crashreporter/client/crashreporter.cpp b/toolkit/crashreporter/client/crashreporter.cpp index 82b5b30443f..d9a51f6ede5 100644 --- a/toolkit/crashreporter/client/crashreporter.cpp +++ b/toolkit/crashreporter/client/crashreporter.cpp @@ -151,10 +151,15 @@ bool ReadStringsFromFile(const string& path, StringTable& strings, bool unescape) { - ifstream f(path.c_str(), std::ios::in); - if (!f.is_open()) return false; + ifstream* f = UIOpenRead(path); + bool success = false; + if (f->is_open()) { + success = ReadStrings(*f, strings, unescape); + } - return ReadStrings(f, strings, unescape); + f->close(); + delete f; + return success; } bool WriteStrings(ostream& out, @@ -183,10 +188,15 @@ bool WriteStringsToFile(const string& path, StringTable& strings, bool escape) { - ofstream f(path.c_str(), std::ios::out); - if (!f.is_open()) return false; + ofstream* f = UIOpenWrite(path.c_str()); + bool success = false; + if (f->is_open()) { + success = WriteStrings(*f, header, strings, escape); + } - return WriteStrings(f, header, strings, escape); + f->close(); + delete f; + return success; } static bool ReadConfig() @@ -455,9 +465,14 @@ int main(int argc, char** argv) #if defined(XP_WIN) && !defined(__GNUC__) // We need WinMain in order to not be a console app. This function is unused // if we are a console application. -int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR args, int ) +int WINAPI wWinMain( HINSTANCE, HINSTANCE, LPSTR args, int ) { + char** argv = static_cast(malloc(__argc * sizeof(char*))); + for (int i = 0; i < __argc; i++) { + argv[i] = strdup(WideToUTF8(__wargv[i]).c_str()); + } + // Do the real work. - return main(__argc, __argv); + return main(__argc, argv); } #endif diff --git a/toolkit/crashreporter/client/crashreporter.h b/toolkit/crashreporter/client/crashreporter.h index ec7fe469e55..aaac7fb9080 100644 --- a/toolkit/crashreporter/client/crashreporter.h +++ b/toolkit/crashreporter/client/crashreporter.h @@ -13,13 +13,17 @@ #include #include #include +#include #if defined(XP_WIN32) #include + #define UI_SNPRINTF _snprintf #define UI_DIR_SEPARATOR "\\" +std::string WideToUTF8(const std::wstring& wide, bool* success = 0); + #else #define UI_SNPRINTF snprintf @@ -113,6 +117,8 @@ bool UIEnsurePathExists(const std::string& path); bool UIFileExists(const std::string& path); bool UIMoveFile(const std::string& oldfile, const std::string& newfile); bool UIDeleteFile(const std::string& oldfile); +std::ifstream* UIOpenRead(const std::string& filename); +std::ofstream* UIOpenWrite(const std::string& filename); #ifdef _MSC_VER # pragma warning( pop ) diff --git a/toolkit/crashreporter/client/crashreporter_linux.cpp b/toolkit/crashreporter/client/crashreporter_linux.cpp index d47151006cf..b38d0cd2567 100644 --- a/toolkit/crashreporter/client/crashreporter_linux.cpp +++ b/toolkit/crashreporter/client/crashreporter_linux.cpp @@ -496,3 +496,14 @@ bool UIDeleteFile(const string& file) { return (unlink(file.c_str()) != -1); } + +std::ifstream* UIOpenRead(const string& filename) +{ + return new std::ifstream(filename.c_str(), std::ios::in); +} + +std::ofstream* UIOpenWrite(const string& filename) +{ + return new std::ofstream(filename.c_str(), std::ios::out); +} + diff --git a/toolkit/crashreporter/client/crashreporter_osx.mm b/toolkit/crashreporter/client/crashreporter_osx.mm index 1cbb2a2a398..b9eccedb75f 100644 --- a/toolkit/crashreporter/client/crashreporter_osx.mm +++ b/toolkit/crashreporter/client/crashreporter_osx.mm @@ -522,3 +522,13 @@ bool UIDeleteFile(const string& file) { return (unlink(file.c_str()) != -1); } + +std::ifstream* UIOpenRead(const string& filename) +{ + return new std::ifstream(filename.c_str(), std::ios::in); +} + +std::ofstream* UIOpenWrite(const string& filename) +{ + return new std::ofstream(filename.c_str(), std::ios::out); +} diff --git a/toolkit/crashreporter/client/crashreporter_win.cpp b/toolkit/crashreporter/client/crashreporter_win.cpp index 14f7aaf85a1..a92f63661f2 100644 --- a/toolkit/crashreporter/client/crashreporter_win.cpp +++ b/toolkit/crashreporter/client/crashreporter_win.cpp @@ -67,6 +67,9 @@ using std::wstring; using std::map; using std::vector; using std::set; +using std::ios; +using std::ifstream; +using std::ofstream; using namespace CrashReporter; @@ -100,7 +103,6 @@ static const UINT kDefaultAttachedBottom[] = { }; static wstring UTF8ToWide(const string& utf8, bool *success = 0); -static string WideToUTF8(const wstring& wide, bool *success = 0); static DWORD WINAPI SendThreadProc(LPVOID param); static wstring Str(const char* key) @@ -627,7 +629,7 @@ static wstring UTF8ToWide(const string& utf8, bool *success) return str; } -static string WideToUTF8(const wstring& wide, bool *success) +string WideToUTF8(const wstring& wide, bool* success) { char* buffer = NULL; int buffer_size = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), @@ -784,3 +786,39 @@ bool UIDeleteFile(const string& oldfile) { return DeleteFile(UTF8ToWide(oldfile).c_str()) == TRUE; } + +ifstream* UIOpenRead(const string& filename) +{ + // adapted from breakpad's src/common/windows/http_upload.cc + + // The "open" method on pre-MSVC8 ifstream implementations doesn't accept a + // wchar_t* filename, so use _wfopen directly in that case. For VC8 and + // later, _wfopen has been deprecated in favor of _wfopen_s, which does + // not exist in earlier versions, so let the ifstream open the file itself. +#if _MSC_VER >= 1400 // MSVC 2005/8 + ifstream* file = new ifstream(); + file->open(UTF8ToWide(filename).c_str(), ios::in); +#else // _MSC_VER >= 1400 + ifstream* file = new ifstream(_wfopen(UTF8ToWide(filename).c_str(), L"r")); +#endif // _MSC_VER >= 1400 + + return file; +} + +ofstream* UIOpenWrite(const string& filename) +{ + // adapted from breakpad's src/common/windows/http_upload.cc + + // The "open" method on pre-MSVC8 ifstream implementations doesn't accept a + // wchar_t* filename, so use _wfopen directly in that case. For VC8 and + // later, _wfopen has been deprecated in favor of _wfopen_s, which does + // not exist in earlier versions, so let the ifstream open the file itself. +#if _MSC_VER >= 1400 // MSVC 2005/8 + ofstream* file = new ofstream(); + file->open(UTF8ToWide(filename).c_str(), ios::out); +#else // _MSC_VER >= 1400 + ofstream* file = new ofstream(_wfopen(UTF8ToWide(filename).c_str(), L"w")); +#endif // _MSC_VER >= 1400 + + return file; +}