From f5a790e291ba82b20566f118de2efc4d6dcf0154 Mon Sep 17 00:00:00 2001 From: felixdoerre Date: Thu, 31 Mar 2022 12:45:49 +0200 Subject: [PATCH] Fix postgresql host-v6 literals (#46876) Ipv6 literals in postgresql hosts previously worked and were subsequently broken. This change fixes the parsing and adds additional test cases. --- pkg/tsdb/postgres/postgres.go | 34 +++++++++++++++++++++++------- pkg/tsdb/postgres/postgres_test.go | 27 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/pkg/tsdb/postgres/postgres.go b/pkg/tsdb/postgres/postgres.go index e7e73f0c3ea..527102831b6 100644 --- a/pkg/tsdb/postgres/postgres.go +++ b/pkg/tsdb/postgres/postgres.go @@ -122,18 +122,36 @@ func (s *Service) generateConnectionString(dsInfo sqleng.DataSourceInfo) (string host = dsInfo.URL logger.Debug("Generating connection string with Unix socket specifier", "socket", host) } else { + index := strings.LastIndex(dsInfo.URL, ":") + v6Index := strings.Index(dsInfo.URL, "]") sp := strings.SplitN(dsInfo.URL, ":", 2) host = sp[0] - if len(sp) > 1 { - var err error - port, err = strconv.Atoi(sp[1]) - if err != nil { - return "", errutil.Wrapf(err, "invalid port in host specifier %q", sp[1]) - } + if v6Index == -1 { + if len(sp) > 1 { + var err error + port, err = strconv.Atoi(sp[1]) + if err != nil { + return "", errutil.Wrapf(err, "invalid port in host specifier %q", sp[1]) + } - logger.Debug("Generating connection string with network host/port pair", "host", host, "port", port) + logger.Debug("Generating connection string with network host/port pair", "host", host, "port", port) + } else { + logger.Debug("Generating connection string with network host", "host", host) + } } else { - logger.Debug("Generating connection string with network host", "host", host) + if index == v6Index+1 { + host = dsInfo.URL[0:index] + var err error + port, err = strconv.Atoi(dsInfo.URL[index+1:]) + if err != nil { + return "", errutil.Wrapf(err, "invalid port in host specifier %q", dsInfo.URL[index+1:]) + } + + logger.Debug("Generating ipv6 connection string with network host/port pair", "host", host, "port", port) + } else { + host = dsInfo.URL + logger.Debug("Generating ipv6 connection string with network host", "host", host) + } } } diff --git a/pkg/tsdb/postgres/postgres_test.go b/pkg/tsdb/postgres/postgres_test.go index ae9e4baa2a9..eb7278d47ff 100644 --- a/pkg/tsdb/postgres/postgres_test.go +++ b/pkg/tsdb/postgres/postgres_test.go @@ -67,6 +67,24 @@ func TestGenerateConnectionString(t *testing.T) { tlsSettings: tlsSettings{Mode: "verify-full"}, expConnStr: "user='user' password='password' host='host' dbname='database' port=1234 sslmode='verify-full'", }, + { + desc: "Ipv6 host", + host: "[::1]", + user: "user", + password: "password", + database: "database", + tlsSettings: tlsSettings{Mode: "verify-full"}, + expConnStr: "user='user' password='password' host='[::1]' dbname='database' sslmode='verify-full'", + }, + { + desc: "Ipv6/port host", + host: "[::1]:1234", + user: "user", + password: "password", + database: "database", + tlsSettings: tlsSettings{Mode: "verify-full"}, + expConnStr: "user='user' password='password' host='[::1]' dbname='database' port=1234 sslmode='verify-full'", + }, { desc: "Invalid port", host: "host:invalid", @@ -84,6 +102,15 @@ func TestGenerateConnectionString(t *testing.T) { tlsSettings: tlsSettings{Mode: "verify-full"}, expConnStr: `user='user' password='p\'\\assword' host='host' dbname='database' sslmode='verify-full'`, }, + { + desc: "User/DB with single quote and backslash", + host: "host", + user: `u'\ser`, + password: `password`, + database: `d'\atabase`, + tlsSettings: tlsSettings{Mode: "verify-full"}, + expConnStr: `user='u\'\\ser' password='password' host='host' dbname='d\'\\atabase' sslmode='verify-full'`, + }, { desc: "Custom TLS mode disabled", host: "host",