summaryrefslogtreecommitdiff
path: root/src/os
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2021-02-21 17:03:19 +0100
committerNiels Martin Hansen <nielsm@indvikleren.dk>2021-04-07 09:31:47 +0200
commite0561dbded57f195e7842cf69764e3ee2c3a71da (patch)
tree10ae740118601eb102fa73a753bdcdca03607552 /src/os
parent825867f2c50ce508fac442e6113da9cebbfccf75 (diff)
downloadopenttd-e0561dbded57f195e7842cf69764e3ee2c3a71da.tar.xz
Fix #8713: Change OTTD2FS and FS2OTTD to return string objects instead of static buffers
Diffstat (limited to 'src/os')
-rw-r--r--src/os/os2/os2.cpp3
-rw-r--r--src/os/unix/unix.cpp21
-rw-r--r--src/os/windows/crashlog_win.cpp35
-rw-r--r--src/os/windows/font_win32.cpp11
-rw-r--r--src/os/windows/font_win32.h3
-rw-r--r--src/os/windows/win32.cpp60
6 files changed, 70 insertions, 63 deletions
diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp
index f1128b0c6..009a3e0ed 100644
--- a/src/os/os2/os2.cpp
+++ b/src/os/os2/os2.cpp
@@ -203,9 +203,6 @@ bool GetClipboardContents(char *buffer, const char *last)
}
-const char *FS2OTTD(const char *name) {return name;}
-const char *OTTD2FS(const char *name) {return name;}
-
void OSOpenBrowser(const char *url)
{
// stub only
diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp
index 9ef2bc386..57edf1d38 100644
--- a/src/os/unix/unix.cpp
+++ b/src/os/unix/unix.cpp
@@ -146,9 +146,8 @@ static const char *GetLocalCode()
* Convert between locales, which from and which to is set in the calling
* functions OTTD2FS() and FS2OTTD().
*/
-static const char *convert_tofrom_fs(iconv_t convd, const char *name)
+static const char *convert_tofrom_fs(iconv_t convd, const char *name, char *outbuf, size_t outlen)
{
- static char buf[1024];
/* There are different implementations of iconv. The older ones,
* e.g. SUSv2, pass a const pointer, whereas the newer ones, e.g.
* IEEE 1003.1 (2004), pass a non-const pointer. */
@@ -158,9 +157,8 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name)
const char *inbuf = name;
#endif
- char *outbuf = buf;
- size_t outlen = sizeof(buf) - 1;
size_t inlen = strlen(name);
+ char *buf = outbuf;
strecpy(outbuf, name, outbuf + outlen);
@@ -179,9 +177,10 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name)
* @param name pointer to a valid string that will be converted
* @return pointer to a new stringbuffer that contains the converted string
*/
-const char *OTTD2FS(const char *name)
+std::string OTTD2FS(const std::string &name)
{
static iconv_t convd = (iconv_t)(-1);
+ char buf[1024] = {};
if (convd == (iconv_t)(-1)) {
const char *env = GetLocalCode();
@@ -192,17 +191,18 @@ const char *OTTD2FS(const char *name)
}
}
- return convert_tofrom_fs(convd, name);
+ return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
}
/**
* Convert to OpenTTD's encoding from that of the local environment
- * @param name pointer to a valid string that will be converted
+ * @param name valid string that will be converted
* @return pointer to a new stringbuffer that contains the converted string
*/
-const char *FS2OTTD(const char *name)
+std::string FS2OTTD(const std::string &name)
{
static iconv_t convd = (iconv_t)(-1);
+ char buf[1024] = {};
if (convd == (iconv_t)(-1)) {
const char *env = GetLocalCode();
@@ -213,12 +213,9 @@ const char *FS2OTTD(const char *name)
}
}
- return convert_tofrom_fs(convd, name);
+ return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
}
-#else
-const char *FS2OTTD(const char *name) {return name;}
-const char *OTTD2FS(const char *name) {return name;}
#endif /* WITH_ICONV */
void ShowInfo(const char *str)
diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp
index 76a05eaa9..9768bcc82 100644
--- a/src/os/windows/crashlog_win.cpp
+++ b/src/os/windows/crashlog_win.cpp
@@ -189,7 +189,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
GetModuleFileName(mod, buffer, MAX_PATH);
GetFileInfo(&dfi, buffer);
output += seprintf(output, last, " %-20s handle: %p size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\n",
- FS2OTTD(buffer),
+ FS2OTTD(buffer).c_str(),
mod,
dfi.size,
dfi.crc32,
@@ -501,7 +501,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump");
if (funcMiniDumpWriteDump != nullptr) {
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
- HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
+ HANDLE file = CreateFile(OTTD2FS(filename).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
HANDLE proc = GetCurrentProcess();
DWORD procid = GetCurrentProcessId();
MINIDUMP_EXCEPTION_INFORMATION mdei;
@@ -689,7 +689,8 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
switch (msg) {
case WM_INITDIALOG: {
/* We need to put the crash-log in a separate buffer because the default
- * buffer in OTTD2FS is not large enough (512 chars) */
+ * buffer in MB_TO_WIDE is not large enough (512 chars) */
+ wchar_t filenamebuf[MAX_PATH * 2];
wchar_t crash_msgW[lengthof(CrashLogWindows::current->crashlog)];
/* Convert unix -> dos newlines because the edit box only supports that properly :( */
const char *unix_nl = CrashLogWindows::current->crashlog;
@@ -704,19 +705,23 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
/* Add path to crash.log and crash.dmp (if any) to the crash window text */
size_t len = wcslen(_crash_desc) + 2;
- len += wcslen(OTTD2FS(CrashLogWindows::current->crashlog_filename)) + 2;
- len += wcslen(OTTD2FS(CrashLogWindows::current->crashdump_filename)) + 2;
- len += wcslen(OTTD2FS(CrashLogWindows::current->screenshot_filename)) + 1;
+ len += wcslen(convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf), false)) + 2;
+ len += wcslen(convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf), false)) + 2;
+ len += wcslen(convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf), false)) + 1;
wchar_t *text = AllocaM(wchar_t, len);
- _snwprintf(text, len, _crash_desc, OTTD2FS(CrashLogWindows::current->crashlog_filename));
- if (OTTD2FS(CrashLogWindows::current->crashdump_filename)[0] != L'\0') {
+ int printed = _snwprintf(text, len, _crash_desc, convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf), false));
+ if (printed < 0 || (size_t)printed > len) {
+ MessageBox(wnd, L"Catastrophic failure trying to display crash message. Could not perform text formatting.", L"OpenTTD", MB_ICONERROR);
+ return FALSE;
+ }
+ if (convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf), false)[0] != L'\0') {
wcscat(text, L"\n");
- wcscat(text, OTTD2FS(CrashLogWindows::current->crashdump_filename));
+ wcscat(text, filenamebuf);
}
- if (OTTD2FS(CrashLogWindows::current->screenshot_filename)[0] != L'\0') {
+ if (convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf), false)[0] != L'\0') {
wcscat(text, L"\n");
- wcscat(text, OTTD2FS(CrashLogWindows::current->screenshot_filename));
+ wcscat(text, filenamebuf);
}
SetDlgItemText(wnd, 10, text);
@@ -730,18 +735,20 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
CrashLog::AfterCrashLogCleanup();
ExitProcess(2);
case 13: // Emergency save
+ wchar_t filenamebuf[MAX_PATH * 2];
char filename[MAX_PATH];
if (CrashLogWindows::current->WriteSavegame(filename, lastof(filename))) {
- size_t len = wcslen(_save_succeeded) + wcslen(OTTD2FS(filename)) + 1;
+ convert_to_fs(filename, filenamebuf, lengthof(filenamebuf), false);
+ size_t len = lengthof(_save_succeeded) + wcslen(filenamebuf) + 1;
wchar_t *text = AllocaM(wchar_t, len);
- _snwprintf(text, len, _save_succeeded, OTTD2FS(filename));
+ _snwprintf(text, len, _save_succeeded, filenamebuf);
MessageBox(wnd, text, L"Save successful", MB_ICONINFORMATION);
} else {
MessageBox(wnd, L"Save failed", L"Save failed", MB_ICONINFORMATION);
}
break;
case 15: // Expand window to show crash-message
- _expanded ^= 1;
+ _expanded = !_expanded;
SetWndSize(wnd, _expanded);
break;
}
diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp
index 9a9dba2f2..1d923ddb2 100644
--- a/src/os/windows/font_win32.cpp
+++ b/src/os/windows/font_win32.cpp
@@ -83,7 +83,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
}
/* Convert font name to file system encoding. */
- wchar_t *font_namep = wcsdup(OTTD2FS(font_name));
+ wchar_t *font_namep = wcsdup(OTTD2FS(font_name).c_str());
for (index = 0;; index++) {
wchar_t *s;
@@ -377,6 +377,7 @@ Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels)
{
this->dc = CreateCompatibleDC(nullptr);
this->SetFontSize(fs, pixels);
+ this->fontname = FS2OTTD(this->logfont.lfFaceName);
}
Win32FontCache::~Win32FontCache()
@@ -438,7 +439,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels)
this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth;
this->glyph_size.cy = otm->otmTextMetrics.tmHeight;
- DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPTSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
+ DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)).c_str(), pixels);
}
/**
@@ -541,10 +542,10 @@ void Win32FontCache::ClearFontCache()
/* Convert characters outside of the BMP into surrogate pairs. */
WCHAR chars[2];
if (key >= 0x010000U) {
- chars[0] = (WCHAR)(((key - 0x010000U) >> 10) + 0xD800);
- chars[1] = (WCHAR)(((key - 0x010000U) & 0x3FF) + 0xDC00);
+ chars[0] = (wchar_t)(((key - 0x010000U) >> 10) + 0xD800);
+ chars[1] = (wchar_t)(((key - 0x010000U) & 0x3FF) + 0xDC00);
} else {
- chars[0] = (WCHAR)(key & 0xFFFF);
+ chars[0] = (wchar_t)(key & 0xFFFF);
}
WORD glyphs[2] = { 0, 0 };
diff --git a/src/os/windows/font_win32.h b/src/os/windows/font_win32.h
index ba413fae5..6ab304c89 100644
--- a/src/os/windows/font_win32.h
+++ b/src/os/windows/font_win32.h
@@ -21,6 +21,7 @@ private:
HDC dc = nullptr; ///< Cached GDI device context.
HGDIOBJ old_font; ///< Old font selected into the GDI context.
SIZE glyph_size; ///< Maximum size of regular glyphs.
+ std::string fontname; ///< Cached copy of this->logfont.lfFaceName
void SetFontSize(FontSize fs, int pixels);
@@ -33,7 +34,7 @@ public:
~Win32FontCache();
void ClearFontCache() override;
GlyphID MapCharToGlyph(WChar key) override;
- const char *GetFontName() override { return FS2OTTD(this->logfont.lfFaceName); }
+ const char *GetFontName() override { return this->fontname.c_str(); }
const void *GetOSHandle() override { return &this->logfont; }
};
diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp
index cfe7d42d9..568876ab1 100644
--- a/src/os/windows/win32.cpp
+++ b/src/os/windows/win32.cpp
@@ -57,7 +57,7 @@ bool LoadLibraryList(Function proc[], const char *dll)
{
while (*dll != '\0') {
HMODULE lib;
- lib = LoadLibrary(OTTD2FS(dll));
+ lib = LoadLibrary(OTTD2FS(dll).c_str());
if (lib == nullptr) return false;
for (;;) {
@@ -77,12 +77,12 @@ bool LoadLibraryList(Function proc[], const char *dll)
void ShowOSErrorBox(const char *buf, bool system)
{
MyShowCursor(true);
- MessageBox(GetActiveWindow(), OTTD2FS(buf), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
+ MessageBox(GetActiveWindow(), OTTD2FS(buf).c_str(), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
}
void OSOpenBrowser(const char *url)
{
- ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url), nullptr, nullptr, SW_SHOWNORMAL);
+ ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
}
/* Code below for windows version of opendir/readdir/closedir copied and
@@ -141,14 +141,14 @@ DIR *opendir(const wchar_t *path)
if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) {
d = dir_calloc();
if (d != nullptr) {
- wchar_t search_path[MAX_PATH];
+ std::wstring search_path = path;
bool slash = path[wcslen(path) - 1] == '\\';
/* build search path for FindFirstFile, try not to append additional slashes
* as it throws Win9x off its groove for root directories */
- _snwprintf(search_path, lengthof(search_path), L"%s%s*", path, slash ? L"" : L"\\");
- *lastof(search_path) = '\0';
- d->hFind = FindFirstFile(search_path, &d->fd);
+ if (!slash) search_path += L"\\";
+ search_path += L"*";
+ d->hFind = FindFirstFile(search_path.c_str(), &d->fd);
if (d->hFind != INVALID_HANDLE_VALUE ||
GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty
@@ -246,7 +246,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
ULARGE_INTEGER bytes_free;
- bool retval = GetDiskFreeSpaceEx(OTTD2FS(path), &bytes_free, nullptr, nullptr);
+ bool retval = GetDiskFreeSpaceEx(OTTD2FS(path).c_str(), &bytes_free, nullptr, nullptr);
if (retval) *tot = bytes_free.QuadPart;
SetErrorMode(sem); // reset previous setting
@@ -415,7 +415,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
/* Convert the command line to UTF-8. We need a dedicated buffer
* for this because argv[] points into this buffer and this needs to
* be available between subsequent calls to FS2OTTD(). */
- char *cmdline = stredup(FS2OTTD(GetCommandLine()));
+ char *cmdline = stredup(FS2OTTD(GetCommandLine()).c_str());
#if defined(_DEBUG)
CreateConsole();
@@ -553,34 +553,40 @@ bool GetClipboardContents(char *buffer, const char *last)
/**
- * Convert to OpenTTD's encoding from wide characters.
+ * Convert to OpenTTD's encoding from a wide string.
* OpenTTD internal encoding is UTF8.
- * The returned value's contents can only be guaranteed until the next call to
- * this function. So if the value is needed for anything else, use convert_from_fs
- * @param name pointer to a valid string that will be converted (local, or wide)
- * @return pointer to the converted string; if failed string is of zero-length
+ * @param name valid string that will be converted (local, or wide)
+ * @return converted string; if failed string is of zero-length
* @see the current code-page comes from video\win32_v.cpp, event-notification
* WM_INPUTLANGCHANGE
*/
-const char *FS2OTTD(const wchar_t *name)
+std::string FS2OTTD(const std::wstring &name)
{
- static char utf8_buf[512];
- return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
+ int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
+ int len = WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0, nullptr, nullptr);
+ if (len <= 0) return std::string();
+ char *utf8_buf = AllocaM(char, len + 1);
+ utf8_buf[len] = '\0';
+ WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, utf8_buf, len, nullptr, nullptr);
+ return std::string(utf8_buf, static_cast<size_t>(len));
}
/**
- * Convert from OpenTTD's encoding to wide characters.
+ * Convert from OpenTTD's encoding to a wide string.
* OpenTTD internal encoding is UTF8.
- * The returned value's contents can only be guaranteed until the next call to
- * this function. So if the value is needed for anything else, use convert_from_fs
- * @param name pointer to a valid string that will be converted (UTF8)
+ * @param name valid string that will be converted (UTF8)
* @param console_cp convert to the console encoding instead of the normal system encoding.
- * @return pointer to the converted string; if failed string is of zero-length
+ * @return converted string; if failed string is of zero-length
*/
-const wchar_t *OTTD2FS(const char *name, bool console_cp)
+std::wstring OTTD2FS(const std::string &name, bool console_cp)
{
- static wchar_t system_buf[512];
- return convert_to_fs(name, system_buf, lengthof(system_buf), console_cp);
+ int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
+ int len = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0);
+ if (len <= 0) return std::wstring();
+ wchar_t *system_buf = AllocaM(wchar_t, len + 1);
+ system_buf[len] = L'\0';
+ MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, system_buf, len);
+ return std::wstring(system_buf, static_cast<size_t>(len));
}
@@ -594,10 +600,8 @@ const wchar_t *OTTD2FS(const char *name, bool console_cp)
*/
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
{
- const wchar_t *wide_buf = name;
-
/* Convert UTF-16 string to UTF-8. */
- int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, nullptr, nullptr);
+ int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, (int)buflen, nullptr, nullptr);
if (len == 0) utf8_buf[0] = '\0';
return utf8_buf;