From aa44ed9cf16ea4d9619797f35abe182c40cb6563 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 26 Jul 2023 10:14:41 +0300 Subject: [PATCH 25/25] Free encoding buffers on non-readline builds See osdn #48445 Signed-off-by: Marko Lindqvist --- server/handchat.c | 3 ++- server/sernet.c | 25 ++++++++++++------------- server/stdinhand.c | 17 ++++++++++++++++- server/stdinhand.h | 1 + 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/server/handchat.c b/server/handchat.c index c216c3dfca..a40874bcbc 100644 --- a/server/handchat.c +++ b/server/handchat.c @@ -347,7 +347,8 @@ void handle_chat_msg_req(struct connection *pconn, const char *message) */ if (real_message[0] == SERVER_COMMAND_PREFIX) { /* Pass it to the command parser, which will chop the prefix off */ - (void) handle_stdin_input(pconn, real_message); + handle_stdin_input(pconn, real_message); + return; } diff --git a/server/sernet.c b/server/sernet.c index 51570b77c6..dad9b6a53b 100644 --- a/server/sernet.c +++ b/server/sernet.c @@ -149,6 +149,8 @@ static void handle_stdin_close(void) #endif /* FREECIV_HAVE_LIBREADLINE || (!FREECIV_SOCKET_ZERO_NOT_STDIN && !FREECIV_HAVE_LIBREADLINE) */ +static char *current_internal = NULL; + #ifdef FREECIV_HAVE_LIBREADLINE /****************************************************************************/ @@ -158,7 +160,6 @@ static void handle_stdin_close(void) static char *history_file = NULL; static bool readline_handled_input = FALSE; static bool readline_initialized = FALSE; -static char *current_internal = NULL; /*************************************************************************//** Readline callback for input. @@ -181,9 +182,7 @@ static void handle_readline_input_callback(char *line) con_prompt_enter(); /* just got an 'Enter' hit */ current_internal = local_to_internal_string_malloc(line); free(line); /* This is already freed if we exit() with /quit command */ - (void) handle_stdin_input(NULL, current_internal); - free(current_internal); /* Since handle_stdin_input() returned, - * we can be sure this was not freed in atexit. */ + handle_stdin_input_free(NULL, current_internal); current_internal = NULL; readline_handled_input = TRUE; @@ -209,12 +208,12 @@ void readline_atexit(void) rl_callback_handler_remove(); readline_initialized = FALSE; } +#endif /* FREECIV_HAVE_LIBREADLINE */ if (current_internal != NULL) { free(current_internal); current_internal = NULL; } -#endif /* FREECIV_HAVE_LIBREADLINE */ } /*************************************************************************//** @@ -825,11 +824,11 @@ enum server_events server_sniff_all_input(void) } #ifdef FREECIV_SOCKET_ZERO_NOT_STDIN if (!no_input && (bufptr = fc_read_console())) { - char *bufptr_internal = local_to_internal_string_malloc(bufptr); + current_internal = local_to_internal_string_malloc(bufptr); - con_prompt_enter(); /* will need a new prompt, regardless */ - handle_stdin_input(NULL, bufptr_internal); - free(bufptr_internal); + con_prompt_enter(); /* Will need a new prompt, regardless */ + handle_stdin_input_free(NULL, current_internal); + current_internal = NULL; } #else /* !FREECIV_SOCKET_ZERO_NOT_STDIN */ if (!no_input && FD_ISSET(0, &readfs)) { /* input from server operator */ @@ -869,12 +868,12 @@ enum server_events server_sniff_all_input(void) handle_stdin_close(); } - con_prompt_enter(); /* will need a new prompt, regardless */ + con_prompt_enter(); /* Will need a new prompt, regardless */ if (didget >= 0) { - buf_internal = local_to_internal_string_malloc(buffer); - handle_stdin_input(NULL, buf_internal); - free(buf_internal); + current_internal = local_to_internal_string_malloc(buffer); + handle_stdin_input_free(NULL, current_internal); + current_internal = NULL; } free(buffer); #endif /* !FREECIV_HAVE_LIBREADLINE */ diff --git a/server/stdinhand.c b/server/stdinhand.c index 63e5ba32c0..9e751fb1ce 100644 --- a/server/stdinhand.c +++ b/server/stdinhand.c @@ -4419,13 +4419,28 @@ static bool quit_game(struct connection *caller, bool check) } /**********************************************************************//** - Main entry point for "command input". + Main entry point for "command input". Version to be used with + statically allocated 'str' **************************************************************************/ bool handle_stdin_input(struct connection *caller, char *str) { return handle_stdin_input_real(caller, str, FALSE, 0); } +/**********************************************************************//** + Entry point for "command input". Version that frees 'str' in the end. +**************************************************************************/ +bool handle_stdin_input_free(struct connection *caller, char *str) +{ + bool ret = handle_stdin_input_real(caller, str, FALSE, 0); + + /* Since handle_stdin_input_real() returned, + * we can be sure this was not freed in atexit(). */ + free(str); + + return ret; +} + /**********************************************************************//** Handle "command input", which could really come from stdin on console, or from client chat command, or read from file with -r, etc. diff --git a/server/stdinhand.h b/server/stdinhand.h index 6a210dc2fd..a225f58f45 100644 --- a/server/stdinhand.h +++ b/server/stdinhand.h @@ -31,6 +31,7 @@ void cmd_reply(enum command_id cmd, struct connection *caller, fc__attribute((__format__ (__printf__, 4, 5))); bool handle_stdin_input(struct connection *caller, char *str); +bool handle_stdin_input_free(struct connection *caller, char *str); void set_ai_level_direct(struct player *pplayer, enum ai_level level); bool read_init_script(struct connection *caller, const char *script_filename, bool from_cmdline, bool check); -- 2.40.1