4471: Add open_file, works on macOS, safer, Add buttons to open settings file and config directory r=heinrich5991 a=def-

<img width="1790" alt="Screenshot 2021-12-19 at 01 23 12" src="https://user-images.githubusercontent.com/2335377/146659150-2945d3d4-d6e9-41b2-834d-54487a9b91cd.png">
## Checklist

- [x] Tested the change ingame
- [x] Provided screenshots if it is a visual change
- [x] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [x] Considered possible null pointers and out of bounds array indexing
- [x] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: def <dennis@felsin9.de>
This commit is contained in:
bors[bot] 2021-12-19 22:42:26 +00:00 committed by GitHub
commit 56aa4d1c76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 25 deletions

View file

@ -3666,13 +3666,26 @@ int open_link(const char *link)
MultiByteToWideChar(CP_UTF8, 0, link, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); MultiByteToWideChar(CP_UTF8, 0, link, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR));
return (uintptr_t)ShellExecuteW(NULL, L"open", wBuffer, NULL, NULL, SW_SHOWDEFAULT) > 32; return (uintptr_t)ShellExecuteW(NULL, L"open", wBuffer, NULL, NULL, SW_SHOWDEFAULT) > 32;
#elif defined(CONF_PLATFORM_LINUX) #elif defined(CONF_PLATFORM_LINUX)
char aBuf[512]; const int pid = fork();
str_format(aBuf, sizeof(aBuf), "xdg-open %s >/dev/null 2>&1 &", link); if(pid == 0)
return system(aBuf) == 0; execlp("xdg-open", "xdg-open", link, nullptr);
return pid > 0;
#elif defined(CONF_FAMILY_UNIX) #elif defined(CONF_FAMILY_UNIX)
char aBuf[512]; const int pid = fork();
str_format(aBuf, sizeof(aBuf), "open %s &", link); if(pid == 0)
return system(aBuf) == 0; execlp("open", "open", link, nullptr);
return pid > 0;
#endif
}
int open_file(const char *path)
{
#if defined(CONF_PLATFORM_MACOS)
return open_link(path);
#else
char buf[512];
str_format(buf, sizeof(buf), "file://%s", path);
return open_link(buf);
#endif #endif
} }

View file

@ -1815,10 +1815,25 @@ int net_socket_read_wait(NETSOCKET sock, int time);
Returns 1 on success, 0 on failure. Returns 1 on success, 0 on failure.
Remarks: Remarks:
This may not be called with untrusted input or it'll result in arbitrary code execution. This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows.
*/ */
int open_link(const char *link); int open_link(const char *link);
/*
Function: open_file
Opens a file or directory with default program.
Parameters:
path - The path to open.
Returns:
Returns 1 on success, 0 on failure.
Remarks:
This may not be called with untrusted input or it'll result in arbitrary code execution, especially on Windows.
*/
int open_file(const char *path);
void swap_endian(void *data, unsigned elem_size, unsigned num); void swap_endian(void *data, unsigned elem_size, unsigned num);
typedef void (*DBG_LOGGER)(const char *line, void *user); typedef void (*DBG_LOGGER)(const char *line, void *user);

View file

@ -1254,13 +1254,11 @@ void CMenus::RenderDemoList(CUIRect MainView)
if(DoButton_Menu(&s_DirectoryButtonID, Localize("Demos directory"), 0, &DirectoryButton)) if(DoButton_Menu(&s_DirectoryButtonID, Localize("Demos directory"), 0, &DirectoryButton))
{ {
char aBuf[IO_MAX_PATH_LENGTH]; char aBuf[IO_MAX_PATH_LENGTH];
char aBufFull[IO_MAX_PATH_LENGTH + 7];
Storage()->GetCompletePath(IStorage::TYPE_SAVE, "demos", aBuf, sizeof(aBuf)); Storage()->GetCompletePath(IStorage::TYPE_SAVE, "demos", aBuf, sizeof(aBuf));
Storage()->CreateFolder("demos", IStorage::TYPE_SAVE); Storage()->CreateFolder("demos", IStorage::TYPE_SAVE);
str_format(aBufFull, sizeof(aBufFull), "file://%s", aBuf); if(!open_file(aBuf))
if(!open_link(aBufFull))
{ {
dbg_msg("menus", "couldn't open link"); dbg_msg("menus", "couldn't open file");
} }
} }

View file

@ -258,6 +258,38 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView)
m_NeedRestartGeneral = s_ClShowConsole != g_Config.m_ClShowConsole; m_NeedRestartGeneral = s_ClShowConsole != g_Config.m_ClShowConsole;
#endif #endif
Left.HSplitTop(15.0f, 0, &Left);
CUIRect SettingsButton;
Left.HSplitBottom(25.0f, &Left, &SettingsButton);
SettingsButton.HSplitTop(5.0f, 0, &SettingsButton);
static int s_SettingsButtonID = 0;
if(DoButton_Menu(&s_SettingsButtonID, Localize("Settings file"), 0, &SettingsButton))
{
char aBuf[IO_MAX_PATH_LENGTH];
Storage()->GetCompletePath(IStorage::TYPE_SAVE, "settings_ddnet.cfg", aBuf, sizeof(aBuf));
if(!open_file(aBuf))
{
dbg_msg("menus", "couldn't open file");
}
}
Left.HSplitTop(15.0f, 0, &Left);
CUIRect ConfigButton;
Left.HSplitBottom(25.0f, &Left, &ConfigButton);
ConfigButton.HSplitTop(5.0f, 0, &ConfigButton);
static int s_ConfigButtonID = 0;
if(DoButton_Menu(&s_ConfigButtonID, Localize("Config directory"), 0, &ConfigButton))
{
char aBuf[IO_MAX_PATH_LENGTH];
Storage()->GetCompletePath(IStorage::TYPE_SAVE, "", aBuf, sizeof(aBuf));
if(!open_file(aBuf))
{
dbg_msg("menus", "couldn't open file");
}
}
Left.HSplitTop(15.0f, 0, &Left); Left.HSplitTop(15.0f, 0, &Left);
CUIRect DirectoryButton; CUIRect DirectoryButton;
Left.HSplitBottom(25.0f, &Left, &DirectoryButton); Left.HSplitBottom(25.0f, &Left, &DirectoryButton);
@ -268,13 +300,11 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView)
if(DoButton_Menu(&s_ThemesButtonID, Localize("Themes directory"), 0, &DirectoryButton)) if(DoButton_Menu(&s_ThemesButtonID, Localize("Themes directory"), 0, &DirectoryButton))
{ {
char aBuf[IO_MAX_PATH_LENGTH]; char aBuf[IO_MAX_PATH_LENGTH];
char aBufFull[IO_MAX_PATH_LENGTH + 7];
Storage()->GetCompletePath(IStorage::TYPE_SAVE, "themes", aBuf, sizeof(aBuf)); Storage()->GetCompletePath(IStorage::TYPE_SAVE, "themes", aBuf, sizeof(aBuf));
Storage()->CreateFolder("themes", IStorage::TYPE_SAVE); Storage()->CreateFolder("themes", IStorage::TYPE_SAVE);
str_format(aBufFull, sizeof(aBufFull), "file://%s", aBuf); if(!open_file(aBuf))
if(!open_link(aBufFull))
{ {
dbg_msg("menus", "couldn't open link"); dbg_msg("menus", "couldn't open file");
} }
} }
@ -733,13 +763,11 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
if(DoButton_Menu(&s_DirectoryButtonID, Localize("Skins directory"), 0, &DirectoryButton)) if(DoButton_Menu(&s_DirectoryButtonID, Localize("Skins directory"), 0, &DirectoryButton))
{ {
char aBuf[IO_MAX_PATH_LENGTH]; char aBuf[IO_MAX_PATH_LENGTH];
char aBufFull[IO_MAX_PATH_LENGTH + 7];
Storage()->GetCompletePath(IStorage::TYPE_SAVE, "skins", aBuf, sizeof(aBuf)); Storage()->GetCompletePath(IStorage::TYPE_SAVE, "skins", aBuf, sizeof(aBuf));
Storage()->CreateFolder("skins", IStorage::TYPE_SAVE); Storage()->CreateFolder("skins", IStorage::TYPE_SAVE);
str_format(aBufFull, sizeof(aBufFull), "file://%s", aBuf); if(!open_file(aBuf))
if(!open_link(aBufFull))
{ {
dbg_msg("menus", "couldn't open link"); dbg_msg("menus", "couldn't open file");
} }
} }

View file

@ -547,10 +547,9 @@ void CMenus::RenderSettingsCustom(CUIRect MainView)
Storage()->GetCompletePath(IStorage::TYPE_SAVE, aBufFull, aBuf, sizeof(aBuf)); Storage()->GetCompletePath(IStorage::TYPE_SAVE, aBufFull, aBuf, sizeof(aBuf));
Storage()->CreateFolder("assets", IStorage::TYPE_SAVE); Storage()->CreateFolder("assets", IStorage::TYPE_SAVE);
Storage()->CreateFolder(aBufFull, IStorage::TYPE_SAVE); Storage()->CreateFolder(aBufFull, IStorage::TYPE_SAVE);
str_format(aBufFull, sizeof(aBufFull), "file://%s", aBuf); if(!open_file(aBuf))
if(!open_link(aBufFull))
{ {
dbg_msg("menus", "couldn't open link"); dbg_msg("menus", "couldn't open file");
} }
} }