mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Add checks for remaining WideCharToMultiByte
usages in system
Converting wide-char (UTF-16) to multi-byte (UTF-8) takes 1-2 wide-chars from the input and transforms them to 1-4 bytes, so having `char` and `WCHAR` buffers with equal static lengths means that this function can fail due to insufficient buffer sizes when the user has folder or files with very long names (many unicode codepoints). Therefore checks are added that allow only the error `ERROR_INSUFFICIENT_BUFFER` when `WideCharToMultiByte` fails, which is expected on very long paths, as these would also lead to further errors later in the code. The respective functions will now fail with a return and ignore files that have too long names. This could only completely be fixed using dynamically sized buffers for all paths, which seems like too much work and overhead. Other errors are not expected and hence caught by the assertions, as those would indicate programming errors like wrong arguments being passed. Reference: https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte
This commit is contained in:
parent
6c30fb6f5a
commit
6501ae9b9d
|
@ -95,12 +95,13 @@ IOHANDLE io_current_exe()
|
|||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
wchar_t wpath[IO_MAX_PATH_LENGTH];
|
||||
char path[IO_MAX_PATH_LENGTH];
|
||||
if(!GetModuleFileNameW(NULL, wpath, std::size(wpath)))
|
||||
if(GetModuleFileNameW(NULL, wpath, std::size(wpath)) == 0 || GetLastError() != ERROR_SUCCESS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(!WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path), NULL, NULL))
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path), NULL, NULL) == 0)
|
||||
{
|
||||
dbg_assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "WideCharToMultiByte failure");
|
||||
return 0;
|
||||
}
|
||||
return io_open(path, IOFLAG_READ);
|
||||
|
@ -2121,7 +2122,11 @@ void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user)
|
|||
/* add all the entries */
|
||||
do
|
||||
{
|
||||
WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer, sizeof(buffer), NULL, NULL);
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer, sizeof(buffer), NULL, NULL) == 0)
|
||||
{
|
||||
dbg_assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "WideCharToMultiByte failure");
|
||||
continue;
|
||||
}
|
||||
if(cb(buffer, (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0, type, user))
|
||||
break;
|
||||
} while(FindNextFileW(handle, &finddata));
|
||||
|
@ -2169,7 +2174,11 @@ void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int t
|
|||
/* add all the entries */
|
||||
do
|
||||
{
|
||||
WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer, sizeof(buffer), NULL, NULL);
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer, sizeof(buffer), NULL, NULL) == 0)
|
||||
{
|
||||
dbg_assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "WideCharToMultiByte failure");
|
||||
continue;
|
||||
}
|
||||
|
||||
CFsFileInfo info;
|
||||
info.m_pName = buffer;
|
||||
|
@ -2221,7 +2230,11 @@ int fs_storage_path(const char *appname, char *path, int max)
|
|||
if(!home)
|
||||
return -1;
|
||||
char buffer[IO_MAX_PATH_LENGTH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, home, -1, buffer, sizeof(buffer), NULL, NULL);
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, home, -1, buffer, sizeof(buffer), NULL, NULL) == 0)
|
||||
{
|
||||
dbg_assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "WideCharToMultiByte failure");
|
||||
return -1;
|
||||
}
|
||||
str_format(path, max, "%s/%s", buffer, appname);
|
||||
return 0;
|
||||
#elif defined(CONF_PLATFORM_ANDROID)
|
||||
|
@ -2366,8 +2379,12 @@ char *fs_getcwd(char *buffer, int buffer_size)
|
|||
WCHAR wBuffer[IO_MAX_PATH_LENGTH];
|
||||
DWORD result = GetCurrentDirectoryW(std::size(wBuffer), wBuffer);
|
||||
if(result == 0 || result > std::size(wBuffer))
|
||||
return 0;
|
||||
WideCharToMultiByte(CP_UTF8, 0, wBuffer, -1, buffer, buffer_size, NULL, NULL);
|
||||
return nullptr;
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, wBuffer, -1, buffer, buffer_size, NULL, NULL) == 0)
|
||||
{
|
||||
dbg_assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "WideCharToMultiByte failure");
|
||||
return nullptr;
|
||||
}
|
||||
return buffer;
|
||||
#else
|
||||
return getcwd(buffer, buffer_size);
|
||||
|
@ -3958,7 +3975,8 @@ int open_file(const char *path)
|
|||
char workingDir[IO_MAX_PATH_LENGTH];
|
||||
if(fs_is_relative_path(path))
|
||||
{
|
||||
fs_getcwd(workingDir, sizeof(workingDir));
|
||||
if(!fs_getcwd(workingDir, sizeof(workingDir)))
|
||||
return 0;
|
||||
str_append(workingDir, "/", sizeof(workingDir));
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue