@@ -15,6 +15,7 @@ import (
1515 "testing"
1616 "time"
1717
18+ "github.com/lib/pq/internal/pgpass"
1819 "github.com/lib/pq/internal/pqtest"
1920)
2021
@@ -82,57 +83,8 @@ func TestOpenURL(t *testing.T) {
8283 testURL ("postgresql://" )
8384}
8485
85- const pgpassFile = "/tmp/pqgotest_pgpass"
86-
8786func TestPgpass (t * testing.T ) {
88- testAssert := func (conninfo string , expected string , reason string ) {
89- conn := pqtest .MustDB (t , conninfo )
90-
91- txn , err := conn .Begin ()
92- if err != nil {
93- if expected != "fail" {
94- t .Fatalf (reason , err )
95- }
96- return
97- }
98- rows , err := txn .Query ("SELECT USER" )
99- if err != nil {
100- txn .Rollback ()
101- if expected != "fail" {
102- t .Fatalf (reason , err )
103- }
104- } else {
105- rows .Close ()
106- if expected != "ok" {
107- t .Fatalf (reason , err )
108- }
109- }
110- txn .Rollback ()
111- }
112- testAssert ("" , "ok" , "missing .pgpass, unexpected error %#v" )
113- os .Setenv ("PGPASSFILE" , pgpassFile )
114- defer os .Unsetenv ("PGPASSFILE" )
115- testAssert ("host=/tmp" , "fail" , ", unexpected error %#v" )
116- os .Unsetenv ("PGPASSFILE" )
117-
118- os .Remove (pgpassFile )
119- pgpass , err := os .OpenFile (pgpassFile , os .O_RDWR | os .O_CREATE , 0644 )
120- if err != nil {
121- t .Fatalf ("Unexpected error writing pgpass file %#v" , err )
122- }
123- _ , err = pgpass .WriteString (`# comment
124- server:5432:some_db:some_user:pass_A
125- *:5432:some_db:some_user:pass_B
126- localhost:*:*:*:pass_C
127- *:*:*:*:pass_fallback
128- ` )
129- if err != nil {
130- t .Fatalf ("Unexpected error writing pgpass file %#v" , err )
131- }
132- defer os .Remove (pgpassFile )
133- pgpass .Close ()
134-
135- assertPassword := func (extra values , expected string ) {
87+ assertPassword := func (want string , extra values ) {
13688 o := values {
13789 "host" : "localhost" ,
13890 "sslmode" : "disable" ,
@@ -146,27 +98,42 @@ localhost:*:*:*:pass_C
14698 for k , v := range extra {
14799 o [k ] = v
148100 }
149- ( & conn {}). handlePgpass (o )
150- if pw := o [ "password" ]; pw != expected {
151- t .Fatalf ("For %v expected %s got %s " , extra , expected , pw )
101+ have := pgpass . PasswordFromPgpass (o )
102+ if have != want {
103+ t .Fatalf ("wrong password \n have: %q \n want: %q " , have , want )
152104 }
153105 }
154- // missing passfile means empty psasword
155- assertPassword (values {"host" : "server" , "dbname" : "some_db" , "user" : "some_user" }, "" )
106+
107+ file := pqtest .TempFile (t , "pgpass" , pqtest .NormalizeIndent (`
108+ # comment
109+ server:5432:some_db:some_user:pass_A
110+ *:5432:some_db:some_user:pass_B
111+ localhost:*:*:*:pass_C
112+ *:*:*:*:pass_fallback
113+ ` ))
114+
115+ // Missing passfile means empty password.
116+ assertPassword ("" , values {"host" : "server" , "dbname" : "some_db" , "user" : "some_user" })
117+
156118 // wrong permissions for the pgpass file means it should be ignored
157- assertPassword (values {"host" : "example.com" , "passfile" : pgpassFile , "user" : "foo" }, "" )
158- // fix the permissions and check if it has taken effect
159- os .Chmod (pgpassFile , 0600 )
119+ assertPassword ("" , values {"host" : "example.com" , "passfile" : file , "user" : "foo" })
120+
121+ if err := os .Chmod (file , 0600 ); err != nil { // Fix the permissions
122+ t .Fatal (err )
123+ }
124+
125+ assertPassword ("pass_A" , values {"host" : "server" , "passfile" : file , "dbname" : "some_db" , "user" : "some_user" })
126+ assertPassword ("pass_fallback" , values {"host" : "example.com" , "passfile" : file , "user" : "foo" })
127+ assertPassword ("pass_B" , values {"host" : "example.com" , "passfile" : file , "dbname" : "some_db" , "user" : "some_user" })
160128
161- assertPassword (values {"host" : "server" , "passfile" : pgpassFile , "dbname" : "some_db" , "user" : "some_user" }, "pass_A" )
162- assertPassword (values {"host" : "example.com" , "passfile" : pgpassFile , "user" : "foo" }, "pass_fallback" )
163- assertPassword (values {"host" : "example.com" , "passfile" : pgpassFile , "dbname" : "some_db" , "user" : "some_user" }, "pass_B" )
164129 // localhost also matches the default "" and UNIX sockets
165- assertPassword (values {"host" : "" , "passfile" : pgpassFile , "user" : "some_user" }, "pass_C" )
166- assertPassword (values {"host" : "/tmp" , "passfile" : pgpassFile , "user" : "some_user" }, "pass_C" )
167- // passfile connection parameter takes precedence
130+ assertPassword ("pass_C" , values {"host" : "" , "passfile" : file , "user" : "some_user" })
131+ assertPassword ("pass_C" , values {"host" : "/tmp" , "passfile" : file , "user" : "some_user" })
132+
133+ // Connection parameter takes precedence
168134 os .Setenv ("PGPASSFILE" , "/tmp" )
169- assertPassword (values {"host" : "server" , "passfile" : pgpassFile , "dbname" : "some_db" , "user" : "some_user" }, "pass_A" )
135+ defer os .Unsetenv ("PGPASSFILE" )
136+ assertPassword ("pass_A" , values {"host" : "server" , "passfile" : file , "dbname" : "some_db" , "user" : "some_user" })
170137}
171138
172139func TestExecNilSlice (t * testing.T ) {
@@ -1473,58 +1440,6 @@ func TestRuntimeParameters(t *testing.T) {
14731440 }
14741441}
14751442
1476- func TestQuoteIdentifier (t * testing.T ) {
1477- var cases = []struct {
1478- input string
1479- want string
1480- }{
1481- {`foo` , `"foo"` },
1482- {`foo bar baz` , `"foo bar baz"` },
1483- {`foo"bar` , `"foo""bar"` },
1484- {"foo\x00 bar" , `"foo"` },
1485- {"\x00 foo" , `""` },
1486- }
1487-
1488- for _ , test := range cases {
1489- got := QuoteIdentifier (test .input )
1490- if got != test .want {
1491- t .Errorf ("QuoteIdentifier(%q) = %v want %v" , test .input , got , test .want )
1492- }
1493- }
1494- }
1495-
1496- func TestQuoteLiteral (t * testing.T ) {
1497- var cases = []struct {
1498- input string
1499- want string
1500- }{
1501- {`foo` , `'foo'` },
1502- {`foo bar baz` , `'foo bar baz'` },
1503- {`foo'bar` , `'foo''bar'` },
1504- {`foo\bar` , ` E'foo\\bar'` },
1505- {`foo\ba'r` , ` E'foo\\ba''r'` },
1506- {`foo"bar` , `'foo"bar'` },
1507- {`foo\x00bar` , ` E'foo\\x00bar'` },
1508- {`\x00foo` , ` E'\\x00foo'` },
1509- {`'` , `''''` },
1510- {`''` , `''''''` },
1511- {`\` , ` E'\\'` },
1512- {`'abc'; DROP TABLE users;` , `'''abc''; DROP TABLE users;'` },
1513- {`\'` , ` E'\\'''` },
1514- {`E'\''` , ` E'E''\\'''''` },
1515- {`e'\''` , ` E'e''\\'''''` },
1516- {`E'\'abc\'; DROP TABLE users;'` , ` E'E''\\''abc\\''; DROP TABLE users;'''` },
1517- {`e'\'abc\'; DROP TABLE users;'` , ` E'e''\\''abc\\''; DROP TABLE users;'''` },
1518- }
1519-
1520- for _ , test := range cases {
1521- got := QuoteLiteral (test .input )
1522- if got != test .want {
1523- t .Errorf ("QuoteLiteral(%q) = %v want %v" , test .input , got , test .want )
1524- }
1525- }
1526- }
1527-
15281443func TestRowsResultTag (t * testing.T ) {
15291444 type ResultTag interface {
15301445 Result () driver.Result
0 commit comments