Handle non-ascii filenames in the crash reporter. b=382508, r=luser
authordcamp@mozilla.com
Tue, 24 Jul 2007 18:06:10 -0700
changeset 3911 b058297fabf57e39708571b1aa0ff0c0cbe6286d
parent 3910 38ab679b5dfa5de4876e1adddba7f72796847d3d
child 3912 ba50b24295f4fe03a5c147a40057116f6760ae97
push idunknown
push userunknown
push dateunknown
reviewersluser
bugs382508
milestone1.9a7pre
Handle non-ascii filenames in the crash reporter. b=382508, r=luser
toolkit/crashreporter/client/crashreporter.cpp
toolkit/crashreporter/client/crashreporter.h
toolkit/crashreporter/client/crashreporter_linux.cpp
toolkit/crashreporter/client/crashreporter_osx.mm
toolkit/crashreporter/client/crashreporter_win.cpp
--- a/toolkit/crashreporter/client/crashreporter.cpp
+++ b/toolkit/crashreporter/client/crashreporter.cpp
@@ -146,20 +146,25 @@ bool ReadStrings(istream& in, StringTabl
 
   return true;
 }
 
 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,
                   const string& header,
                   StringTable& strings,
                   bool escape)
 {
   out << "[" << header << "]" << std::endl;
@@ -178,20 +183,25 @@ bool WriteStrings(ostream& out,
   return true;
 }
 
 bool WriteStringsToFile(const string& path,
                         const string& header,
                         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()
 {
   string iniPath;
   if (!UIGetIniPath(iniPath))
     return false;
 
@@ -450,14 +460,19 @@ int main(int argc, char** argv)
   UIShutdown();
 
   return 0;
 }
 
 #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<char**>(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
--- a/toolkit/crashreporter/client/crashreporter.h
+++ b/toolkit/crashreporter/client/crashreporter.h
@@ -8,23 +8,27 @@
 #endif
 
 #include <string>
 #include <map>
 #include <vector>
 #include <stdlib.h>
 #include <stdio.h>
 #include <iostream>
+#include <fstream>
 
 #if defined(XP_WIN32)
 
 #include <windows.h>
+
 #define UI_SNPRINTF _snprintf
 #define UI_DIR_SEPARATOR "\\"
 
+std::string WideToUTF8(const std::wstring& wide, bool* success = 0);
+
 #else
 
 #define UI_SNPRINTF snprintf
 #define UI_DIR_SEPARATOR "/"
 
 #endif
 
 typedef std::map<std::string, std::string> StringTable;
@@ -108,14 +112,16 @@ void UIError_impl(const std::string& mes
 bool UIGetIniPath(std::string& path);
 bool UIGetSettingsPath(const std::string& vendor,
                        const std::string& product,
                        std::string& settingsPath);
 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 )
 #endif
 
 #endif
--- a/toolkit/crashreporter/client/crashreporter_linux.cpp
+++ b/toolkit/crashreporter/client/crashreporter_linux.cpp
@@ -491,8 +491,19 @@ bool UIMoveFile(const string& file, cons
 {
   return (rename(file.c_str(), newfile.c_str()) != -1);
 }
 
 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);
+}
+
--- a/toolkit/crashreporter/client/crashreporter_osx.mm
+++ b/toolkit/crashreporter/client/crashreporter_osx.mm
@@ -517,8 +517,18 @@ bool UIMoveFile(const string& file, cons
 {
   return (rename(file.c_str(), newfile.c_str()) != -1);
 }
 
 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);
+}
--- a/toolkit/crashreporter/client/crashreporter_win.cpp
+++ b/toolkit/crashreporter/client/crashreporter_win.cpp
@@ -62,16 +62,19 @@
 
 #define WM_UPLOADCOMPLETE WM_APP
 
 using std::string;
 using std::wstring;
 using std::map;
 using std::vector;
 using std::set;
+using std::ios;
+using std::ifstream;
+using std::ofstream;
 
 using namespace CrashReporter;
 
 typedef struct {
   HWND hDlg;
   wstring dumpFile;
   map<wstring,wstring> queryParameters;
   wstring sendURL;
@@ -95,17 +98,16 @@ static const UINT kDefaultAttachedBottom
   IDC_SUBMITCRASHCHECK,
   IDC_EMAILMECHECK,
   IDC_EMAILTEXT,
   IDC_CLOSEBUTTON,
   IDC_RESTARTBUTTON,
 };
 
 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)
 {
   return UTF8ToWide(gStrings[key]);
 }
 
 /* === win32 helper functions === */
@@ -622,17 +624,17 @@ static wstring UTF8ToWide(const string& 
   delete [] buffer;
 
   if (success)
     *success = true;
 
   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(),
                                         -1, NULL, 0, NULL, NULL);
   if(buffer_size == 0) {
     if (success)
       *success = false;
     return "";
@@ -779,8 +781,44 @@ bool UIMoveFile(const string& oldfile, c
   return MoveFile(UTF8ToWide(oldfile).c_str(), UTF8ToWide(newfile).c_str())
     == TRUE;
 }
 
 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;
+}