libpq: change PQconndefaults() to ignore invalid service files
authorBruce Momjian <bruce@momjian.us>
Tue, 3 Dec 2013 16:11:56 +0000 (11:11 -0500)
committerBruce Momjian <bruce@momjian.us>
Tue, 3 Dec 2013 16:12:25 +0000 (11:12 -0500)
Previously missing or invalid service files returned NULL.  Also fix
pg_upgrade to report "out of memory" for a null return from
PQconndefaults().

Patch by Steve Singer, rewritten by me

contrib/pg_upgrade/server.c
doc/src/sgml/libpq.sgml
src/interfaces/libpq/fe-auth.c
src/interfaces/libpq/fe-auth.h
src/interfaces/libpq/fe-connect.c

index b75f5530edfb3948ac12e0fd96f28b3c5e1cbe92..7d2aa352c802873e8848d3f30a16f6fc5c4021f3 100644 (file)
@@ -325,6 +325,9 @@ check_pghost_envvar(void)
 
        start = PQconndefaults();
 
+       if (!start)
+               pg_fatal("out of memory\n");
+               
        for (option = start; option->keyword != NULL; option++)
        {
                if (option->envvar && (strcmp(option->envvar, "PGHOST") == 0 ||
index 955f248b13a39b67c99fb67a7e6772141e956aa5..503a63a58bdc9c544ef58cb2fcaa92f2ead28388 100644 (file)
@@ -483,7 +483,8 @@ typedef struct
        with an entry having a null <structfield>keyword</> pointer.  The
        null pointer is returned if memory could not be allocated. Note that
        the current default values (<structfield>val</structfield> fields)
-       will depend on environment variables and other context.  Callers
+       will depend on environment variables and other context.  A
+       missing or invalid service file will be silently ignored.  Callers
        must treat the connection options data as read-only.
       </para>
 
index 975f7958d11567ce93e8b7a384e3b2578c4884bb..979714055e34335743af8b6c72b0281f6cf9dd27 100644 (file)
@@ -982,7 +982,7 @@ pg_fe_sendauth(AuthRequest areq, PGconn *conn)
  * if there is an error, return NULL with an error message in errorMessage
  */
 char *
-pg_fe_getauthname(PQExpBuffer errorMessage)
+pg_fe_getauthname(void)
 {
        const char *name = NULL;
        char       *authn;
index bfddc682b1f34c7f88ce830570e8bb6beca99c32..25440b06bd9fe01395c74e940c368cd2b01bae9a 100644 (file)
@@ -19,6 +19,6 @@
 
 
 extern int     pg_fe_sendauth(AuthRequest areq, PGconn *conn);
-extern char *pg_fe_getauthname(PQExpBuffer errorMessage);
+extern char *pg_fe_getauthname(void);
 
 #endif   /* FE_AUTH_H */
index 8dd1a5960f6e3bb4c327cc92fbe7ef23249ddb9a..7ab4a9a36231a973ae501f35833560ecea8298a1 100644 (file)
@@ -875,7 +875,8 @@ PQconndefaults(void)
        connOptions = conninfo_init(&errorBuf);
        if (connOptions != NULL)
        {
-               if (!conninfo_add_defaults(connOptions, &errorBuf))
+               /* pass NULL errorBuf to ignore errors */
+               if (!conninfo_add_defaults(connOptions, NULL))
                {
                        PQconninfoFree(connOptions);
                        connOptions = NULL;
@@ -4412,9 +4413,10 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
  *
  * Defaults are obtained from a service file, environment variables, etc.
  *
- * Returns TRUE if successful, otherwise FALSE; errorMessage is filled in
- * upon failure.  Note that failure to locate a default value is not an
- * error condition here --- we just leave the option's value as NULL.
+ * Returns TRUE if successful, otherwise FALSE; errorMessage, if supplied,
+ * is filled in upon failure.  Note that failure to locate a default value
+ * is not an error condition here --- we just leave the option's value as
+ * NULL.
  */
 static bool
 conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
@@ -4424,9 +4426,10 @@ conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
 
        /*
         * If there's a service spec, use it to obtain any not-explicitly-given
-        * parameters.
+        * parameters.  Ignore error if no error message buffer is passed
+        * because there is no way to pass back the failure message.
         */
-       if (parseServiceInfo(options, errorMessage) != 0)
+       if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
                return false;
 
        /*
@@ -4448,8 +4451,9 @@ conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
                                option->val = strdup(tmp);
                                if (!option->val)
                                {
-                                       printfPQExpBuffer(errorMessage,
-                                                                         libpq_gettext("out of memory\n"));
+                                       if (errorMessage)
+                                               printfPQExpBuffer(errorMessage,
+                                                                                 libpq_gettext("out of memory\n"));
                                        return false;
                                }
                                continue;
@@ -4465,8 +4469,9 @@ conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
                        option->val = strdup(option->compiled);
                        if (!option->val)
                        {
-                               printfPQExpBuffer(errorMessage,
-                                                                 libpq_gettext("out of memory\n"));
+                               if (errorMessage)
+                                       printfPQExpBuffer(errorMessage,
+                                                                         libpq_gettext("out of memory\n"));
                                return false;
                        }
                        continue;
@@ -4477,7 +4482,7 @@ conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
                 */
                if (strcmp(option->keyword, "user") == 0)
                {
-                       option->val = pg_fe_getauthname(errorMessage);
+                       option->val = pg_fe_getauthname();
                        continue;
                }
        }