mysql
Advanced tools
Comparing version 2.14.1 to 2.15.0
@@ -7,2 +7,16 @@ # Changes | ||
## v2.15.0 (2017-10-05) | ||
* Add new Amazon RDS ca-central-1 certificate CA to Amazon RDS SSL profile #1809 | ||
* Add new error codes up to MySQL 5.7.19 | ||
* Add `mysql.raw()` to generate pre-escaped values #877 #1821 | ||
* Fix "changedRows" to work on non-English servers #1819 | ||
* Fix error when server sends RST on `QUIT` #1811 | ||
* Fix typo in insecure auth error message | ||
* Support `mysql_native_password` auth switch request for Azure #1396 #1729 #1730 | ||
* Update `sqlstring` to 2.3.0 | ||
- Add `.toSqlString()` escape overriding | ||
- Small performance improvement on `escapeId` | ||
* Update `bignumber.js` to 4.0.4 | ||
## v2.14.1 (2017-08-01) | ||
@@ -9,0 +23,0 @@ |
12
index.js
@@ -98,2 +98,14 @@ var Classes = Object.create(null); | ||
/** | ||
* Wrap raw SQL strings from escape overriding. | ||
* @param {string} sql The raw SQL | ||
* @return {object} Wrapped object | ||
* @public | ||
*/ | ||
exports.raw = function raw(sql) { | ||
var SqlString = loadClass('SqlString'); | ||
return SqlString.raw(sql); | ||
}; | ||
/** | ||
* The type constants. | ||
@@ -100,0 +112,0 @@ * @public |
@@ -56,3 +56,3 @@ var Buffer = require('safe-buffer').Buffer; | ||
// nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8))) | ||
nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0,63]), [0,add]), [0,c]), this.shl32(nr, 8))); | ||
nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0, 63]), [0, add]), [0, c]), this.shl32(nr, 8))); | ||
@@ -109,7 +109,7 @@ // nr2+=(nr2 << 8) ^ nr; | ||
Auth.xor32 = function(a,b){ | ||
Auth.xor32 = function(a, b){ | ||
return [a[0] ^ b[0], a[1] ^ b[1]]; | ||
}; | ||
Auth.add32 = function(a,b){ | ||
Auth.add32 = function(a, b){ | ||
var w1 = a[1] + b[1], | ||
@@ -121,3 +121,3 @@ w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16); | ||
Auth.mul32 = function(a,b){ | ||
Auth.mul32 = function(a, b){ | ||
// based on this example of multiplying 32b ints using 16b | ||
@@ -131,7 +131,7 @@ // http://www.dsprelated.com/showmessage/89790/1.php | ||
Auth.and32 = function(a,b){ | ||
Auth.and32 = function(a, b){ | ||
return [a[0] & b[0], a[1] & b[1]]; | ||
}; | ||
Auth.shl32 = function(a,b){ | ||
Auth.shl32 = function(a, b){ | ||
// assume b is 16 or less | ||
@@ -138,0 +138,0 @@ var w1 = a[1] << b, |
@@ -482,2 +482,39 @@ // Certificates for Amazon RDS | ||
/** | ||
* Amazon RDS ca-central-1 certificate CA 2016 to 2020 | ||
* | ||
* CN = Amazon RDS ca-central-1 CA | ||
* OU = Amazon RDS | ||
* O = Amazon Web Services, Inc. | ||
* L = Seattle | ||
* ST = Washington | ||
* C = US | ||
* P = 2016-09-15T00:10:11Z/2020-03-05T00:10:11Z | ||
* F = D7:E0:16:AB:8A:0B:63:9F:67:1F:16:87:42:F4:0A:EE:73:A6:FC:04 | ||
*/ | ||
'-----BEGIN CERTIFICATE-----\n' | ||
+ 'MIID/zCCAuegAwIBAgIBTzANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMCVVMx\n' | ||
+ 'EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxIjAgBgNVBAoM\n' | ||
+ 'GUFtYXpvbiBXZWIgU2VydmljZXMsIEluYy4xEzARBgNVBAsMCkFtYXpvbiBSRFMx\n' | ||
+ 'GzAZBgNVBAMMEkFtYXpvbiBSRFMgUm9vdCBDQTAeFw0xNjA5MTUwMDEwMTFaFw0y\n' | ||
+ 'MDAzMDUwMDEwMTFaMIGSMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv\n' | ||
+ 'bjEQMA4GA1UEBwwHU2VhdHRsZTEiMCAGA1UECgwZQW1hem9uIFdlYiBTZXJ2aWNl\n' | ||
+ 'cywgSW5jLjETMBEGA1UECwwKQW1hem9uIFJEUzEjMCEGA1UEAwwaQW1hem9uIFJE\n' | ||
+ 'UyBjYS1jZW50cmFsLTEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n' | ||
+ 'AQCZYI/iQ6DrS3ny3t1EwX1wAD+3LMgh7Fd01EW5LIuaK2kYIIQpsVKhxLCit/V5\n' | ||
+ 'AGc/1qiJS1Qz9ODLTh0Na6bZW6EakRzuHJLe32KJtoFYPC7Z09UqzXrpA/XL+1hM\n' | ||
+ 'P0ZmCWsU7Nn/EmvfBp9zX3dZp6P6ATrvDuYaVFr+SA7aT3FXpBroqBS1fyzUPs+W\n' | ||
+ 'c6zTR6+yc4zkHX0XQxC5RH6xjgpeRkoOajA/sNo7AQF7KlWmKHbdVF44cvvAhRKZ\n' | ||
+ 'XaoVs/C4GjkaAEPTCbopYdhzg+KLx9eB2BQnYLRrIOQZtRfbQI2Nbj7p3VsRuOW1\n' | ||
+ 'tlcks2w1Gb0YC6w6SuIMFkl1AgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNV\n' | ||
+ 'HRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBToYWxE1lawl6Ks6NsvpbHQ3GKEtzAf\n' | ||
+ 'BgNVHSMEGDAWgBROAu6sPvYVyEztLPUFwY+chAhJgzANBgkqhkiG9w0BAQsFAAOC\n' | ||
+ 'AQEAG/8tQ0ooi3hoQpa5EJz0/E5VYBsAz3YxA2HoIonn0jJyG16bzB4yZt4vNQMA\n' | ||
+ 'KsNlQ1uwDWYL1nz63axieUUFIxqxl1KmwfhsmLgZ0Hd2mnTPIl2Hw3uj5+wdgGBg\n' | ||
+ 'agnAZ0bajsBYgD2VGQbqjdk2Qn7Fjy3LEWIvGZx4KyZ99OJ2QxB7JOPdauURAtWA\n' | ||
+ 'DKYkP4LLJxtj07DSzG8kuRWb9B47uqUD+eKDIyjfjbnzGtd9HqqzYFau7EX3HVD9\n' | ||
+ '9Qhnjl7bTZ6YfAEZ3nH2t3Vc0z76XfGh47rd0pNRhMV+xpok75asKf/lNh5mcUrr\n' | ||
+ 'VKwflyMkQpSbDCmcdJ90N2xEXQ==\n' | ||
+ '-----END CERTIFICATE-----\n', | ||
/** | ||
* Amazon RDS eu-west-2 certificate CA 2016 to 2020 | ||
@@ -484,0 +521,0 @@ * |
@@ -0,1 +1,3 @@ | ||
exports.AuthSwitchRequestPacket = require('./AuthSwitchRequestPacket'); | ||
exports.AuthSwitchResponsePacket = require('./AuthSwitchResponsePacket'); | ||
exports.ClientAuthenticationPacket = require('./ClientAuthenticationPacket'); | ||
@@ -2,0 +4,0 @@ exports.ComChangeUserPacket = require('./ComChangeUserPacket'); |
@@ -0,1 +1,5 @@ | ||
// Language-neutral expression to match ER_UPDATE_INFO | ||
var ER_UPDATE_INFO_REGEXP = /^[^:0-9]+: [0-9]+[^:0-9]+: ([0-9]+)[^:0-9]+: [0-9]+[^:0-9]*$/; | ||
module.exports = OkPacket; | ||
@@ -25,4 +29,3 @@ function OkPacket(options) { | ||
var m = this.message.match(/\schanged:\s*(\d+)/i); | ||
var m = ER_UPDATE_INFO_REGEXP.exec(this.message); | ||
if (m !== null) { | ||
@@ -29,0 +32,0 @@ this.changedRows = parseInt(m[1], 10); |
@@ -312,2 +312,7 @@ var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1; | ||
Parser.prototype.parsePacketTerminatedBuffer = function parsePacketTerminatedBuffer() { | ||
var length = this._packetEnd - this._offset; | ||
return this.parseBuffer(length); | ||
}; | ||
Parser.prototype.parsePacketTerminatedString = function() { | ||
@@ -314,0 +319,0 @@ var length = this._packetEnd - this._offset; |
@@ -18,3 +18,3 @@ var Sequence = require('./Sequence'); | ||
Handshake.prototype.determinePacket = function(firstByte) { | ||
Handshake.prototype.determinePacket = function determinePacket(firstByte, parser) { | ||
if (firstByte === 0xff) { | ||
@@ -29,3 +29,5 @@ return Packets.ErrorPacket; | ||
if (firstByte === 0xfe) { | ||
return Packets.UseOldPasswordPacket; | ||
return (parser.packetLength() === 1) | ||
? Packets.UseOldPasswordPacket | ||
: Packets.AuthSwitchRequestPacket; | ||
} | ||
@@ -36,2 +38,27 @@ | ||
Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) { | ||
switch (packet.authMethodName) { | ||
case 'mysql_native_password': | ||
case 'mysql_old_password': | ||
default: | ||
} | ||
if (packet.authMethodName === 'mysql_native_password') { | ||
var challenge = packet.authMethodData.slice(0, 20); | ||
this.emit('packet', new Packets.AuthSwitchResponsePacket({ | ||
data: Auth.token(this._config.password, challenge) | ||
})); | ||
} else { | ||
var err = new Error( | ||
'MySQL is requesting the ' + packet.authMethodName + ' authentication method, which is not supported.' | ||
); | ||
err.code = 'UNSUPPORTED_AUTH_METHOD'; | ||
err.fatal = true; | ||
this.end(err); | ||
} | ||
}; | ||
Handshake.prototype['HandshakeInitializationPacket'] = function(packet) { | ||
@@ -89,3 +116,3 @@ this._handshakeInitializationPacket = packet; | ||
var err = new Error( | ||
'MySQL server is requesting the old and insecure pre-4.1 auth mechanism.' + | ||
'MySQL server is requesting the old and insecure pre-4.1 auth mechanism. ' + | ||
'Upgrade the user password or use the {insecureAuth: true} option.' | ||
@@ -92,0 +119,0 @@ ); |
@@ -200,9 +200,9 @@ var Sequence = require('./Sequence'); | ||
this.on('result',function(row,i) { | ||
this.on('result', function(row, i) { | ||
if (!stream.push(row)) self._connection.pause(); | ||
stream.emit('result',row,i); // replicate old emitter | ||
stream.emit('result', row, i); // replicate old emitter | ||
}); | ||
this.on('error',function(err) { | ||
stream.emit('error',err); // Pass on any errors | ||
this.on('error', function(err) { | ||
stream.emit('error', err); // Pass on any errors | ||
}); | ||
@@ -214,4 +214,4 @@ | ||
this.on('fields',function(fields,i) { | ||
stream.emit('fields',fields,i); // replicate old emitter | ||
this.on('fields', function(fields, i) { | ||
stream.emit('fields', fields, i); // replicate old emitter | ||
}); | ||
@@ -218,0 +218,0 @@ |
@@ -14,6 +14,28 @@ var Sequence = require('./Sequence'); | ||
Sequence.call(this, options, callback); | ||
this._started = false; | ||
} | ||
Quit.prototype.end = function end(err) { | ||
if (this._ended) { | ||
return; | ||
} | ||
if (!this._started) { | ||
Sequence.prototype.end.call(this, err); | ||
return; | ||
} | ||
if (err && err.code === 'ECONNRESET' && err.syscall === 'read') { | ||
// Ignore read errors after packet sent | ||
Sequence.prototype.end.call(this); | ||
return; | ||
} | ||
Sequence.prototype.end.call(this, err); | ||
}; | ||
Quit.prototype.start = function() { | ||
this._started = true; | ||
this.emit('packet', new Packets.ComQuitPacket()); | ||
}; |
{ | ||
"name": "mysql", | ||
"description": "A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.", | ||
"version": "2.14.1", | ||
"version": "2.15.0", | ||
"license": "MIT", | ||
@@ -9,2 +9,3 @@ "author": "Felix Geisendörfer <felix@debuggable.com> (http://debuggable.com/)", | ||
"Andrey Sidorov <sidorares@yandex.ru>", | ||
"Bradley Grainger <bgrainger@gmail.com>", | ||
"Douglas Christopher Wilson <doug@somethingdoug.com>", | ||
@@ -16,10 +17,10 @@ "Diogo Resende <dresende@thinkdigital.pt>", | ||
"dependencies": { | ||
"bignumber.js": "4.0.2", | ||
"bignumber.js": "4.0.4", | ||
"readable-stream": "2.3.3", | ||
"safe-buffer": "5.1.1", | ||
"sqlstring": "2.2.0" | ||
"sqlstring": "2.3.0" | ||
}, | ||
"devDependencies": { | ||
"after": "0.8.2", | ||
"eslint": "4.3.0", | ||
"eslint": "4.8.0", | ||
"nyc": "10.3.2", | ||
@@ -45,4 +46,5 @@ "seedrandom": "2.4.3", | ||
"test-ci": "nyc --reporter=text npm test", | ||
"test-cov": "nyc --reporter=html --reporter=text npm test" | ||
"test-cov": "nyc --reporter=html --reporter=text npm test", | ||
"version": "node tool/version-changes.js && git add Changes.md" | ||
} | ||
} |
@@ -460,4 +460,3 @@ # mysql | ||
The `end` method takes an _optional_ callback that you can use to know once | ||
all the connections have ended. The connections end _gracefully_, so all | ||
pending queries will still complete and the time to end the pool will vary. | ||
all the connections have ended. | ||
@@ -467,2 +466,19 @@ **Once `pool.end()` has been called, `pool.getConnection` and other operations | ||
This works by calling `connection.end()` on every active connection in the | ||
pool, which queues a `QUIT` packet on the connection. And sets a flag to | ||
prevent `pool.getConnection` from continuing to create any new connections. | ||
Since this queues a `QUIT` packet on each connection, all commands / queries | ||
already in progress will complete, just like calling `connection.end()`. If | ||
`pool.end` is called and there are connections that have not yet been released, | ||
those connections will fail to execute any new commands after the `pool.end` | ||
since they have a pending `QUIT` packet in their queue; wait until releasing | ||
all connections back to the pool before calling `pool.end()`. | ||
Since the `pool.query` method is a short-hand for the `pool.getConnection` -> | ||
`connection.query` -> `connection.release()` flow, calling `pool.end()` before | ||
all the queries added via `pool.query` have completed, since the underlying | ||
`pool.getConnection` will fail due to all connections ending and not allowing | ||
new connections to be created. | ||
## PoolCluster | ||
@@ -642,2 +658,6 @@ | ||
**Caution** These methods of escaping values only works when the | ||
[NO_BACKSLASH_ESCAPES](https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_backslash_escapes) | ||
SQL mode is disabled (which is the default state for MySQL servers). | ||
In order to avoid SQL Injection attacks, you should always escape any user | ||
@@ -693,2 +713,4 @@ provided data before using it inside a SQL query. You can do so using the | ||
'b'], ['c', 'd']]` turns into `('a', 'b'), ('c', 'd')` | ||
* Objects that have a `toSqlString` method will have `.toSqlString()` called | ||
and the returned value is used as the raw SQL. | ||
* Objects are turned into `key = 'val'` pairs for each enumerable property on | ||
@@ -703,4 +725,3 @@ the object. If the property's value is a function, it is skipped; if the | ||
If you paid attention, you may have noticed that this escaping allows you | ||
to do neat things like this: | ||
This escaping allows you to do neat things like this: | ||
@@ -714,5 +735,25 @@ ```js | ||
console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL' | ||
``` | ||
And the `toSqlString` method allows you to form complex queries with functions: | ||
```js | ||
var CURRENT_TIMESTAMP = { toSqlString: function() { return 'CURRENT_TIMESTAMP()'; } }; | ||
var sql = mysql.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TIMESTAMP, 42]); | ||
console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id = 42 | ||
``` | ||
To generate objects with a `toSqlString` method, the `mysql.raw()` method can | ||
be used. This creates an object that will be left un-touched when using in a `?` | ||
placeholder, useful for using functions as dynamic values: | ||
**Caution** The string provided to `mysql.raw()` will skip all escaping | ||
functions when used, so be careful when passing in unvalidated input. | ||
```js | ||
var CURRENT_TIMESTAMP = mysql.raw('CURRENT_TIMESTAMP()'); | ||
var sql = mysql.format('UPDATE posts SET modified = ? WHERE id = ?', [CURRENT_TIMESTAMP, 42]); | ||
console.log(sql); // UPDATE posts SET modified = CURRENT_TIMESTAMP() WHERE id = 42 | ||
``` | ||
If you feel the need to escape queries by yourself, you can also use the escaping | ||
@@ -719,0 +760,0 @@ function directly: |
Sorry, the diff of this file is too big to display
413961
59
6902
1482
+ Addedbignumber.js@4.0.4(transitive)
+ Addedsqlstring@2.3.0(transitive)
- Removedbignumber.js@4.0.2(transitive)
- Removedsqlstring@2.2.0(transitive)
Updatedbignumber.js@4.0.4
Updatedsqlstring@2.3.0