Skip to content

Commit

Permalink
Fix OpenTTD#8713: Change OTTD2FS and FS2OTTD to return string objects…
Browse files Browse the repository at this point in the history
… instead of static buffers
  • Loading branch information
nielsmh committed Apr 2, 2021
1 parent 799eb31 commit f806879
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 99 deletions.
2 changes: 1 addition & 1 deletion src/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static void debug_print(const char *dbg, const char *buf)
#if defined(_WIN32)
wchar_t system_buf[512];
convert_to_fs(buffer, system_buf, lengthof(system_buf), true);
_fputts(system_buf, stderr);
fputws(system_buf, stderr);
#else
fputs(buffer, stderr);
#endif
Expand Down
14 changes: 7 additions & 7 deletions src/fileio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ bool FioCheckFileExists(const std::string &filename, Subdirectory subdir)
*/
bool FileExists(const std::string &filename)
{
return access(OTTD2FS(filename.c_str()), 0) == 0;
return access(OTTD2FS(filename).c_str(), 0) == 0;
}

/**
Expand Down Expand Up @@ -358,7 +358,7 @@ static FILE *FioFOpenFileSp(const std::string &filename, const char *mode, Searc
}

#if defined(_WIN32)
if (mode[0] == 'r' && GetFileAttributes(OTTD2FS(buf.c_str())) == INVALID_FILE_ATTRIBUTES) return nullptr;
if (mode[0] == 'r' && GetFileAttributes(OTTD2FS(buf).c_str()) == INVALID_FILE_ATTRIBUTES) return nullptr;
#endif

f = fopen(buf.c_str(), mode);
Expand Down Expand Up @@ -506,11 +506,11 @@ void FioCreateDirectory(const std::string &name)
/* Ignore directory creation errors; they'll surface later on, and most
* of the time they are 'directory already exists' errors anyhow. */
#if defined(_WIN32)
CreateDirectory(OTTD2FS(name.c_str()), nullptr);
CreateDirectory(OTTD2FS(name).c_str(), nullptr);
#elif defined(OS2) && !defined(__INNOTEK_LIBC__)
mkdir(OTTD2FS(name.c_str()));
mkdir(OTTD2FS(name).c_str());
#else
mkdir(OTTD2FS(name.c_str()), 0755);
mkdir(OTTD2FS(name).c_str(), 0755);
#endif
}

Expand Down Expand Up @@ -1315,7 +1315,7 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s
if (path == nullptr || (dir = ttd_opendir(path)) == nullptr) return 0;

while ((dirent = readdir(dir)) != nullptr) {
const char *d_name = FS2OTTD(dirent->d_name);
std::string d_name = FS2OTTD(dirent->d_name);

if (!FiosIsValidFile(path, dirent, &sb)) continue;

Expand All @@ -1325,7 +1325,7 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s
if (S_ISDIR(sb.st_mode)) {
/* Directory */
if (!recursive) continue;
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
if (d_name == "." || d_name == "..") continue;
AppendPathSeparator(filename);
num += ScanPath(fs, extension, filename.c_str(), basepath_length, recursive);
} else if (S_ISREG(sb.st_mode)) {
Expand Down
2 changes: 1 addition & 1 deletion src/fileio_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ int closedir(DIR *d);
*/
static inline DIR *ttd_opendir(const char *path)
{
return opendir(OTTD2FS(path));
return opendir(OTTD2FS(path).c_str());
}


Expand Down
4 changes: 2 additions & 2 deletions src/fios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ bool FiosFileScanner::AddFile(const std::string &filename, size_t basepath_lengt
FiosItem *fios = file_list.Append();
#ifdef _WIN32
// Retrieve the file modified date using GetFileTime rather than stat to work around an obscure MSVC bug that affects Windows XP
HANDLE fh = CreateFile(OTTD2FS(filename.c_str()), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
HANDLE fh = CreateFile(OTTD2FS(filename).c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);

if (fh != INVALID_HANDLE_VALUE) {
FILETIME ft;
Expand Down Expand Up @@ -384,7 +384,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c
/* Show subdirectories */
if ((dir = ttd_opendir(_fios_path->c_str())) != nullptr) {
while ((dirent = readdir(dir)) != nullptr) {
strecpy(d_name, FS2OTTD(dirent->d_name), lastof(d_name));
strecpy(d_name, FS2OTTD(dirent->d_name).c_str(), lastof(d_name));

/* found file must be directory, but not '.' or '..' */
if (FiosIsValidFile(_fios_path->c_str(), dirent, &sb) && S_ISDIR(sb.st_mode) &&
Expand Down
6 changes: 3 additions & 3 deletions src/ini.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ bool IniFile::SaveToDisk(const std::string &filename)
std::string file_new{ filename };
file_new.append(".new");

std::ofstream os(OTTD2FS(file_new.c_str()));
std::ofstream os(OTTD2FS(file_new));
if (os.fail()) return false;

for (const IniGroup *group = this->group; group != nullptr; group = group->next) {
Expand Down Expand Up @@ -94,8 +94,8 @@ bool IniFile::SaveToDisk(const std::string &filename)
#if defined(_WIN32)
/* Allocate space for one more \0 character. */
wchar_t tfilename[MAX_PATH + 1], tfile_new[MAX_PATH + 1];
wcsncpy(tfilename, OTTD2FS(filename.c_str()), MAX_PATH);
wcsncpy(tfile_new, OTTD2FS(file_new.c_str()), MAX_PATH);
wcsncpy(tfilename, OTTD2FS(filename).c_str(), MAX_PATH);
wcsncpy(tfile_new, OTTD2FS(file_new).c_str(), MAX_PATH);
/* SHFileOperation wants a double '\0' terminated string. */
tfilename[MAX_PATH - 1] = '\0';
tfile_new[MAX_PATH - 1] = '\0';
Expand Down
4 changes: 2 additions & 2 deletions src/music/cocoa_m.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song)
return;
}

const char *os_file = OTTD2FS(filename.c_str());
CFAutoRelease<CFURLRef> url(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false));
std::string os_file = OTTD2FS(filename);
CFAutoRelease<CFURLRef> url(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file.c_str(), os_file.length(), false));

if (MusicSequenceFileLoad(_sequence, url.get(), kMusicSequenceFile_AnyType, 0) != noErr) {
DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file");
Expand Down
4 changes: 2 additions & 2 deletions src/music/dmusic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ bool DLSFile::ReadDLSWaveList(FILE *f, DWORD list_length)

bool DLSFile::LoadFile(const wchar_t *file)
{
DEBUG(driver, 2, "DMusic: Try to load DLS file %s", FS2OTTD(file));
DEBUG(driver, 2, "DMusic: Try to load DLS file %s", FS2OTTD(file).c_str());

FILE *f = _wfopen(file, L"rb");
if (f == nullptr) return false;
Expand Down Expand Up @@ -881,7 +881,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls)
if (!dls_file.LoadFile(path)) return "Can't load GM DLS collection";
}
} else {
if (!dls_file.LoadFile(OTTD2FS(user_dls))) return "Can't load GM DLS collection";
if (!dls_file.LoadFile(OTTD2FS(user_dls).c_str())) return "Can't load GM DLS collection";
}

/* Get download port and allocate download IDs. */
Expand Down
2 changes: 1 addition & 1 deletion src/network/core/address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *
if (e != 0) {
if (func != ResolveLoopProc) {
DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s failed: %s",
this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)));
this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str());
}
return INVALID_SOCKET;
}
Expand Down
3 changes: 0 additions & 3 deletions src/os/os2/os2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 9 additions & 12 deletions src/os/unix/unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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);

Expand All @@ -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();
Expand All @@ -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();
Expand All @@ -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)
Expand Down
35 changes: 21 additions & 14 deletions src/os/windows/crashlog_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down
11 changes: 6 additions & 5 deletions src/os/windows/font_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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 };
Expand Down
3 changes: 2 additions & 1 deletion src/os/windows/font_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Win32FontCache : public TrueTypeFontCache {
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);

Expand All @@ -33,7 +34,7 @@ class Win32FontCache : public TrueTypeFontCache {
~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; }
};

Expand Down
Loading

0 comments on commit f806879

Please sign in to comment.