@@ -333,7 +333,7 @@ static int connectDBStart(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)
665669 return 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{
671683 const 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- */
681685 for (option = PQconninfoOptions ; option -> keyword ; option ++ )
682686 {
683687 const char * tmp = conninfo_getval (connOptions , option -> keyword );
@@ -688,9 +692,22 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
688692
689693 if (* connmember )
690694 free (* 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)
753775 if (conn -> dbName )
754776 free (conn -> dbName );
755777 conn -> dbName = strdup (conn -> pguser );
778+ if (!conn -> dbName )
779+ goto oom_error ;
756780 }
757781
758782 /*
@@ -765,7 +789,12 @@ connectOptions2(PGconn *conn)
765789 conn -> pgpass = PasswordFromFile (conn -> pghost , conn -> pgport ,
766790 conn -> dbName , conn -> pguser );
767791 if (conn -> pgpass == NULL )
792+ {
768793 conn -> pgpass = strdup (DefaultPassword );
794+ if (!conn -> pgpass )
795+ goto oom_error ;
796+
797+ }
769798 else
770799 conn -> dot_pgpass_used = true;
771800 }
@@ -823,7 +852,11 @@ connectOptions2(PGconn *conn)
823852#endif
824853 }
825854 else
855+ {
826856 conn -> sslmode = strdup (DefaultSSLMode );
857+ if (!conn -> sslmode )
858+ goto oom_error ;
859+ }
827860
828861 /*
829862 * Resolve special "auto" client_encoding from the locale
@@ -833,6 +866,8 @@ connectOptions2(PGconn *conn)
833866 {
834867 free (conn -> client_encoding_initial );
835868 conn -> client_encoding_initial = strdup (pg_encoding_to_char (pg_get_encoding_from_locale (NULL , true)));
869+ if (!conn -> client_encoding_initial )
870+ goto oom_error ;
836871 }
837872
838873 /*
@@ -843,6 +878,12 @@ connectOptions2(PGconn *conn)
843878 conn -> options_valid = true;
844879
845880 return 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,
937978 if (conn -> dbName )
938979 free (conn -> dbName );
939980 conn -> dbName = strdup (dbName );
981+ if (!conn -> dbName )
982+ goto oom_error ;
940983 }
941984 }
942985
@@ -949,41 +992,53 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
949992 if (conn -> pghost )
950993 free (conn -> pghost );
951994 conn -> pghost = strdup (pghost );
995+ if (!conn -> pghost )
996+ goto oom_error ;
952997 }
953998
954999 if (pgport && pgport [0 ] != '\0' )
9551000 {
9561001 if (conn -> pgport )
9571002 free (conn -> pgport );
9581003 conn -> pgport = strdup (pgport );
1004+ if (!conn -> pgport )
1005+ goto oom_error ;
9591006 }
9601007
9611008 if (pgoptions && pgoptions [0 ] != '\0' )
9621009 {
9631010 if (conn -> pgoptions )
9641011 free (conn -> pgoptions );
9651012 conn -> pgoptions = strdup (pgoptions );
1013+ if (!conn -> pgoptions )
1014+ goto oom_error ;
9661015 }
9671016
9681017 if (pgtty && pgtty [0 ] != '\0' )
9691018 {
9701019 if (conn -> pgtty )
9711020 free (conn -> pgtty );
9721021 conn -> pgtty = strdup (pgtty );
1022+ if (!conn -> pgtty )
1023+ goto oom_error ;
9731024 }
9741025
9751026 if (login && login [0 ] != '\0' )
9761027 {
9771028 if (conn -> pguser )
9781029 free (conn -> pguser );
9791030 conn -> pguser = strdup (login );
1031+ if (!conn -> pguser )
1032+ goto oom_error ;
9801033 }
9811034
9821035 if (pwd && pwd [0 ] != '\0' )
9831036 {
9841037 if (conn -> pgpass )
9851038 free (conn -> pgpass );
9861039 conn -> pgpass = strdup (pwd );
1040+ if (!conn -> pgpass )
1041+ goto oom_error ;
9871042 }
9881043
9891044 /*
@@ -999,6 +1054,12 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
9991054 (void ) connectDBComplete (conn );
10001055
10011056 return 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
@@ -3760,7 +3821,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
37603821 if (strcmp (options [i ].keyword , optname ) == 0 )
37613822 {
37623823 if (options [i ].val == NULL )
3824+ {
37633825 options [i ].val = strdup (optval );
3826+ if (!options [i ].val )
3827+ {
3828+ printfPQExpBuffer (errorMessage ,
3829+ libpq_gettext ("out of memory\n" ));
3830+ free (result );
3831+ return 3 ;
3832+ }
3833+ }
37643834 found_keyword = true;
37653835 break ;
37663836 }
@@ -3983,6 +4053,13 @@ parseServiceFile(const char *serviceFile,
39834053 {
39844054 if (options [i ].val == NULL )
39854055 options [i ].val = strdup (val );
4056+ if (!options [i ].val )
4057+ {
4058+ printfPQExpBuffer (errorMessage ,
4059+ libpq_gettext ("out of memory\n" ));
4060+ fclose (f );
4061+ return 3 ;
4062+ }
39864063 found_keyword = true;
39874064 break ;
39884065 }
@@ -4402,6 +4479,14 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
44024479 if (options [k ].val )
44034480 free (options [k ].val );
44044481 options [k ].val = strdup (str_option -> val );
4482+ if (!options [k ].val )
4483+ {
4484+ printfPQExpBuffer (errorMessage ,
4485+ libpq_gettext ("out of memory\n" ));
4486+ PQconninfoFree (options );
4487+ PQconninfoFree (dbname_options );
4488+ return NULL ;
4489+ }
44054490 break ;
44064491 }
44074492 }
@@ -4596,20 +4681,22 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
45964681{
45974682 int prefix_len ;
45984683 char * p ;
4599- char * buf = strdup (uri ); /* need a modifiable copy of the input
4600- * URI */
4601- char * start = buf ;
4684+ char * buf ;
4685+ char * start ;
46024686 char prevchar = '\0' ;
46034687 char * user = NULL ;
46044688 char * host = NULL ;
46054689 bool retval = false;
46064690
4691+ /* need a modifiable copy of the input URI */
4692+ buf = strdup (uri );
46074693 if (buf == NULL )
46084694 {
46094695 printfPQExpBuffer (errorMessage ,
46104696 libpq_gettext ("out of memory\n" ));
46114697 return false;
46124698 }
4699+ start = buf ;
46134700
46144701 /* Skip the URI prefix */
46154702 prefix_len = uri_prefix_length (uri );
@@ -4951,15 +5038,17 @@ conninfo_uri_parse_params(char *params,
49515038static char *
49525039conninfo_uri_decode (const char * str , PQExpBuffer errorMessage )
49535040{
4954- char * buf = malloc ( strlen ( str ) + 1 ) ;
4955- char * p = buf ;
5041+ char * buf ;
5042+ char * p ;
49565043 const char * q = str ;
49575044
5045+ buf = malloc (strlen (str ) + 1 );
49585046 if (buf == NULL )
49595047 {
49605048 printfPQExpBuffer (errorMessage , libpq_gettext ("out of memory\n" ));
49615049 return NULL ;
49625050 }
5051+ p = buf ;
49635052
49645053 for (;;)
49655054 {
@@ -5104,7 +5193,6 @@ conninfo_storeval(PQconninfoOption *connOptions,
51045193 else
51055194 {
51065195 value_copy = strdup (value );
5107-
51085196 if (value_copy == NULL )
51095197 {
51105198 printfPQExpBuffer (errorMessage , libpq_gettext ("out of memory\n" ));
@@ -5672,6 +5760,12 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
56725760 ret = strdup (t );
56735761 fclose (fp );
56745762
5763+ if (!ret )
5764+ {
5765+ /* Out of memory. XXX: an error message would be nice. */
5766+ return NULL ;
5767+ }
5768+
56755769 /* De-escape password. */
56765770 for (p1 = p2 = ret ; * p1 != ':' && * p1 != '\0' ; ++ p1 , ++ p2 )
56775771 {
0 commit comments