diff --git a/AUTHORS b/AUTHORS index 051327519..e35e679e5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -61,6 +61,7 @@ Kamil Dziedzic Kei Kamikawa Kevin Malachowski Kieron Woodhouse +Lachlan Orr Lance Tian Lennart Rudolph Leonardo YongUk Kim diff --git a/dsn.go b/dsn.go index 4b71aaab0..dad86a8e2 100644 --- a/dsn.go +++ b/dsn.go @@ -196,7 +196,7 @@ func (cfg *Config) FormatDSN() string { // /dbname buf.WriteByte('/') - buf.WriteString(cfg.DBName) + buf.WriteString(url.QueryEscape(cfg.DBName)) // [?param1=value1&...¶mN=valueN] hasParam := false @@ -358,7 +358,9 @@ func ParseDSN(dsn string) (cfg *Config, err error) { break } } - cfg.DBName = dsn[i+1 : j] + if cfg.DBName, err = url.QueryUnescape(dsn[i+1 : j]); err != nil { + return nil, fmt.Errorf("invalid DSN: failed to unescape database name: %v", err) + } break } diff --git a/dsn_test.go b/dsn_test.go index 41a6a29fa..1c01a16cb 100644 --- a/dsn_test.go +++ b/dsn_test.go @@ -71,6 +71,18 @@ var testDSNs = []struct { }, { "tcp(de:ad:be:ef::ca:fe)/dbname", &Config{Net: "tcp", Addr: "[de:ad:be:ef::ca:fe]:3306", DBName: "dbname", Collation: "utf8mb4_general_ci", Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, AllowNativePasswords: true, CheckConnLiveness: true}, +}, { + "user@tcp(localhost:3306)/db%2Fdevelopment?parseTime=true", + &Config{User: "user", Net: "tcp", Addr: "localhost:3306", DBName: "db/development", Collation: "utf8mb4_general_ci", Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, AllowNativePasswords: true, CheckConnLiveness: true, ParseTime: true}, +}, { + "user:password@/dbname%2F?allowNativePasswords=false&checkConnLiveness=false&maxAllowedPacket=0&allowFallbackToPlaintext=true", + &Config{User: "user", Passwd: "password", Net: "tcp", Addr: "127.0.0.1:3306", DBName: "dbname/", Collation: "utf8mb4_general_ci", Loc: time.UTC, MaxAllowedPacket: 0, AllowFallbackToPlaintext: true, AllowNativePasswords: false, CheckConnLiveness: false}, +}, { + "/dbname%2Fsuffix", + &Config{Net: "tcp", Addr: "127.0.0.1:3306", DBName: "dbname/suffix", Collation: "utf8mb4_general_ci", Loc: time.UTC, MaxAllowedPacket: defaultMaxAllowedPacket, AllowNativePasswords: true, CheckConnLiveness: true}, +}, { + "user:password@/%2Fdbname?loc=UTC&timeout=30s&readTimeout=1s&writeTimeout=1s&allowAllFiles=1&clientFoundRows=true&allowOldPasswords=TRUE&collation=utf8mb4_unicode_ci&maxAllowedPacket=16777216&tls=false&allowCleartextPasswords=true&parseTime=true&rejectReadOnly=true", + &Config{User: "user", Passwd: "password", Net: "tcp", Addr: "127.0.0.1:3306", DBName: "/dbname", Collation: "utf8mb4_unicode_ci", Loc: time.UTC, TLSConfig: "false", AllowCleartextPasswords: true, AllowNativePasswords: true, Timeout: 30 * time.Second, ReadTimeout: time.Second, WriteTimeout: time.Second, AllowAllFiles: true, AllowOldPasswords: true, CheckConnLiveness: true, ClientFoundRows: true, MaxAllowedPacket: 16777216, ParseTime: true, RejectReadOnly: true}, }, }