@@ -286,7 +286,7 @@ static int connectDBStart(PGconn *conn);
286286static int connectDBComplete (PGconn * conn );
287287static PGPing internal_ping (PGconn * conn );
288288static PGconn * makeEmptyPGconn (void );
289- static void fillPGconn (PGconn * conn , PQconninfoOption * connOptions );
289+ static bool fillPGconn (PGconn * conn , PQconninfoOption * connOptions );
290290static void freePGconn (PGconn * conn );
291291static void closePGconn (PGconn * conn );
292292static PQconninfoOption * conninfo_parse (const char * conninfo ,
@@ -494,7 +494,11 @@ PQconnectStartParams(const char **keywords,
494494 /*
495495 * Move option values into conn structure
496496 */
497- fillPGconn (conn , connOptions );
497+ if (!fillPGconn (conn , connOptions ))
498+ {
499+ PQconninfoFree (connOptions );
500+ return conn ;
501+ }
498502
499503 /*
500504 * Free the option info - all is in conn now
@@ -574,7 +578,29 @@ PQconnectStart(const char *conninfo)
574578 return conn ;
575579}
576580
577- static void
581+ /*
582+ * Move option values into conn structure
583+ *
584+ * Don't put anything cute here --- intelligence should be in
585+ * connectOptions2 ...
586+ *
587+ * Returns true on success. On failure, returns false and sets error message.
588+ */
589+ #define FILL_CONN_OPTION (dst , name ) \
590+ do \
591+ { \
592+ tmp = conninfo_getval(connOptions, name); \
593+ if (tmp) \
594+ { \
595+ dst = strdup(tmp); \
596+ if (dst == NULL) \
597+ goto oom_error; \
598+ } \
599+ else \
600+ dst = NULL; \
601+ } while(0)
602+
603+ static bool
578604fillPGconn (PGconn * conn , PQconninfoOption * connOptions )
579605{
580606 char * tmp ;
@@ -587,48 +613,27 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
587613 *
588614 * XXX: probably worth checking strdup() return value here...
589615 */
590- tmp = conninfo_getval (connOptions , "hostaddr" );
591- conn -> pghostaddr = tmp ? strdup (tmp ) : NULL ;
592- tmp = conninfo_getval (connOptions , "host" );
593- conn -> pghost = tmp ? strdup (tmp ) : NULL ;
594- tmp = conninfo_getval (connOptions , "port" );
595- conn -> pgport = tmp ? strdup (tmp ) : NULL ;
596- tmp = conninfo_getval (connOptions , "tty" );
597- conn -> pgtty = tmp ? strdup (tmp ) : NULL ;
598- tmp = conninfo_getval (connOptions , "options" );
599- conn -> pgoptions = tmp ? strdup (tmp ) : NULL ;
600- tmp = conninfo_getval (connOptions , "application_name" );
601- conn -> appname = tmp ? strdup (tmp ) : NULL ;
602- tmp = conninfo_getval (connOptions , "fallback_application_name" );
603- conn -> fbappname = tmp ? strdup (tmp ) : NULL ;
604- tmp = conninfo_getval (connOptions , "dbname" );
605- conn -> dbName = tmp ? strdup (tmp ) : NULL ;
606- tmp = conninfo_getval (connOptions , "user" );
607- conn -> pguser = tmp ? strdup (tmp ) : NULL ;
608- tmp = conninfo_getval (connOptions , "password" );
609- conn -> pgpass = tmp ? strdup (tmp ) : NULL ;
610- tmp = conninfo_getval (connOptions , "connect_timeout" );
611- conn -> connect_timeout = tmp ? strdup (tmp ) : NULL ;
612- tmp = conninfo_getval (connOptions , "client_encoding" );
613- conn -> client_encoding_initial = tmp ? strdup (tmp ) : NULL ;
614- tmp = conninfo_getval (connOptions , "keepalives" );
615- conn -> keepalives = tmp ? strdup (tmp ) : NULL ;
616- tmp = conninfo_getval (connOptions , "keepalives_idle" );
617- conn -> keepalives_idle = tmp ? strdup (tmp ) : NULL ;
618- tmp = conninfo_getval (connOptions , "keepalives_interval" );
619- conn -> keepalives_interval = tmp ? strdup (tmp ) : NULL ;
620- tmp = conninfo_getval (connOptions , "keepalives_count" );
621- conn -> keepalives_count = tmp ? strdup (tmp ) : NULL ;
622- tmp = conninfo_getval (connOptions , "sslmode" );
623- conn -> sslmode = tmp ? strdup (tmp ) : NULL ;
624- tmp = conninfo_getval (connOptions , "sslkey" );
625- conn -> sslkey = tmp ? strdup (tmp ) : NULL ;
626- tmp = conninfo_getval (connOptions , "sslcert" );
627- conn -> sslcert = tmp ? strdup (tmp ) : NULL ;
628- tmp = conninfo_getval (connOptions , "sslrootcert" );
629- conn -> sslrootcert = tmp ? strdup (tmp ) : NULL ;
630- tmp = conninfo_getval (connOptions , "sslcrl" );
631- conn -> sslcrl = tmp ? strdup (tmp ) : NULL ;
616+ FILL_CONN_OPTION (conn -> pghostaddr , "hostaddr" );
617+ FILL_CONN_OPTION (conn -> pghost , "host" );
618+ FILL_CONN_OPTION (conn -> pgport , "port" );
619+ FILL_CONN_OPTION (conn -> pgtty , "tty" );
620+ FILL_CONN_OPTION (conn -> pgoptions , "options" );
621+ FILL_CONN_OPTION (conn -> appname , "application_name" );
622+ FILL_CONN_OPTION (conn -> fbappname , "fallback_application_name" );
623+ FILL_CONN_OPTION (conn -> dbName , "dbname" );
624+ FILL_CONN_OPTION (conn -> pguser , "user" );
625+ FILL_CONN_OPTION (conn -> pgpass , "password" );
626+ FILL_CONN_OPTION (conn -> connect_timeout , "connect_timeout" );
627+ FILL_CONN_OPTION (conn -> client_encoding_initial , "client_encoding" );
628+ FILL_CONN_OPTION (conn -> keepalives , "keepalives" );
629+ FILL_CONN_OPTION (conn -> keepalives_idle , "keepalives_idle" );
630+ FILL_CONN_OPTION (conn -> keepalives_interval , "keepalives_interval" );
631+ FILL_CONN_OPTION (conn -> keepalives_count , "keepalives_count" );
632+ FILL_CONN_OPTION (conn -> sslmode , "sslmode" );
633+ FILL_CONN_OPTION (conn -> sslkey , "sslkey" );
634+ FILL_CONN_OPTION (conn -> sslcert , "sslcert" );
635+ FILL_CONN_OPTION (conn -> sslrootcert , "sslrootcert" );
636+ FILL_CONN_OPTION (conn -> sslcrl , "sslcrl" );
632637#ifdef USE_SSL
633638 tmp = conninfo_getval (connOptions , "requiressl" );
634639 if (tmp && tmp [0 ] == '1' )
@@ -637,20 +642,25 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
637642 if (conn -> sslmode )
638643 free (conn -> sslmode );
639644 conn -> sslmode = strdup ("require" );
645+ if (!conn -> sslmode )
646+ return false;
640647 }
641648#endif
642- tmp = conninfo_getval (connOptions , "requirepeer" );
643- conn -> requirepeer = tmp ? strdup (tmp ) : NULL ;
649+ FILL_CONN_OPTION (conn -> requirepeer , "requirepeer" );
644650#if defined(KRB5 ) || defined(ENABLE_GSS ) || defined(ENABLE_SSPI )
645- tmp = conninfo_getval (connOptions , "krbsrvname" );
646- conn -> krbsrvname = tmp ? strdup (tmp ) : NULL ;
651+ FILL_CONN_OPTION (conn -> krbsrvname , "krbsrvname" );
647652#endif
648653#if defined(ENABLE_GSS ) && defined(ENABLE_SSPI )
649- tmp = conninfo_getval (connOptions , "gsslib" );
650- conn -> gsslib = tmp ? strdup (tmp ) : NULL ;
654+ FILL_CONN_OPTION (conn -> gsslib , "gsslib" );
651655#endif
652- tmp = conninfo_getval (connOptions , "replication" );
653- conn -> replication = tmp ? strdup (tmp ) : NULL ;
656+ FILL_CONN_OPTION (conn -> replication , "replication" );
657+
658+ return true;
659+
660+ oom_error :
661+ printfPQExpBuffer (& conn -> errorMessage ,
662+ libpq_gettext ("out of memory\n" ));
663+ return false;
654664}
655665
656666/*
@@ -683,7 +693,12 @@ connectOptions1(PGconn *conn, const char *conninfo)
683693 /*
684694 * Move option values into conn structure
685695 */
686- fillPGconn (conn , connOptions );
696+ if (!fillPGconn (conn , connOptions ))
697+ {
698+ conn -> status = CONNECTION_BAD ;
699+ PQconninfoFree (connOptions );
700+ return false;
701+ }
687702
688703 /*
689704 * Free the option info - all is in conn now
@@ -713,6 +728,8 @@ connectOptions2(PGconn *conn)
713728 if (conn -> dbName )
714729 free (conn -> dbName );
715730 conn -> dbName = strdup (conn -> pguser );
731+ if (!conn -> dbName )
732+ goto oom_error ;
716733 }
717734
718735 /*
@@ -725,7 +742,12 @@ connectOptions2(PGconn *conn)
725742 conn -> pgpass = PasswordFromFile (conn -> pghost , conn -> pgport ,
726743 conn -> dbName , conn -> pguser );
727744 if (conn -> pgpass == NULL )
745+ {
728746 conn -> pgpass = strdup (DefaultPassword );
747+ if (!conn -> pgpass )
748+ goto oom_error ;
749+
750+ }
729751 else
730752 conn -> dot_pgpass_used = true;
731753 }
@@ -783,7 +805,11 @@ connectOptions2(PGconn *conn)
783805#endif
784806 }
785807 else
808+ {
786809 conn -> sslmode = strdup (DefaultSSLMode );
810+ if (!conn -> sslmode )
811+ goto oom_error ;
812+ }
787813
788814 /*
789815 * Resolve special "auto" client_encoding from the locale
@@ -793,6 +819,8 @@ connectOptions2(PGconn *conn)
793819 {
794820 free (conn -> client_encoding_initial );
795821 conn -> client_encoding_initial = strdup (pg_encoding_to_char (pg_get_encoding_from_locale (NULL , true)));
822+ if (!conn -> client_encoding_initial )
823+ goto oom_error ;
796824 }
797825
798826 /*
@@ -803,6 +831,12 @@ connectOptions2(PGconn *conn)
803831 conn -> options_valid = true;
804832
805833 return true;
834+
835+ oom_error :
836+ conn -> status = CONNECTION_BAD ;
837+ printfPQExpBuffer (& conn -> errorMessage ,
838+ libpq_gettext ("out of memory\n" ));
839+ return false;
806840}
807841
808842/*
@@ -885,6 +919,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
885919 if (conn -> dbName )
886920 free (conn -> dbName );
887921 conn -> dbName = strdup (dbName );
922+ if (!conn -> dbName )
923+ goto oom_error ;
888924 }
889925 }
890926
@@ -897,41 +933,53 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
897933 if (conn -> pghost )
898934 free (conn -> pghost );
899935 conn -> pghost = strdup (pghost );
936+ if (!conn -> pghost )
937+ goto oom_error ;
900938 }
901939
902940 if (pgport && pgport [0 ] != '\0' )
903941 {
904942 if (conn -> pgport )
905943 free (conn -> pgport );
906944 conn -> pgport = strdup (pgport );
945+ if (!conn -> pgport )
946+ goto oom_error ;
907947 }
908948
909949 if (pgoptions && pgoptions [0 ] != '\0' )
910950 {
911951 if (conn -> pgoptions )
912952 free (conn -> pgoptions );
913953 conn -> pgoptions = strdup (pgoptions );
954+ if (!conn -> pgoptions )
955+ goto oom_error ;
914956 }
915957
916958 if (pgtty && pgtty [0 ] != '\0' )
917959 {
918960 if (conn -> pgtty )
919961 free (conn -> pgtty );
920962 conn -> pgtty = strdup (pgtty );
963+ if (!conn -> pgtty )
964+ goto oom_error ;
921965 }
922966
923967 if (login && login [0 ] != '\0' )
924968 {
925969 if (conn -> pguser )
926970 free (conn -> pguser );
927971 conn -> pguser = strdup (login );
972+ if (!conn -> pguser )
973+ goto oom_error ;
928974 }
929975
930976 if (pwd && pwd [0 ] != '\0' )
931977 {
932978 if (conn -> pgpass )
933979 free (conn -> pgpass );
934980 conn -> pgpass = strdup (pwd );
981+ if (!conn -> pgpass )
982+ goto oom_error ;
935983 }
936984
937985 /*
@@ -947,6 +995,12 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
947995 (void ) connectDBComplete (conn );
948996
949997 return conn ;
998+
999+ oom_error :
1000+ conn -> status = CONNECTION_BAD ;
1001+ printfPQExpBuffer (& conn -> errorMessage ,
1002+ libpq_gettext ("out of memory\n" ));
1003+ return conn ;
9501004}
9511005
9521006
@@ -3761,7 +3815,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
37613815 if (strcmp (options [i ].keyword , optname ) == 0 )
37623816 {
37633817 if (options [i ].val == NULL )
3818+ {
37643819 options [i ].val = strdup (optval );
3820+ if (!options [i ].val )
3821+ {
3822+ printfPQExpBuffer (errorMessage ,
3823+ libpq_gettext ("out of memory\n" ));
3824+ free (result );
3825+ return 3 ;
3826+ }
3827+ }
37653828 found_keyword = true;
37663829 break ;
37673830 }
@@ -3984,6 +4047,13 @@ parseServiceFile(const char *serviceFile,
39844047 {
39854048 if (options [i ].val == NULL )
39864049 options [i ].val = strdup (val );
4050+ if (!options [i ].val )
4051+ {
4052+ printfPQExpBuffer (errorMessage ,
4053+ libpq_gettext ("out of memory\n" ));
4054+ fclose (f );
4055+ return 3 ;
4056+ }
39874057 found_keyword = true;
39884058 break ;
39894059 }
@@ -4411,6 +4481,14 @@ conninfo_array_parse(const char **keywords, const char **values,
44114481 if (options [k ].val )
44124482 free (options [k ].val );
44134483 options [k ].val = strdup (str_option -> val );
4484+ if (!options [k ].val )
4485+ {
4486+ printfPQExpBuffer (errorMessage ,
4487+ libpq_gettext ("out of memory\n" ));
4488+ PQconninfoFree (options );
4489+ PQconninfoFree (str_options );
4490+ return NULL ;
4491+ }
44144492 break ;
44154493 }
44164494 }
@@ -4430,6 +4508,7 @@ conninfo_array_parse(const char **keywords, const char **values,
44304508 printfPQExpBuffer (errorMessage ,
44314509 libpq_gettext ("out of memory\n" ));
44324510 PQconninfoFree (options );
4511+ PQconninfoFree (str_options );
44334512 return NULL ;
44344513 }
44354514 }
0 commit comments