]> granicus.if.org Git - postgresql/commitdiff
Cosmetic improvements for options-handling code in ECPGconnect().
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 31 Aug 2019 17:37:10 +0000 (13:37 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 31 Aug 2019 17:37:10 +0000 (13:37 -0400)
The comment describing the string format was a lie.  Make it agree with
reality, add/improve some other comments, fix coding style for loops with
empty bodies.  Also add an Assert that we counted parameters correctly,
because the spread-out logic for that looks pretty fragile.

No actual bugs fixed here, so no need to back-patch.

Discussion: https://postgr.es/m/848B1649C8A6274AA527C4472CA11EDD5FC70CBE@G01JPEXMBYT02

src/interfaces/ecpg/ecpglib/connect.c

index ec01f67b61d5e8f0b88f84346451d2135a78b777..4f361510c36575ec64078401942efd9bc034dcb3 100644 (file)
@@ -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);