From 9c46ddddb66b21d4afcc4a7aa5cca4ac52f854d1 Mon Sep 17 00:00:00 2001 From: Kevin Easton Date: Sat, 15 Jul 2017 00:07:25 +1000 Subject: [PATCH] Check for unset MSGLOG_FILE or CTOOLZ_DIR, or failed stat(), in readlog() Unset MSGLOG_FILE or CTOOLZ_DIR could cause a null pointer dereference. If stat() failed it dereferenced the bogus 'struct stat', and in the directory case just silently failed. Now it falls through to the "error opening" path. --- Changelog | 2 ++ source/readlog.c | 44 ++++++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Changelog b/Changelog index 44b5304..9856c81 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,7 @@ [Changes 1.2.2] +* Improve error handling in /READLOG. (caf) + * Fix memory leak in /QUEUE -FLUSH. (caf) * Messages sent by /SV and /PASTE should be logged in the send log. (caf) diff --git a/source/readlog.c b/source/readlog.c index 0cef35a..96f5768 100644 --- a/source/readlog.c +++ b/source/readlog.c @@ -74,14 +74,11 @@ static int in_read_log = 0; BUILT_IN_COMMAND(readlog) { char *expand; - struct stat stat_buf; - char *filename = NULL; - char buffer[BIG_BUFFER_SIZE + 1]; + struct stat stat_buf; + char *filename = NULL; read_log_func = fgets; - if (!get_string_var(MSGLOGFILE_VAR)) - if (!args || (args && !*args)) - return; + if (msg_window) return; @@ -93,36 +90,47 @@ BUILT_IN_COMMAND(readlog) if (args && !my_strnicmp(args, "-resume", 2)) { next_arg(args, &args); - read_log_func = (char *(*)(char *, int, FILE *))global[RFGETS]; + read_log_func = &rfgets; } } - } + } + if (args && *args) + { malloc_sprintf(&filename, "%s", args); + } else + { + const char *ctoolz_dir = get_string_var(CTOOLZ_DIR_VAR); + const char *msglogfile = get_string_var(MSGLOGFILE_VAR); + + if (!ctoolz_dir || !msglogfile) + return; + malloc_sprintf(&filename, "%s/%s", get_string_var(CTOOLZ_DIR_VAR), get_string_var(MSGLOGFILE_VAR)); + } + expand = expand_twiddle(filename); new_free(&filename); - stat(expand, &stat_buf); - strcpy(buffer, expand); - - if (stat_buf.st_mode & S_IFDIR) - return; - if ((msg_fp = fopen(expand, "r")) == NULL) + if (stat(expand, &stat_buf) == 0 && !(stat_buf.st_mode & S_IFDIR)) + msg_fp = fopen(expand, "r"); + + if (msg_fp == NULL) { log_put_it(expand, "%s Error Opening Log file %s", thing_ansi, expand); new_free(&expand); - msg_fp = NULL; return; } - if (read_log_func == (char *(*)(char *, int, FILE *))global[RFGETS]) + + if (read_log_func == &rfgets) fseek(msg_fp, 0, SEEK_END); - new_free(&expand); + msg_window = current_window; msg_screen = current_window->screen; - log_prompt(buffer, NULL); + log_prompt(expand, NULL); + new_free(&expand); } /*