From 1fbdb6bc9f7740ab0d5a3495efa20c1ef522258a Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Thu, 30 Dec 2004 09:36:37 +0000 Subject: [PATCH] Fixed segfault in connect when specifying no database name. --- src/interfaces/ecpg/ecpglib/connect.c | 167 +++++++++++++------------- src/interfaces/ecpg/ecpglib/memory.c | 8 +- 2 files changed, 92 insertions(+), 83 deletions(-) diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c index 2dded3a17d..6a621f99af 100644 --- a/src/interfaces/ecpg/ecpglib/connect.c +++ b/src/interfaces/ecpg/ecpglib/connect.c @@ -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 diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c index eff214d9fd..97c8500b95 100644 --- a/src/interfaces/ecpg/ecpglib/memory.c +++ b/src/interfaces/ecpg/ecpglib/memory.c @@ -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); -- 2.40.0