Skip to content
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

Merged
merged 6 commits into from
Aug 17, 2019

Conversation

erikdubbelboer
Copy link
Contributor

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

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
justincormack
justincormack previously approved these changes Aug 14, 2019
thaJeztah
thaJeztah previously approved these changes Aug 14, 2019
Copy link
Contributor

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

koenbollen
koenbollen previously approved these changes Aug 14, 2019
Copy link
Member

@dhui dhui left a 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!

database/mysql/mysql.go Outdated Show resolved Hide resolved
util.go Outdated Show resolved Hide resolved
util_test.go Outdated
@@ -86,6 +86,19 @@ func TestDatabaseSchemeFromUrlSuccess(t *testing.T) {
}
}

func TestDatabaseSchemeFromUrlIssue264(t *testing.T) {
Copy link
Member

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},
Copy link
Member

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

Copy link
Contributor Author

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

Copy link
Member

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    = "!" / "$" / "&" / "'" / "(" / ")"
                 / "*" / "+" / "," / ";" / "="

https://tools.ietf.org/html/rfc3986#appendix-A


migrationsTable := purl.Query().Get("x-migrations-table")
migrationsTable := config.Params["x-migrations-table"]
Copy link
Member

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.

database/mysql/mysql_test.go Outdated Show resolved Hide resolved
@erikdubbelboer
Copy link
Contributor Author

@dhui I have fixed your suggestions, please check again.

Copy link
Member

@dhui dhui left a 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.
Copy link
Member

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},
Copy link
Member

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    = "!" / "$" / "&" / "'" / "(" / ")"
                 / "*" / "+" / "," / ";" / "="

https://tools.ietf.org/html/rfc3986#appendix-A

@dhui dhui merged commit eb7d0dd into golang-migrate:master Aug 17, 2019
@erikdubbelboer
Copy link
Contributor Author

@dhui can you please tag a new 4.5.1 release so people can upgrade their dependencies without having to change them to master?

@thaJeztah
Copy link
Contributor

@erikdubbelboer see #264 (comment)

(trying to address that through #270)

@dhui
Copy link
Member

dhui commented Aug 17, 2019

can you please tag a new 4.5.1 release so people can upgrade their dependencies without having to change them to master?

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.
Normally, we only merge in PRs if builds are passing, but are making an exception in this case due to the widespread breakage.

@lou-lan
Copy link

lou-lan commented Aug 18, 2019

// 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 nurl "net/url" package

erikdubbelboer added a commit to erikdubbelboer/migrate that referenced this pull request Aug 18, 2019
Moved schemeFromURL into the database package. Also removed databaseSchemeFromURL
and sourceSchemeFromURL as they were just calling schemeFromURL.

Fixes golang-migrate#265 (comment)
erikdubbelboer added a commit to erikdubbelboer/migrate that referenced this pull request Aug 18, 2019
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)
@erikdubbelboer
Copy link
Contributor Author

@lou-lan you are right, I just created a pull request for this: #271

dhui pushed a commit that referenced this pull request Aug 20, 2019
* 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
FPiety0521 pushed a commit to FPiety0521/Golang-SQL that referenced this pull request May 24, 2023
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incompatibility in the URL parser with go 1.12.8 and github.com/go-sql-driver/mysql
6 participants