From bd4c48d1beabdf92932f5f5544db89c9cd6d61ec Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Wed, 26 Jul 2023 10:18:36 +0300 Subject: [PATCH 20/20] Free encoding buffers on non-readline builds See osdn #48445 Signed-off-by: Marko Lindqvist --- server/handchat.c | 5 +++-- server/sernet.c | 25 ++++++++++++------------- server/stdinhand.c | 17 ++++++++++++++++- server/stdinhand.h | 1 + 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/server/handchat.c b/server/handchat.c index 87abc2ec40..b3eb923705 100644 --- a/server/handchat.c +++ b/server/handchat.c @@ -340,8 +340,9 @@ void handle_chat_msg_req(struct connection *pconn, const char *message) or change it in chat.h - rp */ 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); + /* Pass it to the command parser, which will chop the prefix off */ + handle_stdin_input(pconn, real_message); + return; } diff --git a/server/sernet.c b/server/sernet.c index d70d271cdb..4718f42d17 100644 --- a/server/sernet.c +++ b/server/sernet.c @@ -154,6 +154,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 /****************************************************************************/ @@ -163,7 +165,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. @@ -186,9 +187,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; @@ -214,12 +213,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 */ } /*************************************************************************//** @@ -829,11 +828,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 */ @@ -873,12 +872,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 e03d32027d..0a0b82b0f9 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