@@ -333,7 +333,7 @@ static intconnectDBStart(PGconn *conn);
333333static int connectDBComplete (PGconn * conn );
334334static PGPing internal_ping (PGconn * conn );
335335static PGconn * makeEmptyPGconn (void );
336- static void fillPGconn (PGconn * conn ,PQconninfoOption * connOptions );
336+ static bool fillPGconn (PGconn * conn ,PQconninfoOption * connOptions );
337337static void freePGconn (PGconn * conn );
338338static void closePGconn (PGconn * conn );
339339static PQconninfoOption * conninfo_init (PQExpBuffer errorMessage );
@@ -585,7 +585,11 @@ PQconnectStartParams(const char *const * keywords,
585585/*
586586 * Move option values into conn structure
587587 */
588- fillPGconn (conn ,connOptions );
588+ if (!fillPGconn (conn ,connOptions ))
589+ {
590+ PQconninfoFree (connOptions );
591+ return conn ;
592+ }
589593
590594/*
591595 * Free the option info - all is in conn now
@@ -665,19 +669,19 @@ PQconnectStart(const char *conninfo)
665669return conn ;
666670}
667671
668- static void
672+ /*
673+ * Move option values into conn structure
674+ *
675+ * Don't put anything cute here --- intelligence should be in
676+ * connectOptions2 ...
677+ *
678+ * Returns true on success. On failure, returns false and sets error message.
679+ */
680+ static bool
669681fillPGconn (PGconn * conn ,PQconninfoOption * connOptions )
670682{
671683const internalPQconninfoOption * option ;
672684
673- /*
674- * Move option values into conn structure
675- *
676- * Don't put anything cute here --- intelligence should be in
677- * connectOptions2 ...
678- *
679- * XXX: probably worth checking strdup() return value here...
680- */
681685for (option = PQconninfoOptions ;option -> keyword ;option ++ )
682686{
683687const char * tmp = conninfo_getval (connOptions ,option -> keyword );
@@ -688,9 +692,22 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
688692
689693if (* connmember )
690694free (* connmember );
691- * connmember = tmp ?strdup (tmp ) :NULL ;
695+ if (tmp )
696+ {
697+ * connmember = strdup (tmp );
698+ if (* connmember == NULL )
699+ {
700+ printfPQExpBuffer (& conn -> errorMessage ,
701+ libpq_gettext ("out of memory\n" ));
702+ return false;
703+ }
704+ }
705+ else
706+ * connmember = NULL ;
692707}
693708}
709+
710+ return true;
694711}
695712
696713/*
@@ -723,7 +740,12 @@ connectOptions1(PGconn *conn, const char *conninfo)
723740/*
724741 * Move option values into conn structure
725742 */
726- fillPGconn (conn ,connOptions );
743+ if (!fillPGconn (conn ,connOptions ))
744+ {
745+ conn -> status = CONNECTION_BAD ;
746+ PQconninfoFree (connOptions );
747+ return false;
748+ }
727749
728750/*
729751 * Free the option info - all is in conn now
@@ -753,6 +775,8 @@ connectOptions2(PGconn *conn)
753775if (conn -> dbName )
754776free (conn -> dbName );
755777conn -> dbName = strdup (conn -> pguser );
778+ if (!conn -> dbName )
779+ gotooom_error ;
756780}
757781
758782/*
@@ -765,7 +789,12 @@ connectOptions2(PGconn *conn)
765789conn -> pgpass = PasswordFromFile (conn -> pghost ,conn -> pgport ,
766790conn -> dbName ,conn -> pguser );
767791if (conn -> pgpass == NULL )
792+ {
768793conn -> pgpass = strdup (DefaultPassword );
794+ if (!conn -> pgpass )
795+ gotooom_error ;
796+
797+ }
769798else
770799conn -> dot_pgpass_used = true;
771800}
@@ -823,7 +852,11 @@ connectOptions2(PGconn *conn)
823852#endif
824853}
825854else
855+ {
826856conn -> sslmode = strdup (DefaultSSLMode );
857+ if (!conn -> sslmode )
858+ gotooom_error ;
859+ }
827860
828861/*
829862 * Resolve special "auto" client_encoding from the locale
@@ -833,6 +866,8 @@ connectOptions2(PGconn *conn)
833866{
834867free (conn -> client_encoding_initial );
835868conn -> client_encoding_initial = strdup (pg_encoding_to_char (pg_get_encoding_from_locale (NULL , true)));
869+ if (!conn -> client_encoding_initial )
870+ gotooom_error ;
836871}
837872
838873/*
@@ -843,6 +878,12 @@ connectOptions2(PGconn *conn)
843878conn -> options_valid = true;
844879
845880return true;
881+
882+ oom_error :
883+ conn -> status = CONNECTION_BAD ;
884+ printfPQExpBuffer (& conn -> errorMessage ,
885+ libpq_gettext ("out of memory\n" ));
886+ return false;
846887}
847888
848889/*
@@ -937,6 +978,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
937978if (conn -> dbName )
938979free (conn -> dbName );
939980conn -> dbName = strdup (dbName );
981+ if (!conn -> dbName )
982+ gotooom_error ;
940983}
941984}
942985
@@ -949,41 +992,53 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
949992if (conn -> pghost )
950993free (conn -> pghost );
951994conn -> pghost = strdup (pghost );
995+ if (!conn -> pghost )
996+ gotooom_error ;
952997}
953998
954999if (pgport && pgport [0 ]!= '\0' )
9551000{
9561001if (conn -> pgport )
9571002free (conn -> pgport );
9581003conn -> pgport = strdup (pgport );
1004+ if (!conn -> pgport )
1005+ gotooom_error ;
9591006}
9601007
9611008if (pgoptions && pgoptions [0 ]!= '\0' )
9621009{
9631010if (conn -> pgoptions )
9641011free (conn -> pgoptions );
9651012conn -> pgoptions = strdup (pgoptions );
1013+ if (!conn -> pgoptions )
1014+ gotooom_error ;
9661015}
9671016
9681017if (pgtty && pgtty [0 ]!= '\0' )
9691018{
9701019if (conn -> pgtty )
9711020free (conn -> pgtty );
9721021conn -> pgtty = strdup (pgtty );
1022+ if (!conn -> pgtty )
1023+ gotooom_error ;
9731024}
9741025
9751026if (login && login [0 ]!= '\0' )
9761027{
9771028if (conn -> pguser )
9781029free (conn -> pguser );
9791030conn -> pguser = strdup (login );
1031+ if (!conn -> pguser )
1032+ gotooom_error ;
9801033}
9811034
9821035if (pwd && pwd [0 ]!= '\0' )
9831036{
9841037if (conn -> pgpass )
9851038free (conn -> pgpass );
9861039conn -> pgpass = strdup (pwd );
1040+ if (!conn -> pgpass )
1041+ gotooom_error ;
9871042}
9881043
9891044/*
@@ -999,6 +1054,12 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
9991054(void )connectDBComplete (conn );
10001055
10011056return conn ;
1057+
1058+ oom_error :
1059+ conn -> status = CONNECTION_BAD ;
1060+ printfPQExpBuffer (& conn -> errorMessage ,
1061+ libpq_gettext ("out of memory\n" ));
1062+ return conn ;
10021063}
10031064
10041065
@@ -3759,7 +3820,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
37593820if (strcmp (options [i ].keyword ,optname )== 0 )
37603821{
37613822if (options [i ].val == NULL )
3823+ {
37623824options [i ].val = strdup (optval );
3825+ if (!options [i ].val )
3826+ {
3827+ printfPQExpBuffer (errorMessage ,
3828+ libpq_gettext ("out of memory\n" ));
3829+ free (result );
3830+ return 3 ;
3831+ }
3832+ }
37633833found_keyword = true;
37643834break ;
37653835}
@@ -3982,6 +4052,13 @@ parseServiceFile(const char *serviceFile,
39824052{
39834053if (options [i ].val == NULL )
39844054options [i ].val = strdup (val );
4055+ if (!options [i ].val )
4056+ {
4057+ printfPQExpBuffer (errorMessage ,
4058+ libpq_gettext ("out of memory\n" ));
4059+ fclose (f );
4060+ return 3 ;
4061+ }
39854062found_keyword = true;
39864063break ;
39874064}
@@ -4401,6 +4478,14 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
44014478if (options [k ].val )
44024479free (options [k ].val );
44034480options [k ].val = strdup (str_option -> val );
4481+ if (!options [k ].val )
4482+ {
4483+ printfPQExpBuffer (errorMessage ,
4484+ libpq_gettext ("out of memory\n" ));
4485+ PQconninfoFree (options );
4486+ PQconninfoFree (dbname_options );
4487+ return NULL ;
4488+ }
44044489break ;
44054490}
44064491}
@@ -4595,20 +4680,22 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
45954680{
45964681int prefix_len ;
45974682char * p ;
4598- char * buf = strdup (uri );/* need a modifiable copy of the input
4599- * URI */
4600- char * start = buf ;
4683+ char * buf ;
4684+ char * start ;
46014685char prevchar = '\0' ;
46024686char * user = NULL ;
46034687char * host = NULL ;
46044688bool retval = false;
46054689
4690+ /* need a modifiable copy of the input URI */
4691+ buf = strdup (uri );
46064692if (buf == NULL )
46074693{
46084694printfPQExpBuffer (errorMessage ,
46094695libpq_gettext ("out of memory\n" ));
46104696return false;
46114697}
4698+ start = buf ;
46124699
46134700/* Skip the URI prefix */
46144701prefix_len = uri_prefix_length (uri );
@@ -4950,15 +5037,17 @@ conninfo_uri_parse_params(char *params,
49505037static char *
49515038conninfo_uri_decode (const char * str ,PQExpBuffer errorMessage )
49525039{
4953- char * buf = malloc ( strlen ( str ) + 1 ) ;
4954- char * p = buf ;
5040+ char * buf ;
5041+ char * p ;
49555042const char * q = str ;
49565043
5044+ buf = malloc (strlen (str )+ 1 );
49575045if (buf == NULL )
49585046{
49595047printfPQExpBuffer (errorMessage ,libpq_gettext ("out of memory\n" ));
49605048return NULL ;
49615049}
5050+ p = buf ;
49625051
49635052for (;;)
49645053{
@@ -5103,7 +5192,6 @@ conninfo_storeval(PQconninfoOption *connOptions,
51035192else
51045193{
51055194value_copy = strdup (value );
5106-
51075195if (value_copy == NULL )
51085196{
51095197printfPQExpBuffer (errorMessage ,libpq_gettext ("out of memory\n" ));
@@ -5671,6 +5759,12 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
56715759ret = strdup (t );
56725760fclose (fp );
56735761
5762+ if (!ret )
5763+ {
5764+ /* Out of memory. XXX: an error message would be nice. */
5765+ return NULL ;
5766+ }
5767+
56745768/* De-escape password. */
56755769for (p1 = p2 = ret ;* p1 != ':' && * p1 != '\0' ;++ p1 ,++ p2 )
56765770{