diff options
Diffstat (limited to 'vendor/github.com/go-sql-driver')
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/AUTHORS | 3 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/CHANGELOG.md | 7 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md | 21 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md | 9 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/README.md | 63 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/driver.go | 20 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/dsn.go | 18 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/errors.go | 3 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/infile.go | 3 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/packets.go | 111 | ||||
| -rw-r--r-- | vendor/github.com/go-sql-driver/mysql/statement.go | 5 | 
11 files changed, 165 insertions, 98 deletions
diff --git a/vendor/github.com/go-sql-driver/mysql/AUTHORS b/vendor/github.com/go-sql-driver/mysql/AUTHORS index 466ac86..1003707 100644 --- a/vendor/github.com/go-sql-driver/mysql/AUTHORS +++ b/vendor/github.com/go-sql-driver/mysql/AUTHORS @@ -18,6 +18,7 @@ Chris Moos <chris at tech9computers.com>  Daniel Nichter <nil at codenode.com>  Daniël van Eeden <git at myname.nl>  DisposaBoy <disposaboy at dby.me> +Egor Smolyakov <egorsmkv at gmail.com>  Frederick Mayle <frederickmayle at gmail.com>  Gustavo Kristic <gkristic at gmail.com>  Hanno Braun <mail at hannobraun.com> @@ -38,11 +39,13 @@ Lucas Liu <extrafliu at gmail.com>  Luke Scott <luke at webconnex.com>  Michael Woolnough <michael.woolnough at gmail.com>  Nicola Peduzzi <thenikso at gmail.com> +Olivier Mengué <dolmen at cpan.org>  Paul Bonser <misterpib at gmail.com>  Runrioter Wung <runrioter at gmail.com>  Soroush Pour <me at soroushjp.com>  Stan Putrya <root.vagner at gmail.com>  Stanley Gunawan <gunawan.stanley at gmail.com> +Xiangyu Hu <xiangyu.hu at outlook.com>  Xiaobing Jiang <s7v7nislands at gmail.com>  Xiuming Chen <cc at cxm.cc>  Zhenye Xie <xiezhenye at gmail.com> diff --git a/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md index 617ad80..6bcad7e 100644 --- a/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md +++ b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md @@ -1,4 +1,4 @@ -## HEAD +## Version 1.3 (2016-12-01)  Changes: @@ -8,6 +8,8 @@ Changes:   - TLS ServerName defaults to the host (#283)   - Refactoring (#400, #410, #437)   - Adjusted documentation for second generation CloudSQL (#485) + - Documented DSN system var quoting rules (#502) + - Made statement.Close() calls idempotent to avoid errors in Go 1.6+ (#512)  New Features: @@ -21,6 +23,7 @@ New Features:   - Support for JSON field type (#414)   - Support for multi-statements and multi-results (#411, #431)   - DSN parameter to set the driver-side max_allowed_packet value manually (#489) + - Native password authentication plugin support (#494, #524)  Bugfixes: @@ -38,6 +41,8 @@ Bugfixes:   - Fixed parsing of floats into float64 when placeholders are used (#434)   - Fixed DSN tests with Go 1.7+ (#459)   - Handle ERR packets while waiting for EOF (#473) + - Invalidate connection on error while discarding additional results (#513) + - Allow terminating packets of length 0 (#516)  ## Version 1.2 (2014-06-03) diff --git a/vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md b/vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md deleted file mode 100644 index d9771f1..0000000 --- a/vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,21 +0,0 @@ -### Issue description -Tell us what should happen and what happens instead - -### Example code -```go -If possible, please enter some example code here to reproduce the issue. -``` - -### Error log -``` -If you have an error log, please paste it here. -``` - -### Configuration -*Driver version (or git SHA):* - -*Go version:* run `go version` in your console - -*Server version:* E.g. MySQL 5.6, MariaDB 10.0.20 - -*Server OS:* E.g. Debian 8.1 (Jessie), Windows 10 diff --git a/vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md b/vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 6f5c7eb..0000000 --- a/vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,9 +0,0 @@ -### Description -Please explain the changes you made here. - -### Checklist -- [ ] Code compiles correctly -- [ ] Created tests which fail without the change (if possible) -- [ ] All tests passing -- [ ] Extended the README / documentation, if necessary -- [ ] Added myself / the copyright holder to the AUTHORS file diff --git a/vendor/github.com/go-sql-driver/mysql/README.md b/vendor/github.com/go-sql-driver/mysql/README.md index a110cf1..6452038 100644 --- a/vendor/github.com/go-sql-driver/mysql/README.md +++ b/vendor/github.com/go-sql-driver/mysql/README.md @@ -1,13 +1,9 @@  # Go-MySQL-Driver -A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) package +A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) package   -**Latest stable Release:** [Version 1.2 (June 03, 2014)](https://github.com/go-sql-driver/mysql/releases) - -[](https://travis-ci.org/go-sql-driver/mysql) -  ---------------------------------------    * [Features](#features)    * [Requirements](#requirements) @@ -30,11 +26,11 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa  ## Features    * Lightweight and [fast](https://github.com/go-sql-driver/sql-benchmark "golang MySQL-Driver performance")    * Native Go implementation. No C-bindings, just pure Go -  * Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](http://godoc.org/github.com/go-sql-driver/mysql#DialFunc) +  * Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](https://godoc.org/github.com/go-sql-driver/mysql#DialFunc)    * Automatic handling of broken connections    * Automatic Connection Pooling *(by database/sql package)*    * Supports queries larger than 16MB -  * Full [`sql.RawBytes`](http://golang.org/pkg/database/sql/#RawBytes) support. +  * Full [`sql.RawBytes`](https://golang.org/pkg/database/sql/#RawBytes) support.    * Intelligent `LONG DATA` handling in prepared statements    * Secure `LOAD DATA LOCAL INFILE` support with file Whitelisting and `io.Reader` support    * Optional `time.Time` parsing @@ -47,14 +43,14 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa  ---------------------------------------  ## Installation -Simple install the package to your [$GOPATH](http://code.google.com/p/go-wiki/wiki/GOPATH "GOPATH") with the [go tool](http://golang.org/cmd/go/ "go command") from shell: +Simple install the package to your [$GOPATH](https://github.com/golang/go/wiki/GOPATH "GOPATH") with the [go tool](https://golang.org/cmd/go/ "go command") from shell:  ```bash  $ go get github.com/go-sql-driver/mysql  ``` -Make sure [Git is installed](http://git-scm.com/downloads) on your machine and in your system's `PATH`. +Make sure [Git is installed](https://git-scm.com/downloads) on your machine and in your system's `PATH`.  ## Usage -_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](http://golang.org/pkg/database/sql) API then. +_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](https://golang.org/pkg/database/sql/) API then.  Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name)  as `dataSourceName`:  ```go @@ -99,13 +95,13 @@ Alternatively, [Config.FormatDSN](https://godoc.org/github.com/go-sql-driver/mys  Passwords can consist of any character. Escaping is **not** necessary.  #### Protocol -See [net.Dial](http://golang.org/pkg/net/#Dial) for more information which networks are available. +See [net.Dial](https://golang.org/pkg/net/#Dial) for more information which networks are available.  In general you should use an Unix domain socket if available and TCP otherwise for best performance.  #### Address  For TCP and UDP networks, addresses have the form `host:port`.  If `host` is a literal IPv6 address, it must be enclosed in square brackets. -The functions [net.JoinHostPort](http://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](http://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form. +The functions [net.JoinHostPort](https://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](https://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form.  For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. `/var/run/mysqld/mysqld.sock` or `/tmp/mysql.sock`. @@ -135,6 +131,15 @@ Default:        false  `allowCleartextPasswords=true` allows using the [cleartext client side plugin](http://dev.mysql.com/doc/en/cleartext-authentication-plugin.html) if required by an account, such as one defined with the [PAM authentication plugin](http://dev.mysql.com/doc/en/pam-authentication-plugin.html). Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include [TLS / SSL](#tls), IPsec, or a private network. +##### `allowNativePasswords` + +``` +Type:           bool +Valid Values:   true, false +Default:        false +``` +`allowNativePasswords=true` allows the usage of the mysql native password method. +  ##### `allowOldPasswords`  ``` @@ -215,11 +220,11 @@ Valid Values:   <escaped name>  Default:        UTC  ``` -Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](http://golang.org/pkg/time/#LoadLocation) for details. +Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](https://golang.org/pkg/time/#LoadLocation) for details.  Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter. -Please keep in mind, that param values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`. +Please keep in mind, that param values must be [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.  ##### `maxAllowedPacket`  ``` @@ -292,7 +297,7 @@ Valid Values:   true, false, skip-verify, <name>  Default:        false  ``` -`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](http://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig). +`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).  ##### `writeTimeout` @@ -306,13 +311,21 @@ I/O write timeout. The value must be a decimal number with an unit suffix ( *"ms  ##### System Variables -All other parameters are interpreted as system variables: -  * `autocommit`: `"SET autocommit=<value>"` -  * [`time_zone`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `"SET time_zone=<value>"` -  * [`tx_isolation`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `"SET tx_isolation=<value>"` -  * `param`: `"SET <param>=<value>"` +Any other parameters are interpreted as system variables: +  * `<boolean_var>=<value>`: `SET <boolean_var>=<value>` +  * `<enum_var>=<value>`: `SET <enum_var>=<value>` +  * `<string_var>=%27<value>%27`: `SET <string_var>='<value>'` + +Rules: +* The values for string variables must be quoted with ' +* The values must also be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed! + (which implies values of string variables must be wrapped with `%27`) + +Examples: +  * `autocommit=1`: `SET autocommit=1` +  * [`time_zone=%27Europe%2FParis%27`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `SET time_zone='Europe/Paris'` +  * [`tx_isolation=%27REPEATABLE-READ%27`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `SET tx_isolation='REPEATABLE-READ'` -*The values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!*  #### Examples  ``` @@ -377,17 +390,17 @@ Files must be whitelisted by registering them with `mysql.RegisterLocalFile(file  To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::<name>` then. Choose different names for different handlers and `DeregisterReaderHandler` when you don't need it anymore. -See the [godoc of Go-MySQL-Driver](http://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details. +See the [godoc of Go-MySQL-Driver](https://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.  ### `time.Time` support  The default internal output type of MySQL `DATE` and `DATETIME` values is `[]byte` which allows you to scan the value into a `[]byte`, `string` or `sql.RawBytes` variable in your programm. -However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](http://golang.org/pkg/time/#Location) with the `loc` DSN parameter. +However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](https://golang.org/pkg/time/#Location) with the `loc` DSN parameter.  **Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes). -Alternatively you can use the [`NullTime`](http://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`. +Alternatively you can use the [`NullTime`](https://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`.  ### Unicode support @@ -422,7 +435,7 @@ That means:    * When distributing, you **must publish** the source code of any **changed files** licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0)    * You **needn't publish** the source code of your library as long as the files licensed under the MPL 2.0 are **unchanged** -Please read the [MPL 2.0 FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html) if you have further questions regarding the license. +Please read the [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) if you have further questions regarding the license.  You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE) diff --git a/vendor/github.com/go-sql-driver/mysql/driver.go b/vendor/github.com/go-sql-driver/mysql/driver.go index 562ddef..0022d1f 100644 --- a/vendor/github.com/go-sql-driver/mysql/driver.go +++ b/vendor/github.com/go-sql-driver/mysql/driver.go @@ -134,9 +134,9 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {  	return mc, nil  } -func handleAuthResult(mc *mysqlConn, cipher []byte) error { +func handleAuthResult(mc *mysqlConn, oldCipher []byte) error {  	// Read Result Packet -	err := mc.readResultOK() +	cipher, err := mc.readResultOK()  	if err == nil {  		return nil // auth successful  	} @@ -150,10 +150,17 @@ func handleAuthResult(mc *mysqlConn, cipher []byte) error {  		// Retry with old authentication method. Note: there are edge cases  		// where this should work but doesn't; this is currently "wontfix":  		// https://github.com/go-sql-driver/mysql/issues/184 + +		// If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is +		// sent and we have to keep using the cipher sent in the init packet. +		if cipher == nil { +			cipher = oldCipher +		} +  		if err = mc.writeOldAuthPacket(cipher); err != nil {  			return err  		} -		err = mc.readResultOK() +		_, err = mc.readResultOK()  	} else if mc.cfg.AllowCleartextPasswords && err == ErrCleartextPassword {  		// Retry with clear text password for  		// http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html @@ -161,7 +168,12 @@ func handleAuthResult(mc *mysqlConn, cipher []byte) error {  		if err = mc.writeClearAuthPacket(); err != nil {  			return err  		} -		err = mc.readResultOK() +		_, err = mc.readResultOK() +	} else if mc.cfg.AllowNativePasswords && err == ErrNativePassword { +		if err = mc.writeNativeAuthPacket(cipher); err != nil { +			return err +		} +		_, err = mc.readResultOK()  	}  	return err  } diff --git a/vendor/github.com/go-sql-driver/mysql/dsn.go b/vendor/github.com/go-sql-driver/mysql/dsn.go index 896be9e..ac00dce 100644 --- a/vendor/github.com/go-sql-driver/mysql/dsn.go +++ b/vendor/github.com/go-sql-driver/mysql/dsn.go @@ -46,6 +46,7 @@ type Config struct {  	AllowAllFiles           bool // Allow all files to be used with LOAD DATA LOCAL INFILE  	AllowCleartextPasswords bool // Allows the cleartext client side plugin +	AllowNativePasswords    bool // Allows the native password authentication method  	AllowOldPasswords       bool // Allows the old insecure password method  	ClientFoundRows         bool // Return number of matching rows instead of rows changed  	ColumnsWithAlias        bool // Prepend table alias to column names @@ -101,6 +102,15 @@ func (cfg *Config) FormatDSN() string {  		}  	} +	if cfg.AllowNativePasswords { +		if hasParam { +			buf.WriteString("&allowNativePasswords=true") +		} else { +			hasParam = true +			buf.WriteString("?allowNativePasswords=true") +		} +	} +  	if cfg.AllowOldPasswords {  		if hasParam {  			buf.WriteString("&allowOldPasswords=true") @@ -381,6 +391,14 @@ func parseDSNParams(cfg *Config, params string) (err error) {  				return errors.New("invalid bool value: " + value)  			} +		// Use native password authentication +		case "allowNativePasswords": +			var isBool bool +			cfg.AllowNativePasswords, isBool = readBool(value) +			if !isBool { +				return errors.New("invalid bool value: " + value) +			} +  		// Use old authentication mode (pre MySQL 4.1)  		case "allowOldPasswords":  			var isBool bool diff --git a/vendor/github.com/go-sql-driver/mysql/errors.go b/vendor/github.com/go-sql-driver/mysql/errors.go index 1543a80..857854e 100644 --- a/vendor/github.com/go-sql-driver/mysql/errors.go +++ b/vendor/github.com/go-sql-driver/mysql/errors.go @@ -22,8 +22,9 @@ var (  	ErrInvalidConn       = errors.New("invalid connection")  	ErrMalformPkt        = errors.New("malformed packet")  	ErrNoTLS             = errors.New("TLS requested but server does not support TLS") -	ErrOldPassword       = errors.New("this user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords")  	ErrCleartextPassword = errors.New("this user requires clear text authentication. If you still want to use it, please add 'allowCleartextPasswords=1' to your DSN") +	ErrNativePassword    = errors.New("this user requires mysql native password authentication.") +	ErrOldPassword       = errors.New("this user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords")  	ErrUnknownPlugin     = errors.New("this authentication plugin is not supported")  	ErrOldProtocol       = errors.New("MySQL server does not support required protocol 41+")  	ErrPktSync           = errors.New("commands out of sync. You can't run this command now") diff --git a/vendor/github.com/go-sql-driver/mysql/infile.go b/vendor/github.com/go-sql-driver/mysql/infile.go index 0f975bb..547357c 100644 --- a/vendor/github.com/go-sql-driver/mysql/infile.go +++ b/vendor/github.com/go-sql-driver/mysql/infile.go @@ -173,7 +173,8 @@ func (mc *mysqlConn) handleInFileRequest(name string) (err error) {  	// read OK packet  	if err == nil { -		return mc.readResultOK() +		_, err = mc.readResultOK() +		return err  	}  	mc.readPacket() diff --git a/vendor/github.com/go-sql-driver/mysql/packets.go b/vendor/github.com/go-sql-driver/mysql/packets.go index f06752b..aafe979 100644 --- a/vendor/github.com/go-sql-driver/mysql/packets.go +++ b/vendor/github.com/go-sql-driver/mysql/packets.go @@ -25,9 +25,9 @@ import (  // Read packet to buffer 'data'  func (mc *mysqlConn) readPacket() ([]byte, error) { -	var payload []byte +	var prevData []byte  	for { -		// Read packet header +		// read packet header  		data, err := mc.buf.readNext(4)  		if err != nil {  			errLog.Print(err) @@ -35,16 +35,10 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {  			return nil, driver.ErrBadConn  		} -		// Packet Length [24 bit] +		// packet length [24 bit]  		pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16) -		if pktLen < 1 { -			errLog.Print(ErrMalformPkt) -			mc.Close() -			return nil, driver.ErrBadConn -		} - -		// Check Packet Sync [8 bit] +		// check packet sync [8 bit]  		if data[3] != mc.sequence {  			if data[3] > mc.sequence {  				return nil, ErrPktSyncMul @@ -53,7 +47,20 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {  		}  		mc.sequence++ -		// Read packet body [pktLen bytes] +		// packets with length 0 terminate a previous packet which is a +		// multiple of (2^24)−1 bytes long +		if pktLen == 0 { +			// there was no previous packet +			if prevData == nil { +				errLog.Print(ErrMalformPkt) +				mc.Close() +				return nil, driver.ErrBadConn +			} + +			return prevData, nil +		} + +		// read packet body [pktLen bytes]  		data, err = mc.buf.readNext(pktLen)  		if err != nil {  			errLog.Print(err) @@ -61,18 +68,17 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {  			return nil, driver.ErrBadConn  		} -		isLastPacket := (pktLen < maxPacketSize) +		// return data if this was the last packet +		if pktLen < maxPacketSize { +			// zero allocations for non-split packets +			if prevData == nil { +				return data, nil +			} -		// Zero allocations for non-splitting packets -		if isLastPacket && payload == nil { -			return data, nil +			return append(prevData, data...), nil  		} -		payload = append(payload, data...) - -		if isLastPacket { -			return payload, nil -		} +		prevData = append(prevData, data...)  	}  } @@ -372,6 +378,26 @@ func (mc *mysqlConn) writeClearAuthPacket() error {  	return mc.writePacket(data)  } +//  Native password authentication method +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse +func (mc *mysqlConn) writeNativeAuthPacket(cipher []byte) error { +	scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.Passwd)) + +	// Calculate the packet length and add a tailing 0 +	pktLen := len(scrambleBuff) +	data := mc.buf.takeSmallBuffer(4 + pktLen) +	if data == nil { +		// can not take the buffer. Something must be wrong with the connection +		errLog.Print(ErrBusyBuffer) +		return driver.ErrBadConn +	} + +	// Add the scramble +	copy(data[4:], scrambleBuff) + +	return mc.writePacket(data) +} +  /******************************************************************************  *                             Command Packets                                 *  ******************************************************************************/ @@ -445,36 +471,43 @@ func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {  ******************************************************************************/  // Returns error if Packet is not an 'Result OK'-Packet -func (mc *mysqlConn) readResultOK() error { +func (mc *mysqlConn) readResultOK() ([]byte, error) {  	data, err := mc.readPacket()  	if err == nil {  		// packet indicator  		switch data[0] {  		case iOK: -			return mc.handleOkPacket(data) +			return nil, mc.handleOkPacket(data)  		case iEOF:  			if len(data) > 1 { -				plugin := string(data[1:bytes.IndexByte(data, 0x00)]) +				pluginEndIndex := bytes.IndexByte(data, 0x00) +				plugin := string(data[1:pluginEndIndex]) +				cipher := data[pluginEndIndex+1 : len(data)-1] +  				if plugin == "mysql_old_password" {  					// using old_passwords -					return ErrOldPassword +					return cipher, ErrOldPassword  				} else if plugin == "mysql_clear_password" {  					// using clear text password -					return ErrCleartextPassword +					return cipher, ErrCleartextPassword +				} else if plugin == "mysql_native_password" { +					// using mysql default authentication method +					return cipher, ErrNativePassword  				} else { -					return ErrUnknownPlugin +					return cipher, ErrUnknownPlugin  				}  			} else { -				return ErrOldPassword +				// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest +				return nil, ErrOldPassword  			}  		default: // Error otherwise -			return mc.handleErrorPacket(data) +			return nil, mc.handleErrorPacket(data)  		}  	} -	return err +	return nil, err  }  // Result Set Header Packet @@ -674,11 +707,15 @@ func (rows *textRows) readRow(dest []driver.Value) error {  	if data[0] == iEOF && len(data) == 5 {  		// server_status [2 bytes]  		rows.mc.status = readStatus(data[3:]) -		if err := rows.mc.discardResults(); err != nil { -			return err +		err = rows.mc.discardResults() +		if err == nil { +			err = io.EOF +		} else { +			// connection unusable +			rows.mc.Close()  		}  		rows.mc = nil -		return io.EOF +		return err  	}  	if data[0] == iERR {  		rows.mc = nil @@ -1079,11 +1116,15 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {  		// EOF Packet  		if data[0] == iEOF && len(data) == 5 {  			rows.mc.status = readStatus(data[3:]) -			if err := rows.mc.discardResults(); err != nil { -				return err +			err = rows.mc.discardResults() +			if err == nil { +				err = io.EOF +			} else { +				// connection unusable +				rows.mc.Close()  			}  			rows.mc = nil -			return io.EOF +			return err  		}  		rows.mc = nil diff --git a/vendor/github.com/go-sql-driver/mysql/statement.go b/vendor/github.com/go-sql-driver/mysql/statement.go index ead9a6b..7f9b045 100644 --- a/vendor/github.com/go-sql-driver/mysql/statement.go +++ b/vendor/github.com/go-sql-driver/mysql/statement.go @@ -24,7 +24,10 @@ type mysqlStmt struct {  func (stmt *mysqlStmt) Close() error {  	if stmt.mc == nil || stmt.mc.netConn == nil { -		errLog.Print(ErrInvalidConn) +		// driver.Stmt.Close can be called more than once, thus this function +		// has to be idempotent. +		// See also Issue #450 and golang/go#16019. +		//errLog.Print(ErrInvalidConn)  		return driver.ErrBadConn  	}  | 
