5975: Fix crash when cutting a demo opened from command line, various other demo menu fixes r=heinrich5991 a=Robyt3

Crash reported by `@teini94` on Discord.

## Checklist

- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] 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: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
bors[bot] 2022-10-24 20:31:25 +00:00 committed by GitHub
commit cc9ef401db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 36 deletions

View file

@ -1143,7 +1143,7 @@ void CDemoEditor::Slice(const char *pDemo, const char *pDst, int StartTick, int
m_SliceTo = EndTick;
m_Stop = false;
if(m_pDemoPlayer->Load(m_pStorage, m_pConsole, pDemo, IStorage::TYPE_ALL) == -1)
if(m_pDemoPlayer->Load(m_pStorage, m_pConsole, pDemo, fs_is_relative_path(pDemo) ? IStorage::TYPE_ALL : IStorage::TYPE_ABSOLUTE) == -1)
return;
const CMapInfo *pMapInfo = m_pDemoPlayer->GetMapInfo();

View file

@ -1995,14 +1995,12 @@ int CMenus::Render()
// rename demo
if(m_DemolistSelectedIndex >= 0 && !m_DemolistSelectedIsDir)
{
char aBufOld[512];
char aBufOld[IO_MAX_PATH_LENGTH];
str_format(aBufOld, sizeof(aBufOld), "%s/%s", m_aCurrentDemoFolder, m_vDemos[m_DemolistSelectedIndex].m_aFilename);
int Length = str_length(m_aCurrentDemoFile);
char aBufNew[512];
if(Length <= 4 || m_aCurrentDemoFile[Length - 5] != '.' || str_comp_nocase(m_aCurrentDemoFile + Length - 4, "demo"))
str_format(aBufNew, sizeof(aBufNew), "%s/%s.demo", m_aCurrentDemoFolder, m_aCurrentDemoFile);
else
str_format(aBufNew, sizeof(aBufNew), "%s/%s", m_aCurrentDemoFolder, m_aCurrentDemoFile);
char aBufNew[IO_MAX_PATH_LENGTH];
str_format(aBufNew, sizeof(aBufNew), "%s/%s", m_aCurrentDemoFolder, m_aCurrentDemoFile);
if(!str_endswith(aBufNew, ".demo"))
str_append(aBufNew, ".demo", sizeof(aBufNew));
if(Storage()->RenameFile(aBufOld, aBufNew, m_vDemos[m_DemolistSelectedIndex].m_StorageType))
{
DemolistPopulate();
@ -2054,27 +2052,20 @@ int CMenus::Render()
// name video
if(m_DemolistSelectedIndex >= 0 && !m_DemolistSelectedIsDir)
{
char aBufOld[512];
char aBufOld[IO_MAX_PATH_LENGTH];
str_format(aBufOld, sizeof(aBufOld), "%s/%s", m_aCurrentDemoFolder, m_vDemos[m_DemolistSelectedIndex].m_aFilename);
int Length = str_length(m_aCurrentDemoFile);
char aBufNew[512];
if(Length <= 3 || m_aCurrentDemoFile[Length - 4] != '.' || str_comp_nocase(m_aCurrentDemoFile + Length - 3, "mp4"))
str_format(aBufNew, sizeof(aBufNew), "%s.mp4", m_aCurrentDemoFile);
else
str_format(aBufNew, sizeof(aBufNew), "%s", m_aCurrentDemoFile);
char aWholePath[1024];
if(!str_endswith(m_aCurrentDemoFile, ".mp4"))
str_append(m_aCurrentDemoFile, ".mp4", sizeof(m_aCurrentDemoFile));
char aWholePath[IO_MAX_PATH_LENGTH];
// store new video filename to origin buffer
str_copy(m_aCurrentDemoFile, aBufNew);
if(Storage()->FindFile(m_aCurrentDemoFile, "videos", IStorage::TYPE_ALL, aWholePath, sizeof(aWholePath)))
{
PopupMessage(Localize("Error"), Localize("Destination file already exist"), Localize("Ok"));
m_Popup = POPUP_REPLACE_VIDEO;
}
else
{
const char *pError = Client()->DemoPlayer_Render(aBufOld, m_vDemos[m_DemolistSelectedIndex].m_StorageType, m_aCurrentDemoFile, m_Speed);
m_Speed = 4;
//Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "demo_render_path", aWholePath);
if(pError)
PopupMessage(Localize("Error"), str_comp(pError, "error loading demo") ? pError : Localize("Error loading demo"), Localize("Ok"));
}

View file

@ -374,7 +374,7 @@ protected:
struct CDemoItem
{
char m_aFilename[IO_MAX_PATH_LENGTH];
char m_aName[128];
char m_aName[IO_MAX_PATH_LENGTH];
bool m_IsDir;
int m_StorageType;
time_t m_Date;
@ -434,8 +434,8 @@ protected:
}
};
char m_aCurrentDemoFolder[256];
char m_aCurrentDemoFile[64];
char m_aCurrentDemoFolder[IO_MAX_PATH_LENGTH];
char m_aCurrentDemoFile[IO_MAX_PATH_LENGTH];
int m_DemolistSelectedIndex;
bool m_DemolistSelectedIsDir;
int m_DemolistStorageType;
@ -444,7 +444,6 @@ protected:
std::chrono::nanoseconds m_DemoPopulateStartTime{0};
void DemolistOnUpdate(bool Reset);
//void DemolistPopulate();
static int DemolistFetchCallback(const CFsFileInfo *pInfo, int IsDir, int StorageType, void *pUser);
// friends

View file

@ -160,13 +160,17 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
static CButtonContainer s_ButtonOk;
if(DoButton_Menu(&s_ButtonOk, Localize("Ok"), 0, &Ok) || UI()->ConsumeHotkey(CUI::HOTKEY_ENTER))
{
if(str_comp(m_vDemos[m_DemolistSelectedIndex].m_aFilename, m_aCurrentDemoFile) == 0)
char aDemoName[IO_MAX_PATH_LENGTH];
DemoPlayer()->GetDemoName(aDemoName, sizeof(aDemoName));
str_append(aDemoName, ".demo", sizeof(aDemoName));
if(!str_endswith(m_aCurrentDemoFile, ".demo"))
str_append(m_aCurrentDemoFile, ".demo", sizeof(m_aCurrentDemoFile));
if(str_comp(aDemoName, m_aCurrentDemoFile) == 0)
str_copy(m_aDemoPlayerPopupHint, Localize("Please use a different name"));
else
{
if(!str_endswith(m_aCurrentDemoFile, ".demo"))
str_append(m_aCurrentDemoFile, ".demo", sizeof(m_aCurrentDemoFile));
char aPath[IO_MAX_PATH_LENGTH];
str_format(aPath, sizeof(aPath), "%s/%s", m_aCurrentDemoFolder, m_aCurrentDemoFile);
@ -179,6 +183,8 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
}
else
{
if(DemoFile)
io_close(DemoFile);
m_DemoPlayerState = DEMOPLAYER_NONE;
Client()->DemoSlice(aPath, CMenus::DemoFilterChat, &s_RemoveChat);
DemolistPopulate();
@ -509,7 +515,8 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
static CButtonContainer s_SliceSaveButton;
if(DoButton_FontIcon(&s_SliceSaveButton, "\xEF\x80\xBD", 0, &Button, IGraphics::CORNER_ALL))
{
str_copy(m_aCurrentDemoFile, m_vDemos[m_DemolistSelectedIndex].m_aFilename);
DemoPlayer()->GetDemoName(m_aCurrentDemoFile, sizeof(m_aCurrentDemoFile));
str_append(m_aCurrentDemoFile, ".demo", sizeof(m_aCurrentDemoFile));
m_aDemoPlayerPopupHint[0] = '\0';
m_DemoPlayerState = DEMOPLAYER_SLICE_SAVE;
}
@ -535,9 +542,9 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
GameClient()->m_Tooltips.DoToolTip(&s_KeyboardShortcutsButton, &Button, Localize("Toggle keyboard shortcuts"));
// demo name
char aDemoName[64] = {0};
char aDemoName[IO_MAX_PATH_LENGTH];
DemoPlayer()->GetDemoName(aDemoName, sizeof(aDemoName));
char aBuf[128];
char aBuf[IO_MAX_PATH_LENGTH + 128];
str_format(aBuf, sizeof(aBuf), Localize("Demofile: %s"), aDemoName);
CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, NameBar.x, NameBar.y + (NameBar.h - (Button.h * 0.5f)) / 2.f, Button.h * 0.5f, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
@ -817,7 +824,7 @@ int CMenus::DemolistFetchCallback(const CFsFileInfo *pInfo, int IsDir, int Stora
}
else
{
str_truncate(Item.m_aName, sizeof(Item.m_aName), pInfo->m_pName, str_length(pInfo->m_pName) - 5);
str_truncate(Item.m_aName, sizeof(Item.m_aName), pInfo->m_pName, str_length(pInfo->m_pName) - str_length(".demo"));
Item.m_InfosLoaded = false;
Item.m_Date = pInfo->m_TimeModified;
}
@ -880,7 +887,7 @@ bool CMenus::FetchHeader(CDemoItem &Item)
{
if(!Item.m_InfosLoaded)
{
char aBuffer[512];
char aBuffer[IO_MAX_PATH_LENGTH];
str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aCurrentDemoFolder, Item.m_aFilename);
Item.m_Valid = DemoPlayer()->GetDemoInfo(Storage(), aBuffer, Item.m_StorageType, &Item.m_Info, &Item.m_TimelineMarkers, &Item.m_MapInfo);
Item.m_InfosLoaded = true;
@ -1295,9 +1302,8 @@ void CMenus::RenderDemoList(CUIRect MainView)
fs_parent_dir(m_aCurrentDemoFolder);
else // sub folder
{
char aTemp[256];
str_copy(aTemp, m_aCurrentDemoFolder);
str_format(m_aCurrentDemoFolder, sizeof(m_aCurrentDemoFolder), "%s/%s", aTemp, m_vDemos[m_DemolistSelectedIndex].m_aFilename);
str_append(m_aCurrentDemoFolder, "/", sizeof(m_aCurrentDemoFolder));
str_append(m_aCurrentDemoFolder, m_vDemos[m_DemolistSelectedIndex].m_aFilename, sizeof(m_aCurrentDemoFolder));
m_DemolistStorageType = m_vDemos[m_DemolistSelectedIndex].m_StorageType;
}
DemolistPopulate();
@ -1305,7 +1311,7 @@ void CMenus::RenderDemoList(CUIRect MainView)
}
else // file
{
char aBuf[512];
char aBuf[IO_MAX_PATH_LENGTH];
str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_vDemos[m_DemolistSelectedIndex].m_aFilename);
const char *pError = Client()->DemoPlayer_Play(aBuf, m_vDemos[m_DemolistSelectedIndex].m_StorageType);
if(pError)