Fixed one memory leak in descriptor code.
authorMichael Meskes <meskes@postgresql.org>
Mon, 11 Jun 2007 11:52:08 +0000 (11:52 +0000)
committerMichael Meskes <meskes@postgresql.org>
Mon, 11 Jun 2007 11:52:08 +0000 (11:52 +0000)
Made sure ecpg deletes output file in case of an error.

src/interfaces/ecpg/ecpglib/descriptor.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/preproc/extern.h
src/interfaces/ecpg/preproc/preproc.y

index 88d07c0b8dd89f3f06231c2364b8247cd643ae5f..0a4ecf86fc752e04fd47c790fce60cf78f49c104 100644 (file)
@@ -1,6 +1,6 @@
 /* dynamic SQL support routines
  *
- * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.21 2007/04/27 06:56:11 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.22 2007/06/11 11:52:08 meskes Exp $
  */
 
 #define POSTGRES_ECPG_INTERNAL
@@ -547,7 +547,7 @@ ECPGset_desc(int lineno, const char *desc_name, int index,...)
                        ECPGfree(var);
                        return false;
                    }
-
+                   ECPGfree(desc_item->data); /* free() takes care of a potential NULL value */
                    desc_item->data = (char *) tobeinserted;
                    tobeinserted = NULL;
                    break;
@@ -607,6 +607,18 @@ ECPGdeallocate_desc(int line, const char *name)
    {
        if (!strcmp(name, i->name))
        {
+           struct descriptor_item *desc_item;
+
+           for (desc_item = i->items; desc_item;)
+           {
+               struct descriptor_item *di;
+
+               ECPGfree(desc_item->data);
+               di = desc_item;
+               desc_item = desc_item->next;
+               ECPGfree(di);
+           }
+
            *lastptr = i->next;
            ECPGfree(i->name);
            PQclear(i->result);
index 79e3e1bafbfa97f6c73542e5fa0cb702d8518a86..5c3ecf6461f0534c3f21f62ed75f7a13067e974e 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.66 2007/04/27 06:56:11 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.67 2007/06/11 11:52:08 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -48,7 +48,7 @@ quote_postgres(char *arg, bool quote, int lineno)
     * will be quoted once they are inserted in a statement
     */
    if (!quote)
-       return res = ECPGstrdup(arg, lineno);
+       return arg;
    else
    {
        length = strlen(arg);
index e419a199db7fda53d398ff259219934956d1f50e..e5439a9622ea37ab88fc09b42d728ca9c12729e3 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.98 2007/03/17 19:25:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.99 2007/06/11 11:52:08 meskes Exp $ */
 
 /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
 /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
@@ -20,6 +20,8 @@ int           ret_value = 0,
            header_mode = false,
            regression_mode = false;
 
+char      *output_filename;
+
 enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL;
 
 struct _include_path *include_paths = NULL;
@@ -135,6 +137,7 @@ main(int argc, char *const argv[])
 
    find_my_exec(argv[0], my_exec_path);
 
+   output_filename = NULL;
    while ((c = getopt_long(argc, argv, "vcio:I:tD:dC:r:h?", ecpg_options, NULL)) != -1)
    {
        switch (c)
@@ -163,14 +166,18 @@ main(int argc, char *const argv[])
                regression_mode = true;
                break;
            case 'o':
-               if (strcmp(optarg, "-") == 0)
+               output_filename = optarg;
+               if (strcmp(output_filename, "-") == 0)
                    yyout = stdout;
                else
-                   yyout = fopen(optarg, PG_BINARY_W);
+                   yyout = fopen(output_filename, PG_BINARY_W);
 
-               if (yyout == NULL)
+               if (yyout == NULL) 
+               {
                    fprintf(stderr, "%s: could not open file \"%s\": %s\n",
-                           progname, optarg, strerror(errno));
+                           progname, output_filename, strerror(errno));
+                   output_filename = NULL;
+               }
                else
                    out_option = 1;
                break;
@@ -269,8 +276,7 @@ main(int argc, char *const argv[])
        /* after the options there must not be anything but filenames */
        for (fnr = optind; fnr < argc; fnr++)
        {
-           char       *output_filename = NULL,
-                      *ptr2ext;
+           char *ptr2ext;
 
            /* If argv[fnr] is "-" we have to read from stdin */
            if (strcmp(argv[fnr], "-") == 0)
@@ -467,7 +473,7 @@ main(int argc, char *const argv[])
                    fclose(yyout);
            }
 
-           if (output_filename)
+           if (output_filename && out_option == 0)
                free(output_filename);
 
            free(input_filename);
index 1d0835d706e28dca8db55647f1b43b2be04ea9a6..4a2cfaf747c9be1ccb1c4b27817a4e6873d5b685 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.65 2007/03/17 19:25:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/extern.h,v 1.66 2007/06/11 11:52:08 meskes Exp $ */
 
 #ifndef _ECPG_PREPROC_EXTERN_H
 #define _ECPG_PREPROC_EXTERN_H
@@ -37,6 +37,7 @@ extern int    yylineno,
            yyleng;
 extern FILE *yyin,
           *yyout;
+extern char *output_filename;
 
 extern struct _include_path *include_paths;
 extern struct cursor *cur;
@@ -93,7 +94,7 @@ extern ScanKeyword *ScanKeywordLookup(char *text);
 extern void scanner_init(const char *);
 extern void parser_init(void);
 extern void scanner_finish(void);
-int filtered_base_yylex(void);
+extern int filtered_base_yylex(void);
 
 /* return codes */
 
index 69c8d7de0113f946a8514f6ddf8f21c7e184653c..80dc3765827858c22e517302e4e3401df464cbba 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.343 2007/05/10 09:53:17 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.344 2007/06/11 11:52:08 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -99,6 +99,10 @@ mmerror(int error_code, enum errortype type, char * error, ...)
            ret_value = error_code;
            break;
        case ET_FATAL:
+           fclose(yyin);
+           fclose(yyout);
+           if (unlink(output_filename) != 0)
+               fprintf(stderr, "Could not remove ourput file %s!\n", output_filename);
            exit(error_code);
    }
 }