From 2e3a2ed08cb015c0f6816174b5a06fcba13b3a91 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 12 Dec 2020 11:29:43 +1100 Subject: [PATCH] Fix stack overflow happening when the game fails to create the logs directory (Thanks Fantasy) This was particularly annoying, because the game would immediately just close without showing the usual crash message box --- src/Chat.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Chat.c b/src/Chat.c index 790dac477..14f575152 100644 --- a/src/Chat.c +++ b/src/Chat.c @@ -108,10 +108,34 @@ void Chat_DisableLogging(void) { CloseLogFile(); } +static cc_bool CreateLogsDirectory(void) { + static const cc_string dir = String_FromConst("logs"); + cc_result res; + /* Utils_EnsureDirectory cannot be used here because it causes a stack overflow */ + /* when running the game and an error occurs when trying to create the directory */ + /* This happens because when running the game, Logger_WarnFunc is changed to log + /* a message in chat instead of showing a dialog box, which causes the following + /* functions to be called in a recursive loop: */ + /* */ + /* Utils_EnsureDirectory --> Logger_SysWarn2 --> Chat_Add --> AppendChatLog -> OpenChatLog */ + /* --> Utils_EnsureDirectory --> Logger_SysWarn2 --> Chat_Add --> AppendChatLog -> OpenChatLog */ + /* --> Utils_EnsureDirectory --> Logger_SysWarn2 --> Chat_Add --> AppendChatLog -> OpenChatLog */ + /* --> Utils_EnsureDirectory --> Logger_SysWarn2 --> Chat_Add --> AppendChatLog ... */ + /* and so on, until eventually the stack overflows */ + if (Directory_Exists(&dir)) return true; + + res = Directory_Create(&dir); + if (!res) return true; + + Chat_DisableLogging(); + Logger_SysWarn2(res, "creating directory", &dir); + return false; +} + static void OpenChatLog(struct DateTime* now) { cc_result res; int i; - if (!Utils_EnsureDirectory("logs")) { Chat_DisableLogging(); return; } + if (!CreateLogsDirectory()) return; /* Ensure multiple instances do not end up overwriting each other's log entries. */ for (i = 0; i < 20; i++) {