Fixed segfault in connect when specifying no database name.
authorMichael Meskes
Thu, 30 Dec 2004 09:36:37 +0000 (09:36 +0000)
committerMichael Meskes
Thu, 30 Dec 2004 09:36:37 +0000 (09:36 +0000)
src/interfaces/ecpg/ecpglib/connect.c
src/interfaces/ecpg/ecpglib/memory.c

index 2dded3a17d4a1f02117f7308d11e044743def9b0..6a621f99af8ac8125e70f9032e32f73497713893 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.23 2004/08/29 05:06:59 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.24 2004/12/30 09:36:37 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -242,7 +242,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
    struct sqlca_t *sqlca = ECPGget_sqlca();
    enum COMPAT_MODE compat = c;
    struct connection *this;
-   char       *dbname = strdup(name),
+   char       *dbname = name ? strdup(name) : NULL,
               *host = NULL,
               *tmp,
               *port = NULL,
@@ -275,75 +275,100 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
    if (dbname == NULL && connection_name == NULL)
        connection_name = "DEFAULT";
 
-   /* get the detail information out of dbname */
-   if (strchr(dbname, '@') != NULL)
-   {
-       /* old style: dbname[@server][:port] */
-       tmp = strrchr(dbname, ':');
-       if (tmp != NULL)        /* port number given */
-       {
-           port = strdup(tmp + 1);
-           *tmp = '\0';
-       }
-
-       tmp = strrchr(dbname, '@');
-       if (tmp != NULL)        /* host name given */
-       {
-           host = strdup(tmp + 1);
-           *tmp = '\0';
-       }
-       realname = strdup(dbname);
-   }
-   else if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
-   {
-       int         offset = 0;
-
-       /*
-        * only allow protocols tcp and unix
-        */
-       if (strncmp(dbname, "tcp:", 4) == 0)
-           offset = 4;
-       else if (strncmp(dbname, "unix:", 5) == 0)
-           offset = 5;
-
-       if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
+   if (dbname != NULL)
+   {   
+       /* get the detail information out of dbname */
+       if (strchr(dbname, '@') != NULL)
        {
-
-           /*------
-            * new style:
-            *  :postgresql://server[:port|:/unixsocket/path:]
-            *  [/db name][?options]
-            *------
-            */
-           offset += strlen("postgresql://");
-
-           tmp = strrchr(dbname + offset, '?');
-           if (tmp != NULL)    /* options given */
+           /* old style: dbname[@server][:port] */
+           tmp = strrchr(dbname, ':');
+           if (tmp != NULL)        /* port number given */
            {
-               options = strdup(tmp + 1);
+               port = strdup(tmp + 1);
                *tmp = '\0';
            }
 
-           tmp = last_dir_separator(dbname + offset);
-           if (tmp != NULL)    /* database name given */
+           tmp = strrchr(dbname, '@');
+           if (tmp != NULL)        /* host name given */
            {
-               realname = strdup(tmp + 1);
+               host = strdup(tmp + 1);
                *tmp = '\0';
            }
+           realname = strdup(dbname);
+       }
+       else if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
+       {
+           int         offset = 0;
+
+           /*
+            * only allow protocols tcp and unix
+            */
+           if (strncmp(dbname, "tcp:", 4) == 0)
+               offset = 4;
+           else if (strncmp(dbname, "unix:", 5) == 0)
+               offset = 5;
 
-           tmp = strrchr(dbname + offset, ':');
-           if (tmp != NULL)    /* port number or Unix socket path given */
+           if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
            {
-               char       *tmp2;
 
-               *tmp = '\0';
-               if ((tmp2 = strchr(tmp + 1, ':')) != NULL)
+               /*------
+                * new style:
+                *  :postgresql://server[:port|:/unixsocket/path:]
+                *  [/db name][?options]
+                *------
+                */
+               offset += strlen("postgresql://");
+
+               tmp = strrchr(dbname + offset, '?');
+               if (tmp != NULL)    /* options given */
+               {
+                   options = strdup(tmp + 1);
+                   *tmp = '\0';
+               }
+
+               tmp = last_dir_separator(dbname + offset);
+               if (tmp != NULL)    /* database name given */
                {
-                   *tmp2 = '\0';
-                   host = strdup(tmp + 1);
-                   if (strncmp(dbname, "unix:", 5) != 0)
+                   realname = strdup(tmp + 1);
+                   *tmp = '\0';
+               }
+
+               tmp = strrchr(dbname + offset, ':');
+               if (tmp != NULL)    /* port number or Unix socket path given */
+               {
+                   char       *tmp2;
+
+                   *tmp = '\0';
+                   if ((tmp2 = strchr(tmp + 1, ':')) != NULL)
                    {
-                       ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno);
+                       *tmp2 = '\0';
+                       host = strdup(tmp + 1);
+                       if (strncmp(dbname, "unix:", 5) != 0)
+                       {
+                           ECPGlog("connect: socketname %s given for TCP connection in line %d\n", host, lineno);
+                           ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : "");
+                           if (host)
+                               ECPGfree(host);
+                           if (port)
+                               ECPGfree(port);
+                           if (options)
+                               ECPGfree(options);
+                           if (realname)
+                               ECPGfree(realname);
+                           if (dbname)
+                               ECPGfree(dbname);
+                           return false;
+                       }
+                   }
+                   else
+                       port = strdup(tmp + 1);
+               }
+
+               if (strncmp(dbname, "unix:", 5) == 0)
+               {
+                   if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
+                   {
+                       ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
                        ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : "");
                        if (host)
                            ECPGfree(host);
@@ -359,37 +384,17 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
                    }
                }
                else
-                   port = strdup(tmp + 1);
-           }
+                   host = strdup(dbname + offset);
 
-           if (strncmp(dbname, "unix:", 5) == 0)
-           {
-               if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
-               {
-                   ECPGlog("connect: non-localhost access via sockets in line %d\n", lineno);
-                   ECPGraise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : "");
-                   if (host)
-                       ECPGfree(host);
-                   if (port)
-                       ECPGfree(port);
-                   if (options)
-                       ECPGfree(options);
-                   if (realname)
-                       ECPGfree(realname);
-                   if (dbname)
-                       ECPGfree(dbname);
-                   return false;
-               }
            }
            else
-               host = strdup(dbname + offset);
-
+               realname = strdup(dbname);
        }
        else
            realname = strdup(dbname);
    }
    else
-       realname = strdup(dbname);
+       realname = NULL;
 
    /* add connection to our list */
 #ifdef ENABLE_THREAD_SAFETY
index eff214d9fd8521284e04ddde6a313bdec1921273..97c8500b950785e6ab12fada6e1eaf6672b59e40 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.5 2003/11/29 19:52:08 pgsql Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.6 2004/12/30 09:36:37 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -46,8 +46,12 @@ ECPGrealloc(void *ptr, long size, int lineno)
 char *
 ECPGstrdup(const char *string, int lineno)
 {
-   char       *new = strdup(string);
+   char       *new;
 
+   if (string == NULL)
+       return NULL;
+   
+   new = strdup(string);
    if (!new)
    {
        ECPGraise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);