@@ -333,7 +333,7 @@ static int connectDBStart(PGconn *conn);
333
333
static int connectDBComplete (PGconn * conn );
334
334
static PGPing internal_ping (PGconn * conn );
335
335
static PGconn * makeEmptyPGconn (void );
336
- static void fillPGconn (PGconn * conn , PQconninfoOption * connOptions );
336
+ static bool fillPGconn (PGconn * conn , PQconninfoOption * connOptions );
337
337
static void freePGconn (PGconn * conn );
338
338
static void closePGconn (PGconn * conn );
339
339
static PQconninfoOption * conninfo_init (PQExpBuffer errorMessage );
@@ -585,7 +585,11 @@ PQconnectStartParams(const char *const * keywords,
585
585
/*
586
586
* Move option values into conn structure
587
587
*/
588
- fillPGconn (conn , connOptions );
588
+ if (!fillPGconn (conn , connOptions ))
589
+ {
590
+ PQconninfoFree (connOptions );
591
+ return conn ;
592
+ }
589
593
590
594
/*
591
595
* Free the option info - all is in conn now
@@ -665,19 +669,19 @@ PQconnectStart(const char *conninfo)
665
669
return conn ;
666
670
}
667
671
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
669
681
fillPGconn (PGconn * conn , PQconninfoOption * connOptions )
670
682
{
671
683
const internalPQconninfoOption * option ;
672
684
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
- */
681
685
for (option = PQconninfoOptions ; option -> keyword ; option ++ )
682
686
{
683
687
const char * tmp = conninfo_getval (connOptions , option -> keyword );
@@ -688,9 +692,22 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
688
692
689
693
if (* connmember )
690
694
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 ;
692
707
}
693
708
}
709
+
710
+ return true;
694
711
}
695
712
696
713
/*
@@ -723,7 +740,12 @@ connectOptions1(PGconn *conn, const char *conninfo)
723
740
/*
724
741
* Move option values into conn structure
725
742
*/
726
- fillPGconn (conn , connOptions );
743
+ if (!fillPGconn (conn , connOptions ))
744
+ {
745
+ conn -> status = CONNECTION_BAD ;
746
+ PQconninfoFree (connOptions );
747
+ return false;
748
+ }
727
749
728
750
/*
729
751
* Free the option info - all is in conn now
@@ -753,6 +775,8 @@ connectOptions2(PGconn *conn)
753
775
if (conn -> dbName )
754
776
free (conn -> dbName );
755
777
conn -> dbName = strdup (conn -> pguser );
778
+ if (!conn -> dbName )
779
+ goto oom_error ;
756
780
}
757
781
758
782
/*
@@ -765,7 +789,12 @@ connectOptions2(PGconn *conn)
765
789
conn -> pgpass = PasswordFromFile (conn -> pghost , conn -> pgport ,
766
790
conn -> dbName , conn -> pguser );
767
791
if (conn -> pgpass == NULL )
792
+ {
768
793
conn -> pgpass = strdup (DefaultPassword );
794
+ if (!conn -> pgpass )
795
+ goto oom_error ;
796
+
797
+ }
769
798
else
770
799
conn -> dot_pgpass_used = true;
771
800
}
@@ -823,7 +852,11 @@ connectOptions2(PGconn *conn)
823
852
#endif
824
853
}
825
854
else
855
+ {
826
856
conn -> sslmode = strdup (DefaultSSLMode );
857
+ if (!conn -> sslmode )
858
+ goto oom_error ;
859
+ }
827
860
828
861
/*
829
862
* Resolve special "auto" client_encoding from the locale
@@ -833,6 +866,8 @@ connectOptions2(PGconn *conn)
833
866
{
834
867
free (conn -> client_encoding_initial );
835
868
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 ;
836
871
}
837
872
838
873
/*
@@ -843,6 +878,12 @@ connectOptions2(PGconn *conn)
843
878
conn -> options_valid = true;
844
879
845
880
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;
846
887
}
847
888
848
889
/*
@@ -936,6 +977,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
936
977
if (conn -> dbName )
937
978
free (conn -> dbName );
938
979
conn -> dbName = strdup (dbName );
980
+ if (!conn -> dbName )
981
+ goto oom_error ;
939
982
}
940
983
}
941
984
@@ -948,41 +991,53 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
948
991
if (conn -> pghost )
949
992
free (conn -> pghost );
950
993
conn -> pghost = strdup (pghost );
994
+ if (!conn -> pghost )
995
+ goto oom_error ;
951
996
}
952
997
953
998
if (pgport && pgport [0 ] != '\0' )
954
999
{
955
1000
if (conn -> pgport )
956
1001
free (conn -> pgport );
957
1002
conn -> pgport = strdup (pgport );
1003
+ if (!conn -> pgport )
1004
+ goto oom_error ;
958
1005
}
959
1006
960
1007
if (pgoptions && pgoptions [0 ] != '\0' )
961
1008
{
962
1009
if (conn -> pgoptions )
963
1010
free (conn -> pgoptions );
964
1011
conn -> pgoptions = strdup (pgoptions );
1012
+ if (!conn -> pgoptions )
1013
+ goto oom_error ;
965
1014
}
966
1015
967
1016
if (pgtty && pgtty [0 ] != '\0' )
968
1017
{
969
1018
if (conn -> pgtty )
970
1019
free (conn -> pgtty );
971
1020
conn -> pgtty = strdup (pgtty );
1021
+ if (!conn -> pgtty )
1022
+ goto oom_error ;
972
1023
}
973
1024
974
1025
if (login && login [0 ] != '\0' )
975
1026
{
976
1027
if (conn -> pguser )
977
1028
free (conn -> pguser );
978
1029
conn -> pguser = strdup (login );
1030
+ if (!conn -> pguser )
1031
+ goto oom_error ;
979
1032
}
980
1033
981
1034
if (pwd && pwd [0 ] != '\0' )
982
1035
{
983
1036
if (conn -> pgpass )
984
1037
free (conn -> pgpass );
985
1038
conn -> pgpass = strdup (pwd );
1039
+ if (!conn -> pgpass )
1040
+ goto oom_error ;
986
1041
}
987
1042
988
1043
/*
@@ -998,6 +1053,12 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
998
1053
(void ) connectDBComplete (conn );
999
1054
1000
1055
return conn ;
1056
+
1057
+ oom_error :
1058
+ conn -> status = CONNECTION_BAD ;
1059
+ printfPQExpBuffer (& conn -> errorMessage ,
1060
+ libpq_gettext ("out of memory\n" ));
1061
+ return conn ;
1001
1062
}
1002
1063
1003
1064
@@ -3774,7 +3835,16 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
3774
3835
if (strcmp (options [i ].keyword , optname ) == 0 )
3775
3836
{
3776
3837
if (options [i ].val == NULL )
3838
+ {
3777
3839
options [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
+ }
3778
3848
found_keyword = true;
3779
3849
break ;
3780
3850
}
@@ -3997,6 +4067,13 @@ parseServiceFile(const char *serviceFile,
3997
4067
{
3998
4068
if (options [i ].val == NULL )
3999
4069
options [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
+ }
4000
4077
found_keyword = true;
4001
4078
break ;
4002
4079
}
@@ -4416,6 +4493,14 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
4416
4493
if (options [k ].val )
4417
4494
free (options [k ].val );
4418
4495
options [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
+ }
4419
4504
break ;
4420
4505
}
4421
4506
}
@@ -4599,20 +4684,22 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
4599
4684
{
4600
4685
int prefix_len ;
4601
4686
char * 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 ;
4605
4689
char prevchar = '\0' ;
4606
4690
char * user = NULL ;
4607
4691
char * host = NULL ;
4608
4692
bool retval = false;
4609
4693
4694
+ /* need a modifiable copy of the input URI */
4695
+ buf = strdup (uri );
4610
4696
if (buf == NULL )
4611
4697
{
4612
4698
printfPQExpBuffer (errorMessage ,
4613
4699
libpq_gettext ("out of memory\n" ));
4614
4700
return false;
4615
4701
}
4702
+ start = buf ;
4616
4703
4617
4704
/* Skip the URI prefix */
4618
4705
prefix_len = uri_prefix_length (uri );
@@ -4954,15 +5041,17 @@ conninfo_uri_parse_params(char *params,
4954
5041
static char *
4955
5042
conninfo_uri_decode (const char * str , PQExpBuffer errorMessage )
4956
5043
{
4957
- char * buf = malloc ( strlen ( str ) + 1 ) ;
4958
- char * p = buf ;
5044
+ char * buf ;
5045
+ char * p ;
4959
5046
const char * q = str ;
4960
5047
5048
+ buf = malloc (strlen (str ) + 1 );
4961
5049
if (buf == NULL )
4962
5050
{
4963
5051
printfPQExpBuffer (errorMessage , libpq_gettext ("out of memory\n" ));
4964
5052
return NULL ;
4965
5053
}
5054
+ p = buf ;
4966
5055
4967
5056
for (;;)
4968
5057
{
@@ -5107,7 +5196,6 @@ conninfo_storeval(PQconninfoOption *connOptions,
5107
5196
else
5108
5197
{
5109
5198
value_copy = strdup (value );
5110
-
5111
5199
if (value_copy == NULL )
5112
5200
{
5113
5201
printfPQExpBuffer (errorMessage , libpq_gettext ("out of memory\n" ));
@@ -5667,6 +5755,12 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
5667
5755
ret = strdup (t );
5668
5756
fclose (fp );
5669
5757
5758
+ if (!ret )
5759
+ {
5760
+ /* Out of memory. XXX: an error message would be nice. */
5761
+ return NULL ;
5762
+ }
5763
+
5670
5764
/* De-escape password. */
5671
5765
for (p1 = p2 = ret ; * p1 != ':' && * p1 != '\0' ; ++ p1 , ++ p2 )
5672
5766
{
0 commit comments