@@ -280,7 +280,7 @@ static bool connectOptions2(PGconn *conn);
280280static int connectDBStart (PGconn * conn );
281281static int connectDBComplete (PGconn * conn );
282282static PGconn * makeEmptyPGconn (void );
283- static void fillPGconn (PGconn * conn ,PQconninfoOption * connOptions );
283+ static bool fillPGconn (PGconn * conn ,PQconninfoOption * connOptions );
284284static void freePGconn (PGconn * conn );
285285static void closePGconn (PGconn * conn );
286286static PQconninfoOption * conninfo_parse (const char * conninfo ,
@@ -452,7 +452,11 @@ PQconnectStartParams(const char **keywords,
452452/*
453453 * Move option values into conn structure
454454 */
455- fillPGconn (conn ,connOptions );
455+ if (!fillPGconn (conn ,connOptions ))
456+ {
457+ PQconninfoFree (connOptions );
458+ return conn ;
459+ }
456460
457461/*
458462 * Free the option info - all is in conn now
@@ -532,59 +536,53 @@ PQconnectStart(const char *conninfo)
532536return conn ;
533537}
534538
535- static void
539+ /*
540+ * Move option values into conn structure
541+ *
542+ * Don't put anything cute here --- intelligence should be in
543+ * connectOptions2 ...
544+ *
545+ * Returns true on success. On failure, returns false and sets error message.
546+ */
547+ #define FILL_CONN_OPTION (dst ,name ) \
548+ do \
549+ { \
550+ tmp = conninfo_getval(connOptions, name); \
551+ if (tmp) \
552+ { \
553+ dst = strdup(tmp); \
554+ if (dst == NULL) \
555+ goto oom_error; \
556+ } \
557+ else \
558+ dst = NULL; \
559+ } while(0)
560+
561+ static bool
536562fillPGconn (PGconn * conn ,PQconninfoOption * connOptions )
537563{
538564char * tmp ;
539565
540- /*
541- * Move option values into conn structure
542- *
543- * Don't put anything cute here --- intelligence should be in
544- * connectOptions2 ...
545- *
546- * XXX: probably worth checking strdup() return value here...
547- */
548- tmp = conninfo_getval (connOptions ,"hostaddr" );
549- conn -> pghostaddr = tmp ?strdup (tmp ) :NULL ;
550- tmp = conninfo_getval (connOptions ,"host" );
551- conn -> pghost = tmp ?strdup (tmp ) :NULL ;
552- tmp = conninfo_getval (connOptions ,"port" );
553- conn -> pgport = tmp ?strdup (tmp ) :NULL ;
554- tmp = conninfo_getval (connOptions ,"tty" );
555- conn -> pgtty = tmp ?strdup (tmp ) :NULL ;
556- tmp = conninfo_getval (connOptions ,"options" );
557- conn -> pgoptions = tmp ?strdup (tmp ) :NULL ;
558- tmp = conninfo_getval (connOptions ,"application_name" );
559- conn -> appname = tmp ?strdup (tmp ) :NULL ;
560- tmp = conninfo_getval (connOptions ,"fallback_application_name" );
561- conn -> fbappname = tmp ?strdup (tmp ) :NULL ;
562- tmp = conninfo_getval (connOptions ,"dbname" );
563- conn -> dbName = tmp ?strdup (tmp ) :NULL ;
564- tmp = conninfo_getval (connOptions ,"user" );
565- conn -> pguser = tmp ?strdup (tmp ) :NULL ;
566- tmp = conninfo_getval (connOptions ,"password" );
567- conn -> pgpass = tmp ?strdup (tmp ) :NULL ;
568- tmp = conninfo_getval (connOptions ,"connect_timeout" );
569- conn -> connect_timeout = tmp ?strdup (tmp ) :NULL ;
570- tmp = conninfo_getval (connOptions ,"keepalives" );
571- conn -> keepalives = tmp ?strdup (tmp ) :NULL ;
572- tmp = conninfo_getval (connOptions ,"keepalives_idle" );
573- conn -> keepalives_idle = tmp ?strdup (tmp ) :NULL ;
574- tmp = conninfo_getval (connOptions ,"keepalives_interval" );
575- conn -> keepalives_interval = tmp ?strdup (tmp ) :NULL ;
576- tmp = conninfo_getval (connOptions ,"keepalives_count" );
577- conn -> keepalives_count = tmp ?strdup (tmp ) :NULL ;
578- tmp = conninfo_getval (connOptions ,"sslmode" );
579- conn -> sslmode = tmp ?strdup (tmp ) :NULL ;
580- tmp = conninfo_getval (connOptions ,"sslkey" );
581- conn -> sslkey = tmp ?strdup (tmp ) :NULL ;
582- tmp = conninfo_getval (connOptions ,"sslcert" );
583- conn -> sslcert = tmp ?strdup (tmp ) :NULL ;
584- tmp = conninfo_getval (connOptions ,"sslrootcert" );
585- conn -> sslrootcert = tmp ?strdup (tmp ) :NULL ;
586- tmp = conninfo_getval (connOptions ,"sslcrl" );
587- conn -> sslcrl = tmp ?strdup (tmp ) :NULL ;
566+ FILL_CONN_OPTION (conn -> pghostaddr ,"hostaddr" );
567+ FILL_CONN_OPTION (conn -> pghost ,"host" );
568+ FILL_CONN_OPTION (conn -> pgport ,"port" );
569+ FILL_CONN_OPTION (conn -> pgtty ,"tty" );
570+ FILL_CONN_OPTION (conn -> pgoptions ,"options" );
571+ FILL_CONN_OPTION (conn -> appname ,"application_name" );
572+ FILL_CONN_OPTION (conn -> fbappname ,"fallback_application_name" );
573+ FILL_CONN_OPTION (conn -> dbName ,"dbname" );
574+ FILL_CONN_OPTION (conn -> pguser ,"user" );
575+ FILL_CONN_OPTION (conn -> pgpass ,"password" );
576+ FILL_CONN_OPTION (conn -> connect_timeout ,"connect_timeout" );
577+ FILL_CONN_OPTION (conn -> keepalives ,"keepalives" );
578+ FILL_CONN_OPTION (conn -> keepalives_idle ,"keepalives_idle" );
579+ FILL_CONN_OPTION (conn -> keepalives_interval ,"keepalives_interval" );
580+ FILL_CONN_OPTION (conn -> keepalives_count ,"keepalives_count" );
581+ FILL_CONN_OPTION (conn -> sslmode ,"sslmode" );
582+ FILL_CONN_OPTION (conn -> sslkey ,"sslkey" );
583+ FILL_CONN_OPTION (conn -> sslcert ,"sslcert" );
584+ FILL_CONN_OPTION (conn -> sslrootcert ,"sslrootcert" );
585+ FILL_CONN_OPTION (conn -> sslcrl ,"sslcrl" );
588586#ifdef USE_SSL
589587tmp = conninfo_getval (connOptions ,"requiressl" );
590588if (tmp && tmp [0 ]== '1' )
@@ -593,18 +591,24 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
593591if (conn -> sslmode )
594592free (conn -> sslmode );
595593conn -> sslmode = strdup ("require" );
594+ if (!conn -> sslmode )
595+ return false;
596596}
597597#endif
598598#if defined(KRB5 )|| defined(ENABLE_GSS )|| defined(ENABLE_SSPI )
599- tmp = conninfo_getval (connOptions ,"krbsrvname" );
600- conn -> krbsrvname = tmp ?strdup (tmp ) :NULL ;
599+ FILL_CONN_OPTION (conn -> krbsrvname ,"krbsrvname" );
601600#endif
602601#if defined(ENABLE_GSS )&& defined(ENABLE_SSPI )
603- tmp = conninfo_getval (connOptions ,"gsslib" );
604- conn -> gsslib = tmp ?strdup (tmp ) :NULL ;
602+ FILL_CONN_OPTION (conn -> gsslib ,"gsslib" );
605603#endif
606- tmp = conninfo_getval (connOptions ,"replication" );
607- conn -> replication = tmp ?strdup (tmp ) :NULL ;
604+ FILL_CONN_OPTION (conn -> replication ,"replication" );
605+
606+ return true;
607+
608+ oom_error :
609+ printfPQExpBuffer (& conn -> errorMessage ,
610+ libpq_gettext ("out of memory\n" ));
611+ return false;
608612}
609613
610614/*
@@ -637,7 +641,12 @@ connectOptions1(PGconn *conn, const char *conninfo)
637641/*
638642 * Move option values into conn structure
639643 */
640- fillPGconn (conn ,connOptions );
644+ if (!fillPGconn (conn ,connOptions ))
645+ {
646+ conn -> status = CONNECTION_BAD ;
647+ PQconninfoFree (connOptions );
648+ return false;
649+ }
641650
642651/*
643652 * Free the option info - all is in conn now
@@ -667,6 +676,8 @@ connectOptions2(PGconn *conn)
667676if (conn -> dbName )
668677free (conn -> dbName );
669678conn -> dbName = strdup (conn -> pguser );
679+ if (!conn -> dbName )
680+ gotooom_error ;
670681}
671682
672683/*
@@ -679,7 +690,12 @@ connectOptions2(PGconn *conn)
679690conn -> pgpass = PasswordFromFile (conn -> pghost ,conn -> pgport ,
680691conn -> dbName ,conn -> pguser );
681692if (conn -> pgpass == NULL )
693+ {
682694conn -> pgpass = strdup (DefaultPassword );
695+ if (!conn -> pgpass )
696+ gotooom_error ;
697+
698+ }
683699else
684700conn -> dot_pgpass_used = true;
685701}
@@ -737,7 +753,11 @@ connectOptions2(PGconn *conn)
737753#endif
738754}
739755else
756+ {
740757conn -> sslmode = strdup (DefaultSSLMode );
758+ if (!conn -> sslmode )
759+ gotooom_error ;
760+ }
741761
742762/*
743763 * Only if we get this far is it appropriate to try to connect. (We need a
@@ -747,6 +767,12 @@ connectOptions2(PGconn *conn)
747767conn -> options_valid = true;
748768
749769return true;
770+
771+ oom_error :
772+ conn -> status = CONNECTION_BAD ;
773+ printfPQExpBuffer (& conn -> errorMessage ,
774+ libpq_gettext ("out of memory\n" ));
775+ return false;
750776}
751777
752778/*
@@ -829,6 +855,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
829855if (conn -> dbName )
830856free (conn -> dbName );
831857conn -> dbName = strdup (dbName );
858+ if (!conn -> dbName )
859+ gotooom_error ;
832860}
833861}
834862
@@ -841,41 +869,53 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
841869if (conn -> pghost )
842870free (conn -> pghost );
843871conn -> pghost = strdup (pghost );
872+ if (!conn -> pghost )
873+ gotooom_error ;
844874}
845875
846876if (pgport && pgport [0 ]!= '\0' )
847877{
848878if (conn -> pgport )
849879free (conn -> pgport );
850880conn -> pgport = strdup (pgport );
881+ if (!conn -> pgport )
882+ gotooom_error ;
851883}
852884
853885if (pgoptions && pgoptions [0 ]!= '\0' )
854886{
855887if (conn -> pgoptions )
856888free (conn -> pgoptions );
857889conn -> pgoptions = strdup (pgoptions );
890+ if (!conn -> pgoptions )
891+ gotooom_error ;
858892}
859893
860894if (pgtty && pgtty [0 ]!= '\0' )
861895{
862896if (conn -> pgtty )
863897free (conn -> pgtty );
864898conn -> pgtty = strdup (pgtty );
899+ if (!conn -> pgtty )
900+ gotooom_error ;
865901}
866902
867903if (login && login [0 ]!= '\0' )
868904{
869905if (conn -> pguser )
870906free (conn -> pguser );
871907conn -> pguser = strdup (login );
908+ if (!conn -> pguser )
909+ gotooom_error ;
872910}
873911
874912if (pwd && pwd [0 ]!= '\0' )
875913{
876914if (conn -> pgpass )
877915free (conn -> pgpass );
878916conn -> pgpass = strdup (pwd );
917+ if (!conn -> pgpass )
918+ gotooom_error ;
879919}
880920
881921/*
@@ -891,6 +931,12 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
891931(void )connectDBComplete (conn );
892932
893933return conn ;
934+
935+ oom_error :
936+ conn -> status = CONNECTION_BAD ;
937+ printfPQExpBuffer (& conn -> errorMessage ,
938+ libpq_gettext ("out of memory\n" ));
939+ return conn ;
894940}
895941
896942
@@ -3530,7 +3576,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
35303576if (strcmp (options [i ].keyword ,optname )== 0 )
35313577{
35323578if (options [i ].val == NULL )
3579+ {
35333580options [i ].val = strdup (optval );
3581+ if (!options [i ].val )
3582+ {
3583+ printfPQExpBuffer (errorMessage ,
3584+ libpq_gettext ("out of memory\n" ));
3585+ free (result );
3586+ return 3 ;
3587+ }
3588+ }
35343589found_keyword = true;
35353590break ;
35363591}
@@ -3753,6 +3808,13 @@ parseServiceFile(const char *serviceFile,
37533808{
37543809if (options [i ].val == NULL )
37553810options [i ].val = strdup (val );
3811+ if (!options [i ].val )
3812+ {
3813+ printfPQExpBuffer (errorMessage ,
3814+ libpq_gettext ("out of memory\n" ));
3815+ fclose (f );
3816+ return 3 ;
3817+ }
37563818found_keyword = true;
37573819break ;
37583820}
@@ -4180,6 +4242,14 @@ conninfo_array_parse(const char **keywords, const char **values,
41804242if (options [k ].val )
41814243free (options [k ].val );
41824244options [k ].val = strdup (str_option -> val );
4245+ if (!options [k ].val )
4246+ {
4247+ printfPQExpBuffer (errorMessage ,
4248+ libpq_gettext ("out of memory\n" ));
4249+ PQconninfoFree (options );
4250+ PQconninfoFree (str_options );
4251+ return NULL ;
4252+ }
41834253break ;
41844254}
41854255}
@@ -4199,6 +4269,7 @@ conninfo_array_parse(const char **keywords, const char **values,
41994269printfPQExpBuffer (errorMessage ,
42004270libpq_gettext ("out of memory\n" ));
42014271PQconninfoFree (options );
4272+ PQconninfoFree (str_options );
42024273return NULL ;
42034274}
42044275}