diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c index ec01f67b61..4f361510c3 100644 --- a/src/interfaces/ecpg/ecpglib/connect.c +++ b/src/interfaces/ecpg/ecpglib/connect.c @@ -516,9 +516,9 @@ 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 : ""); + /* count options (this may produce an overestimate, it's ok) */ if (options) for (i = 0; options[i]; i++) - /* count options */ if (options[i] == '=') connect_params++; @@ -585,8 +585,12 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p { char *str; - /* options look like this "option1 = value1 option2 = value2 ... */ - /* we have to break up the string into single options */ + /* + * The options string contains "keyword=value" pairs separated by + * '&'s. We must break this up into keywords and values to pass to + * libpq (it's okay to scribble on the options string). We ignore + * spaces just before each keyword or value. + */ for (str = options; *str;) { int e, @@ -594,13 +598,21 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p char *token1, *token2; - for (token1 = str; *token1 && *token1 == ' '; token1++); - for (e = 0; token1[e] && token1[e] != '='; e++); + /* Skip spaces before keyword */ + for (token1 = str; *token1 == ' '; token1++) + /* skip */ ; + /* Find end of keyword */ + for (e = 0; token1[e] && token1[e] != '='; e++) + /* skip */ ; if (token1[e]) /* found "=" */ { token1[e] = '\0'; - for (token2 = token1 + e + 1; *token2 && *token2 == ' '; token2++); - for (a = 0; token2[a] && token2[a] != '&'; a++); + /* Skip spaces before value */ + for (token2 = token1 + e + 1; *token2 == ' '; token2++) + /* skip */ ; + /* Find end of value */ + for (a = 0; token2[a] && token2[a] != '&'; a++) + /* skip */ ; if (token2[a]) /* found "&" => another option follows */ { token2[a] = '\0'; @@ -614,11 +626,14 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p i++; } else - /* the parser should not be able to create this invalid option */ + { + /* Bogus options syntax ... ignore trailing garbage */ str = token1 + e; + } } - } + + Assert(i <= connect_params); conn_keywords[i] = NULL; /* terminator */ this->connection = PQconnectdbParams(conn_keywords, conn_values, 0);