Hi, Fix progname memory leak in ecpg client. Issue taken from todo list https://wiki.postgresql.org/wiki/Todo.
Best regards, Maksim Kita
>From 2f730117cbff1207c6b0bffc3097831fe5028fec Mon Sep 17 00:00:00 2001 From: Maksim Kita <kitaet...@gmail.com> Date: Wed, 7 Oct 2020 14:15:52 +0300 Subject: [PATCH] ecpg: fix progname memory leak Added goto on error cleanup for progname in ecpg main. Issue taken from todo list https://wiki.postgresql.org/wiki/Todo. --- src/interfaces/ecpg/preproc/ecpg.c | 33 ++++++++++++++------ src/interfaces/ecpg/preproc/preproc_extern.h | 1 + 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c index 44a6d5119b..1be9483d88 100644 --- a/src/interfaces/ecpg/preproc/ecpg.c +++ b/src/interfaces/ecpg/preproc/ecpg.c @@ -127,7 +127,7 @@ main(int argc, char *const argv[]) bool verbose = false, header_mode = false; struct _include_path *ip; - const char *progname; + const char *progname = NULL; char my_exec_path[MAXPGPATH]; char include_path[MAXPGPATH]; @@ -138,7 +138,8 @@ main(int argc, char *const argv[]) if (find_my_exec(argv[0], my_exec_path) < 0) { fprintf(stderr, _("%s: could not locate my own executable path\n"), argv[0]); - return ILLEGAL_OPTION; + ret_value = ILLEGAL_OPTION; + goto err; } if (argc > 1) @@ -146,12 +147,14 @@ main(int argc, char *const argv[]) if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(progname); - exit(0); + ret_value = EXIT_OK; + goto err; } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { printf("ecpg (PostgreSQL) %s\n", PG_VERSION); - exit(0); + ret_value = EXIT_OK; + goto err; } } @@ -216,7 +219,8 @@ main(int argc, char *const argv[]) else { fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]); - return ILLEGAL_OPTION; + ret_value = ILLEGAL_OPTION; + goto err; } break; case 'r': @@ -229,7 +233,8 @@ main(int argc, char *const argv[]) else { fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]); - return ILLEGAL_OPTION; + ret_value = ILLEGAL_OPTION; + goto err; } break; case 'D': @@ -245,7 +250,8 @@ main(int argc, char *const argv[]) break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]); - return ILLEGAL_OPTION; + ret_value = ILLEGAL_OPTION; + goto err; } } @@ -264,14 +270,16 @@ main(int argc, char *const argv[]) for (ip = include_paths; ip != NULL; ip = ip->next) fprintf(stderr, " %s\n", ip->path); fprintf(stderr, _("end of search list\n")); - return 0; + ret_value = EXIT_OK; + goto err; } if (optind >= argc) /* no files specified */ { fprintf(stderr, _("%s: no input files specified\n"), progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), argv[0]); - return ILLEGAL_OPTION; + ret_value = ILLEGAL_OPTION; + goto err; } else { @@ -473,7 +481,7 @@ main(int argc, char *const argv[]) /* * If there was an error, delete the output file. */ - if (ret_value != 0) + if (ret_value != EXIT_OK) { if (strcmp(output_filename, "-") != 0 && unlink(output_filename) != 0) fprintf(stderr, _("could not remove output file \"%s\"\n"), output_filename); @@ -489,5 +497,10 @@ main(int argc, char *const argv[]) free(input_filename); } } + +err: + if (progname) + free((void*)(progname)); + return ret_value; } diff --git a/src/interfaces/ecpg/preproc/preproc_extern.h b/src/interfaces/ecpg/preproc/preproc_extern.h index 51d5f94f07..5728dd8a96 100644 --- a/src/interfaces/ecpg/preproc/preproc_extern.h +++ b/src/interfaces/ecpg/preproc/preproc_extern.h @@ -106,6 +106,7 @@ extern int filtered_base_yylex(void); /* return codes */ +#define EXIT_OK 0 #define ILLEGAL_OPTION 1 #define NO_INCLUDE_FILE 2 #define PARSE_ERROR 3 -- 2.25.1