-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix in the URL parser with go 1.12.8 and github.com/go-sql-driver/mysql #265
Fix in the URL parser with go 1.12.8 and github.com/go-sql-driver/mysql #265
Conversation
Change schemeFromURL to just split the url by :// to find the scheme. It's not required to parse the whole URL. MySQL DSNs aren't valid URLs. Fixes golang-migrate#264
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
2e39eb9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
util_test.go
Outdated
@@ -86,6 +86,19 @@ func TestDatabaseSchemeFromUrlSuccess(t *testing.T) { | |||
} | |||
} | |||
|
|||
func TestDatabaseSchemeFromUrlIssue264(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding this test!
It's cleaner if you could refactor TestDatabaseSchemeFromUrlSuccess
to be table driven.
Also, give this test a better name. e.g. parse MySQL DSN
I think it's fine to reference the issue (use a URL) in a comment though
@@ -139,8 +139,7 @@ func TestPasswordUnencodedReservedURLChars(t *testing.T) { | |||
}{ | |||
{char: "!", parses: true, expectedUsername: username, expectedPassword: basePassword + "!", | |||
encodedURL: schemeAndUsernameAndSep + basePassword + "%21" + urlSuffixAndSep}, | |||
{char: "#", parses: true, expectedUsername: "", expectedPassword: "", | |||
encodedURL: schemeAndUsernameAndSep + basePassword + "#" + urlSuffixAndSep}, | |||
{char: "#", parses: false}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did these tests break? My understanding is that the hostname/port parsing was fixed. I don't see any changes to parseAuthority()
in the fix: golang/go@3226f2d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see where it changed either but it did: https://play.golang.org/p/gQLxfWBQnQD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like these characters needed to be percent-encoded in the first place.
ABNF for authority part of an URI:
authority = [ userinfo "@" ] host [ ":" port ]
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
database/mysql/mysql.go
Outdated
|
||
migrationsTable := purl.Query().Get("x-migrations-table") | ||
migrationsTable := config.Params["x-migrations-table"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using config.Params
works for now, but because we're no longer pre-processing the DSN, if for some reason a x-*
parameter collides with a go-sql-driver/mysql param, then we'll lose it. This is probably fine for now, but something to be wary of.
@dhui I have fixed your suggestions, please check again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing the issues I raised!
if len(u.Scheme) == 0 { | ||
i := strings.Index(url, ":") | ||
|
||
// No : or : is the first character. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment!
@@ -139,8 +139,7 @@ func TestPasswordUnencodedReservedURLChars(t *testing.T) { | |||
}{ | |||
{char: "!", parses: true, expectedUsername: username, expectedPassword: basePassword + "!", | |||
encodedURL: schemeAndUsernameAndSep + basePassword + "%21" + urlSuffixAndSep}, | |||
{char: "#", parses: true, expectedUsername: "", expectedPassword: "", | |||
encodedURL: schemeAndUsernameAndSep + basePassword + "#" + urlSuffixAndSep}, | |||
{char: "#", parses: false}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like these characters needed to be percent-encoded in the first place.
ABNF for authority part of an URI:
authority = [ userinfo "@" ] host [ ":" port ]
userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
@dhui can you please tag a new |
@erikdubbelboer see #264 (comment) (trying to address that through #270) |
No, not while the builds are failing. We only create releases with passing builds. In the meanwhile, you can use the master branch or an older version of Go to work around the issue. |
// Open returns a new driver instance.
func Open(url string) (Driver, error) {
u, err := nurl.Parse(url)
if err != nil {
return nil, fmt.Errorf("Unable to parse URL. Did you escape all reserved URL characters? "+
"See: https://github.com/golang-migrate/migrate#database-urls Error: %v", err)
}
...
} In master branch, golang-migrate/migrate/v4/database/driver.go file used |
Moved schemeFromURL into the database package. Also removed databaseSchemeFromURL and sourceSchemeFromURL as they were just calling schemeFromURL. Fixes golang-migrate#265 (comment)
Otherwise it will fail on MySQL DSNs. Moved schemeFromURL into the database package. Also removed databaseSchemeFromURL and sourceSchemeFromURL as they were just calling schemeFromURL. Fixes golang-migrate#265 (comment)
* Let database.Open() use schemeFromURL as well Otherwise it will fail on MySQL DSNs. Moved schemeFromURL into the database package. Also removed databaseSchemeFromURL and sourceSchemeFromURL as they were just calling schemeFromURL. Fixes #265 (comment) * Moved url functions into internal/url Also merged the test cases. * Add some database tests to improve coverage * Fix suggestions
* Let database.Open() use schemeFromURL as well Otherwise it will fail on MySQL DSNs. Moved schemeFromURL into the database package. Also removed databaseSchemeFromURL and sourceSchemeFromURL as they were just calling schemeFromURL. Fixes golang-migrate/migrate#265 (comment) * Moved url functions into internal/url Also merged the test cases. * Add some database tests to improve coverage * Fix suggestions
Change schemeFromURL to just split the url by :// to find the scheme.
It's not required to parse the whole URL. MySQL DSNs aren't valid URLs.
Fixes #264