From 5e7710e725b1d1fe408ac20548d872cc52f7b8ab Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Fri, 17 Feb 2012 14:53:22 +0100 Subject: [PATCH] Make sure all connection paramters are used in call to PQconnectdbParams. --- src/interfaces/ecpg/ecpglib/connect.c | 83 ++++++++++++++++--- src/interfaces/ecpg/test/connect/test5.pgc | 3 + .../ecpg/test/expected/connect-test1.stderr | 2 +- .../ecpg/test/expected/connect-test5.c | 19 +++-- .../ecpg/test/expected/connect-test5.stderr | 12 ++- 5 files changed, 98 insertions(+), 21 deletions(-) diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c index 15384ec352..b874d860e2 100644 --- a/src/interfaces/ecpg/ecpglib/connect.c +++ b/src/interfaces/ecpg/ecpglib/connect.c @@ -267,15 +267,15 @@ 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; - int i; + int i, connect_params = 0; char *dbname = name ? ecpg_strdup(name, lineno) : NULL, *host = NULL, *tmp, *port = NULL, *realname = NULL, *options = NULL; - const char *conn_keywords[7]; - const char *conn_values[6]; + const char **conn_keywords; + const char **conn_values; ecpg_init_sqlca(sqlca); @@ -359,7 +359,10 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p if (tmp != NULL) /* database name given */ { if (tmp[1] != '\0') /* non-empty database name */ + { realname = ecpg_strdup(tmp + 1, lineno); + connect_params++; + } *tmp = '\0'; } @@ -373,6 +376,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p { *tmp2 = '\0'; host = ecpg_strdup(tmp + 1, lineno); + connect_params++; if (strncmp(dbname, "unix:", 5) != 0) { ecpg_log("ECPGconnect: socketname %s given for TCP connection on line %d\n", host, lineno); @@ -394,7 +398,10 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p } } else + { port = ecpg_strdup(tmp + 1, lineno); + connect_params++; + } } if (strncmp(dbname, "unix:", 5) == 0) @@ -418,7 +425,10 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p } } else + { host = ecpg_strdup(dbname + offset, lineno); + connect_params++; + } } } @@ -429,6 +439,7 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p if (tmp != NULL) /* port number given */ { port = ecpg_strdup(tmp + 1, lineno); + connect_params++; *tmp = '\0'; } @@ -436,10 +447,17 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p if (tmp != NULL) /* host name given */ { host = ecpg_strdup(tmp + 1, lineno); + connect_params++; *tmp = '\0'; } - realname = (strlen(dbname) > 0) ? ecpg_strdup(dbname, lineno) : NULL; + if (strlen(dbname) > 0) + { + realname = ecpg_strdup(dbname, lineno); + connect_params++; + } + else + realname = NULL; } } else @@ -475,10 +493,35 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p options ? "with options " : "", options ? options : "", (user && strlen(user) > 0) ? "for user " : "", user ? user : ""); - if (options) /* replace '&' if there are any */ + if (options) for (i = 0; options[i]; i++) - if (options[i] == '&') - options[i] = ' '; + /* count options */ + if (options[i] == '=') + connect_params++; + + if (user && strlen(user) > 0) + connect_params++; + if (passwd && strlen(passwd) > 0) + connect_params++; + + /* allocate enough space for all connection parameters */ + conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof (char *), lineno); + conn_values = (const char **) ecpg_alloc(connect_params * sizeof (char *), lineno); + if (conn_keywords == NULL || conn_values == NULL) + { + if (host) + ecpg_free(host); + if (port) + ecpg_free(port); + if (options) + ecpg_free(options); + if (realname) + ecpg_free(realname); + if (dbname) + ecpg_free(dbname); + free(this); + return false; + } i = 0; if (realname) @@ -513,9 +556,27 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p } if (options) { - conn_keywords[i] = "options"; - conn_values[i] = options; - i++; + char *saveptr, *token1, *token2, *str; + + /* options look like this "option1 = value1 option2 = value2 ... */ + /* we have to break up the string into single options */ + for (str = options; ; str = NULL) + { + token1 = strtok_r(str, "=", &saveptr); + if (token1 == NULL) + break; + /* strip leading blanks */ + for (; *token1 && *token1 == ' '; token1++); + + token2 = strtok_r(NULL, "&", &saveptr); + if (token2 == NULL) + break; + + conn_keywords[i] = token1; + conn_values[i] = token2; + i++; + } + } conn_keywords[i] = NULL; /* terminator */ @@ -529,6 +590,8 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p ecpg_free(options); if (dbname) ecpg_free(dbname); + ecpg_free(conn_values); + ecpg_free(conn_keywords); if (PQstatus(this->connection) == CONNECTION_BAD) { diff --git a/src/interfaces/ecpg/test/connect/test5.pgc b/src/interfaces/ecpg/test/connect/test5.pgc index c747a5b437..d3efecbf62 100644 --- a/src/interfaces/ecpg/test/connect/test5.pgc +++ b/src/interfaces/ecpg/test/connect/test5.pgc @@ -53,6 +53,9 @@ exec sql end declare section; exec sql connect to 'unix:postgresql://localhost/connectdb' as main user :user; exec sql disconnect main; + exec sql connect to unix:postgresql://localhost/connectdb?connect_timeout=14&client_encoding=latin1 as main user connectuser; + exec sql disconnect main; + exec sql connect to "unix:postgresql://200.46.204.71/connectdb" as main user connectuser; exec sql disconnect main; diff --git a/src/interfaces/ecpg/test/expected/connect-test1.stderr b/src/interfaces/ecpg/test/expected/connect-test1.stderr index de1bf17121..e755a0a345 100644 --- a/src/interfaces/ecpg/test/expected/connect-test1.stderr +++ b/src/interfaces/ecpg/test/expected/connect-test1.stderr @@ -52,7 +52,7 @@ [NO_PID]: ECPGconnect: opening database connectdb on localhost port for user connectuser [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ECPGconnect: could not open database: could not connect to server: Connection refused - Is the server running on host "localhost" and accepting + Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 20? [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/connect-test5.c b/src/interfaces/ecpg/test/expected/connect-test5.c index 8804eaaf9e..a8f79f9a95 100644 --- a/src/interfaces/ecpg/test/expected/connect-test5.c +++ b/src/interfaces/ecpg/test/expected/connect-test5.c @@ -115,34 +115,41 @@ main(void) #line 54 "test5.pgc" - { ECPGconnect(__LINE__, 0, "unix:postgresql://200.46.204.71/connectdb" , "connectuser" , NULL , "main", 0); } + { ECPGconnect(__LINE__, 0, "unix:postgresql://localhost/connectdb?connect_timeout=14 & client_encoding=latin1" , "connectuser" , NULL , "main", 0); } #line 56 "test5.pgc" { ECPGdisconnect(__LINE__, "main");} #line 57 "test5.pgc" - { ECPGconnect(__LINE__, 0, "unix:postgresql://localhost/" , "connectdb" , NULL , "main", 0); } + { ECPGconnect(__LINE__, 0, "unix:postgresql://200.46.204.71/connectdb" , "connectuser" , NULL , "main", 0); } #line 59 "test5.pgc" { ECPGdisconnect(__LINE__, "main");} #line 60 "test5.pgc" + { ECPGconnect(__LINE__, 0, "unix:postgresql://localhost/" , "connectdb" , NULL , "main", 0); } +#line 62 "test5.pgc" + + { ECPGdisconnect(__LINE__, "main");} +#line 63 "test5.pgc" + + /* connect twice */ { ECPGconnect(__LINE__, 0, "connectdb" , NULL, NULL , "main", 0); } -#line 63 "test5.pgc" +#line 66 "test5.pgc" { ECPGconnect(__LINE__, 0, "connectdb" , NULL, NULL , "main", 0); } -#line 64 "test5.pgc" +#line 67 "test5.pgc" { ECPGdisconnect(__LINE__, "main");} -#line 65 "test5.pgc" +#line 68 "test5.pgc" /* not connected */ { ECPGdisconnect(__LINE__, "nonexistant");} -#line 68 "test5.pgc" +#line 71 "test5.pgc" return (0); diff --git a/src/interfaces/ecpg/test/expected/connect-test5.stderr b/src/interfaces/ecpg/test/expected/connect-test5.stderr index ea6f9e2591..9b40555984 100644 --- a/src/interfaces/ecpg/test/expected/connect-test5.stderr +++ b/src/interfaces/ecpg/test/expected/connect-test5.stderr @@ -46,11 +46,15 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection main closed [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ECPGconnect: non-localhost access via sockets on line 56 +[NO_PID]: ECPGconnect: opening database connectdb on port with options connect_timeout=14 & client_encoding=latin1 for user connectuser [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: raising sqlcode -402 on line 56: could not connect to database "connectdb" on line 56 +[NO_PID]: ecpg_finish: connection main closed +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: non-localhost access via sockets on line 59 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode -402 on line 59: could not connect to database "connectdb" on line 59 [NO_PID]: sqlca: code: -402, state: 08001 -[NO_PID]: raising sqlcode -220 on line 57: connection "main" does not exist on line 57 +[NO_PID]: raising sqlcode -220 on line 60: connection "main" does not exist on line 60 [NO_PID]: sqlca: code: -220, state: 08003 [NO_PID]: ECPGconnect: opening database on port for user connectdb [NO_PID]: sqlca: code: 0, state: 00000 @@ -62,5 +66,5 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection main closed [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: raising sqlcode -220 on line 68: connection "nonexistant" does not exist on line 68 +[NO_PID]: raising sqlcode -220 on line 71: connection "nonexistant" does not exist on line 71 [NO_PID]: sqlca: code: -220, state: 08003 -- 2.40.0