@@ -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/*
@@ -936,6 +977,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
936977if (conn -> dbName )
937978free (conn -> dbName );
938979conn -> dbName = strdup (dbName );
980+ if (!conn -> dbName )
981+ gotooom_error ;
939982}
940983}
941984
@@ -948,41 +991,53 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
948991if (conn -> pghost )
949992free (conn -> pghost );
950993conn -> pghost = strdup (pghost );
994+ if (!conn -> pghost )
995+ gotooom_error ;
951996}
952997
953998if (pgport && pgport [0 ]!= '\0' )
954999{
9551000if (conn -> pgport )
9561001free (conn -> pgport );
9571002conn -> pgport = strdup (pgport );
1003+ if (!conn -> pgport )
1004+ gotooom_error ;
9581005}
9591006
9601007if (pgoptions && pgoptions [0 ]!= '\0' )
9611008{
9621009if (conn -> pgoptions )
9631010free (conn -> pgoptions );
9641011conn -> pgoptions = strdup (pgoptions );
1012+ if (!conn -> pgoptions )
1013+ gotooom_error ;
9651014}
9661015
9671016if (pgtty && pgtty [0 ]!= '\0' )
9681017{
9691018if (conn -> pgtty )
9701019free (conn -> pgtty );
9711020conn -> pgtty = strdup (pgtty );
1021+ if (!conn -> pgtty )
1022+ gotooom_error ;
9721023}
9731024
9741025if (login && login [0 ]!= '\0' )
9751026{
9761027if (conn -> pguser )
9771028free (conn -> pguser );
9781029conn -> pguser = strdup (login );
1030+ if (!conn -> pguser )
1031+ gotooom_error ;
9791032}
9801033
9811034if (pwd && pwd [0 ]!= '\0' )
9821035{
9831036if (conn -> pgpass )
9841037free (conn -> pgpass );
9851038conn -> pgpass = strdup (pwd );
1039+ if (!conn -> pgpass )
1040+ gotooom_error ;
9861041}
9871042
9881043/*
@@ -998,6 +1053,12 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
9981053(void )connectDBComplete (conn );
9991054
10001055return conn ;
1056+
1057+ oom_error :
1058+ conn -> status = CONNECTION_BAD ;
1059+ printfPQExpBuffer (& conn -> errorMessage ,
1060+ libpq_gettext ("out of memory\n" ));
1061+ return conn ;
10011062}
10021063
10031064
@@ -3774,7 +3835,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
37743835if (strcmp (options [i ].keyword ,optname )== 0 )
37753836{
37763837if (options [i ].val == NULL )
3838+ {
37773839options [i ].val = strdup (optval );
3840+ if (!options [i ].val )
3841+ {
3842+ printfPQExpBuffer (errorMessage ,
3843+ libpq_gettext ("out of memory\n" ));
3844+ free (result );
3845+ return 3 ;
3846+ }
3847+ }
37783848found_keyword = true;
37793849break ;
37803850}
@@ -3997,6 +4067,13 @@ parseServiceFile(const char *serviceFile,
39974067{
39984068if (options [i ].val == NULL )
39994069options [i ].val = strdup (val );
4070+ if (!options [i ].val )
4071+ {
4072+ printfPQExpBuffer (errorMessage ,
4073+ libpq_gettext ("out of memory\n" ));
4074+ fclose (f );
4075+ return 3 ;
4076+ }
40004077found_keyword = true;
40014078break ;
40024079}
@@ -4416,6 +4493,14 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
44164493if (options [k ].val )
44174494free (options [k ].val );
44184495options [k ].val = strdup (str_option -> val );
4496+ if (!options [k ].val )
4497+ {
4498+ printfPQExpBuffer (errorMessage ,
4499+ libpq_gettext ("out of memory\n" ));
4500+ PQconninfoFree (options );
4501+ PQconninfoFree (dbname_options );
4502+ return NULL ;
4503+ }
44194504break ;
44204505}
44214506}
@@ -4599,20 +4684,22 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
45994684{
46004685int prefix_len ;
46014686char * p ;
4602- char * buf = strdup (uri );/* need a modifiable copy of the input
4603- * URI */
4604- char * start = buf ;
4687+ char * buf ;
4688+ char * start ;
46054689char prevchar = '\0' ;
46064690char * user = NULL ;
46074691char * host = NULL ;
46084692bool retval = false;
46094693
4694+ /* need a modifiable copy of the input URI */
4695+ buf = strdup (uri );
46104696if (buf == NULL )
46114697{
46124698printfPQExpBuffer (errorMessage ,
46134699libpq_gettext ("out of memory\n" ));
46144700return false;
46154701}
4702+ start = buf ;
46164703
46174704/* Skip the URI prefix */
46184705prefix_len = uri_prefix_length (uri );
@@ -4954,15 +5041,17 @@ conninfo_uri_parse_params(char *params,
49545041static char *
49555042conninfo_uri_decode (const char * str ,PQExpBuffer errorMessage )
49565043{
4957- char * buf = malloc ( strlen ( str ) + 1 ) ;
4958- char * p = buf ;
5044+ char * buf ;
5045+ char * p ;
49595046const char * q = str ;
49605047
5048+ buf = malloc (strlen (str )+ 1 );
49615049if (buf == NULL )
49625050{
49635051printfPQExpBuffer (errorMessage ,libpq_gettext ("out of memory\n" ));
49645052return NULL ;
49655053}
5054+ p = buf ;
49665055
49675056for (;;)
49685057{
@@ -5107,7 +5196,6 @@ conninfo_storeval(PQconninfoOption *connOptions,
51075196else
51085197{
51095198value_copy = strdup (value );
5110-
51115199if (value_copy == NULL )
51125200{
51135201printfPQExpBuffer (errorMessage ,libpq_gettext ("out of memory\n" ));
@@ -5667,6 +5755,12 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
56675755ret = strdup (t );
56685756fclose (fp );
56695757
5758+ if (!ret )
5759+ {
5760+ /* Out of memory. XXX: an error message would be nice. */
5761+ return NULL ;
5762+ }
5763+
56705764/* De-escape password. */
56715765for (p1 = p2 = ret ;* p1 != ':' && * p1 != '\0' ;++ p1 ,++ p2 )
56725766{