Socket
Socket
Sign inDemoInstall

mysql

Package Overview
Dependencies
Maintainers
4
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mysql - npm Package Compare versions

Comparing version 2.16.0 to 2.17.0

12

Changes.md

@@ -7,2 +7,14 @@ # Changes

## v2.17.0 (2019-04-17)
* Add reverse type lookup for small performance gain #2170
* Fix `connection.threadId` missing on handshake failure
* Fix duplicate packet name in debug output
* Fix no password support for old password protocol
* Remove special case for handshake in determine packet code
* Small performance improvement starting command sequence
* Support auth switch in change user flow #1776
* Support Node.js 11.x
* Update `bignumber.js` to 6.0.0
## v2.16.0 (2018-07-17)

@@ -9,0 +21,0 @@

105

lib/Connection.js

@@ -103,2 +103,3 @@ var Crypto = require('crypto');

this._protocol.on('handshake', this._handleProtocolHandshake.bind(this));
this._protocol.on('initialize', this._handleProtocolInitialize.bind(this));
this._protocol.on('unhandledError', this._handleProtocolError.bind(this));

@@ -280,48 +281,48 @@ this._protocol.on('drain', this._handleProtocolDrain.bind(this));

Connection.prototype._startTLS = function _startTLS(onSecure) {
var connection = this;
var secureContext = tls.createSecureContext({
ca : this.config.ssl.ca,
cert : this.config.ssl.cert,
ciphers : this.config.ssl.ciphers,
key : this.config.ssl.key,
passphrase : this.config.ssl.passphrase
});
var connection = this;
// "unpipe"
this._socket.removeAllListeners('data');
this._protocol.removeAllListeners('data');
// socket <-> encrypted
var rejectUnauthorized = this.config.ssl.rejectUnauthorized;
var secureEstablished = false;
var secureSocket = new tls.TLSSocket(this._socket, {
rejectUnauthorized : rejectUnauthorized,
requestCert : true,
secureContext : secureContext,
isServer : false
});
// error handler for secure socket
secureSocket.on('_tlsError', function(err) {
if (secureEstablished) {
connection._handleNetworkError(err);
} else {
createSecureContext(this.config, function (err, secureContext) {
if (err) {
onSecure(err);
return;
}
});
// cleartext <-> protocol
secureSocket.pipe(this._protocol);
this._protocol.on('data', function(data) {
secureSocket.write(data);
});
// "unpipe"
connection._socket.removeAllListeners('data');
connection._protocol.removeAllListeners('data');
secureSocket.on('secure', function() {
secureEstablished = true;
// socket <-> encrypted
var rejectUnauthorized = connection.config.ssl.rejectUnauthorized;
var secureEstablished = false;
var secureSocket = new tls.TLSSocket(connection._socket, {
rejectUnauthorized : rejectUnauthorized,
requestCert : true,
secureContext : secureContext,
isServer : false
});
onSecure(rejectUnauthorized ? this.ssl.verifyError() : null);
// error handler for secure socket
secureSocket.on('_tlsError', function(err) {
if (secureEstablished) {
connection._handleNetworkError(err);
} else {
onSecure(err);
}
});
// cleartext <-> protocol
secureSocket.pipe(connection._protocol);
connection._protocol.on('data', function(data) {
secureSocket.write(data);
});
secureSocket.on('secure', function() {
secureEstablished = true;
onSecure(rejectUnauthorized ? this.ssl.verifyError() : null);
});
// start TLS communications
secureSocket._start();
});
// start TLS communications
secureSocket._start();
};

@@ -439,4 +440,7 @@ } else {

Connection.prototype._handleProtocolHandshake = function _handleProtocolHandshake(packet) {
this.state = 'authenticated';
Connection.prototype._handleProtocolHandshake = function _handleProtocolHandshake() {
this.state = 'authenticated';
};
Connection.prototype._handleProtocolInitialize = function _handleProtocolInitialize(packet) {
this.threadId = packet.threadId;

@@ -460,2 +464,21 @@ };

function createSecureContext (config, cb) {
var context = null;
var error = null;
try {
context = tls.createSecureContext({
ca : config.ssl.ca,
cert : config.ssl.cert,
ciphers : config.ssl.ciphers,
key : config.ssl.key,
passphrase : config.ssl.passphrase
});
} catch (err) {
error = err;
}
cb(error, context);
}
function unwrapFromDomain(fn) {

@@ -462,0 +485,0 @@ return function () {

@@ -5,2 +5,14 @@ var Buffer = require('safe-buffer').Buffer;

function auth(name, data, options) {
options = options || {};
switch (name) {
case 'mysql_native_password':
return Auth.token(options.password, data.slice(0, 20));
default:
return undefined;
}
}
Auth.auth = auth;
function sha1(msg) {

@@ -90,2 +102,6 @@ var hash = Crypto.createHash('sha1');

Auth.scramble323 = function(message, password) {
if (!password) {
return Buffer.alloc(0);
}
var to = Buffer.allocUnsafe(8);

@@ -92,0 +108,0 @@ var hashPass = this.hashPassword(password);

@@ -1,33 +0,72 @@

// Manually extracted from mysql-5.7.9/include/mysql.h.pp
// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html
exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html)
exports.TINY = 0x01; // aka TINYINT, 1 byte
exports.SHORT = 0x02; // aka SMALLINT, 2 bytes
exports.LONG = 0x03; // aka INT, 4 bytes
exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes
exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes
exports.NULL = 0x06; // NULL (used for prepared statements, I think)
exports.TIMESTAMP = 0x07; // aka TIMESTAMP
exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes
exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes
exports.DATE = 0x0a; // aka DATE
exports.TIME = 0x0b; // aka TIME
exports.DATETIME = 0x0c; // aka DATETIME
exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask)
exports.NEWDATE = 0x0e; // aka ?
exports.VARCHAR = 0x0f; // aka VARCHAR (?)
exports.BIT = 0x10; // aka BIT, 1-8 byte
exports.TIMESTAMP2 = 0x11; // aka TIMESTAMP with fractional seconds
exports.DATETIME2 = 0x12; // aka DATETIME with fractional seconds
exports.TIME2 = 0x13; // aka TIME with fractional seconds
exports.JSON = 0xf5; // aka JSON
exports.NEWDECIMAL = 0xf6; // aka DECIMAL
exports.ENUM = 0xf7; // aka ENUM
exports.SET = 0xf8; // aka SET
exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT
exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT
exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT
exports.BLOB = 0xfc; // aka BLOB, TEXT
exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY
exports.STRING = 0xfe; // aka CHAR, BINARY
exports.GEOMETRY = 0xff; // aka GEOMETRY
/**
* MySQL type constants
*
* Extracted from version 5.7.19
*
* !! Generated by generate-type-constants.js, do not modify by hand !!
*/
exports.DECIMAL = 0;
exports.TINY = 1;
exports.SHORT = 2;
exports.LONG = 3;
exports.FLOAT = 4;
exports.DOUBLE = 5;
exports.NULL = 6;
exports.TIMESTAMP = 7;
exports.LONGLONG = 8;
exports.INT24 = 9;
exports.DATE = 10;
exports.TIME = 11;
exports.DATETIME = 12;
exports.YEAR = 13;
exports.NEWDATE = 14;
exports.VARCHAR = 15;
exports.BIT = 16;
exports.TIMESTAMP2 = 17;
exports.DATETIME2 = 18;
exports.TIME2 = 19;
exports.JSON = 245;
exports.NEWDECIMAL = 246;
exports.ENUM = 247;
exports.SET = 248;
exports.TINY_BLOB = 249;
exports.MEDIUM_BLOB = 250;
exports.LONG_BLOB = 251;
exports.BLOB = 252;
exports.VAR_STRING = 253;
exports.STRING = 254;
exports.GEOMETRY = 255;
// Lookup-by-number table
exports[0] = 'DECIMAL';
exports[1] = 'TINY';
exports[2] = 'SHORT';
exports[3] = 'LONG';
exports[4] = 'FLOAT';
exports[5] = 'DOUBLE';
exports[6] = 'NULL';
exports[7] = 'TIMESTAMP';
exports[8] = 'LONGLONG';
exports[9] = 'INT24';
exports[10] = 'DATE';
exports[11] = 'TIME';
exports[12] = 'DATETIME';
exports[13] = 'YEAR';
exports[14] = 'NEWDATE';
exports[15] = 'VARCHAR';
exports[16] = 'BIT';
exports[17] = 'TIMESTAMP2';
exports[18] = 'DATETIME2';
exports[19] = 'TIME2';
exports[245] = 'JSON';
exports[246] = 'NEWDECIMAL';
exports[247] = 'ENUM';
exports[248] = 'SET';
exports[249] = 'TINY_BLOB';
exports[250] = 'MEDIUM_BLOB';
exports[251] = 'LONG_BLOB';
exports[252] = 'BLOB';
exports[253] = 'VAR_STRING';
exports[254] = 'STRING';
exports[255] = 'GEOMETRY';

@@ -12,3 +12,3 @@ var Types = require('../constants/types');

this.name = options.packet.name;
this.type = typeToString(options.packet.type);
this.type = Types[options.packet.type];
this.length = options.packet.length;

@@ -28,9 +28,1 @@ }

};
function typeToString(t) {
for (var k in Types) {
if (Types[k] === t) return k;
}
return undefined;
}

@@ -9,3 +9,3 @@ module.exports = OldPasswordPacket;

OldPasswordPacket.prototype.parse = function(parser) {
this.scrambleBuff = parser.parseNullTerminatedBuffer();
this.scrambleBuff = parser.parsePacketTerminatedBuffer();
};

@@ -15,3 +15,2 @@

writer.writeBuffer(this.scrambleBuff);
writer.writeFiller(1);
};

@@ -126,6 +126,3 @@ var Types = require('../constants/types');

if (Array.isArray(list)) {
for (var i = 0; i < list.length; i++) {
if (Types[list[i]] === type) return true;
}
return false;
return list.indexOf(Types[type]) !== -1;
} else {

@@ -132,0 +129,0 @@ return Boolean(list);

@@ -1,8 +0,10 @@

var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1;
var MUL_32BIT = Math.pow(2, 32);
var PacketHeader = require('./PacketHeader');
var BigNumber = require('bignumber.js');
var Buffer = require('safe-buffer').Buffer;
var BufferList = require('./BufferList');
var PacketHeader = require('./PacketHeader');
var BigNumber = require('bignumber.js');
var Buffer = require('safe-buffer').Buffer;
var BufferList = require('./BufferList');
var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1;
var MUL_32BIT = Math.pow(2, 32);
var PACKET_HEADER_LENGTH = 4;
module.exports = Parser;

@@ -31,67 +33,13 @@ function Parser(options) {

while (!this._paused) {
if (!this._packetHeader) {
if (!this._combineNextBuffers(4)) {
break;
}
var packetHeader = this._tryReadPacketHeader();
this._packetHeader = new PacketHeader(
this.parseUnsignedNumber(3),
this.parseUnsignedNumber(1)
);
if (this._packetHeader.number !== this._nextPacketNumber) {
var err = new Error(
'Packets out of order. Got: ' + this._packetHeader.number + ' ' +
'Expected: ' + this._nextPacketNumber
);
err.code = 'PROTOCOL_PACKETS_OUT_OF_ORDER';
err.fatal = true;
this._onError(err);
}
this.incrementPacketNumber();
if (!packetHeader) {
break;
}
if (!this._combineNextBuffers(this._packetHeader.length)) {
if (!this._combineNextBuffers(packetHeader.length)) {
break;
}
this._packetEnd = this._offset + this._packetHeader.length;
this._packetOffset = this._offset;
if (this._packetHeader.length === MAX_PACKET_LENGTH) {
this._longPacketBuffers.push(this._buffer.slice(this._packetOffset, this._packetEnd));
this._advanceToNextPacket();
continue;
}
this._combineLongPacketBuffers();
// Try...finally to ensure exception safety. Unfortunately this is costing
// us up to ~10% performance in some benchmarks.
var hadException = true;
try {
this._onPacket(this._packetHeader);
hadException = false;
} catch (err) {
if (!err || typeof err.code !== 'string' || err.code.substr(0, 7) !== 'PARSER_') {
throw err; // Rethrow non-MySQL errors
}
// Pass down parser errors
this._onError(err);
hadException = false;
} finally {
this._advanceToNextPacket();
// If we had an exception, the parser while loop will be broken out
// of after the finally block. So we need to make sure to re-enter it
// to continue parsing any bytes that may already have been received.
if (hadException) {
process.nextTick(this.write.bind(this));
}
}
this._parsePacket(packetHeader);
}

@@ -256,3 +204,3 @@ };

if (high >>> 21) {
value = (new BigNumber(low)).plus((new BigNumber(MUL_32BIT)).times(high)).toString();
value = BigNumber(MUL_32BIT).times(high).plus(low).toString();

@@ -473,2 +421,69 @@ if (this._supportBigNumbers) {

Parser.prototype._parsePacket = function _parsePacket(packetHeader) {
this._packetEnd = this._offset + packetHeader.length;
this._packetOffset = this._offset;
if (packetHeader.length === MAX_PACKET_LENGTH) {
this._longPacketBuffers.push(this._buffer.slice(this._packetOffset, this._packetEnd));
this._advanceToNextPacket();
return;
}
this._combineLongPacketBuffers();
var hadException = true;
try {
this._onPacket(packetHeader);
hadException = false;
} catch (err) {
if (!err || typeof err.code !== 'string' || err.code.substr(0, 7) !== 'PARSER_') {
throw err; // Rethrow non-MySQL errors
}
// Pass down parser errors
this._onError(err);
hadException = false;
} finally {
this._advanceToNextPacket();
// If there was an exception, the parser while loop will be broken out
// of after the finally block. So schedule a blank write to re-enter it
// to continue parsing any bytes that may already have been received.
if (hadException) {
process.nextTick(this.write.bind(this));
}
}
};
Parser.prototype._tryReadPacketHeader = function _tryReadPacketHeader() {
if (this._packetHeader) {
return this._packetHeader;
}
if (!this._combineNextBuffers(PACKET_HEADER_LENGTH)) {
return null;
}
this._packetHeader = new PacketHeader(
this.parseUnsignedNumber(3),
this.parseUnsignedNumber(1)
);
if (this._packetHeader.number !== this._nextPacketNumber) {
var err = new Error(
'Packets out of order. Got: ' + this._packetHeader.number + ' ' +
'Expected: ' + this._nextPacketNumber
);
err.code = 'PROTOCOL_PACKETS_OUT_OF_ORDER';
err.fatal = true;
this._onError(err);
}
this.incrementPacketNumber();
return this._packetHeader;
};
Parser.prototype._advanceToNextPacket = function() {

@@ -475,0 +490,0 @@ this._offset = this._packetEnd;

@@ -159,5 +159,2 @@ var Parser = require('./Parser');

})
.on('end', function() {
self._dequeue(sequence);
})
.on('timeout', function() {

@@ -171,4 +168,6 @@ var err = new Error(sequence.constructor.name + ' inactivity timeout');

self._delegateError(err, sequence);
})
.on('start-tls', function() {
});
if (sequence.constructor === Sequences.Handshake) {
sequence.on('start-tls', function () {
sequence._timer.active();

@@ -189,2 +188,15 @@ self._connection._startTLS(function(err) {

sequence.on('end', function () {
self._handshaked = true;
if (!self._fatalError) {
self.emit('handshake', self._handshakeInitializationPacket);
}
});
}
sequence.on('end', function () {
self._dequeue(sequence);
});
if (this._queue.length === 1) {

@@ -268,2 +280,3 @@ this._parser.resetPacketNumber();

this._handshakeInitializationPacket = packet;
this.emit('initialize', packet);
}

@@ -314,8 +327,3 @@

switch (firstByte) {
case 0x00:
if (!this._handshaked) {
this._handshaked = true;
this.emit('handshake', this._handshakeInitializationPacket);
}
return Packets.OkPacket;
case 0x00: return Packets.OkPacket;
case 0xfe: return Packets.EofPacket;

@@ -444,20 +452,18 @@ case 0xff: return Packets.ErrorPacket;

var connection = this._connection;
var headline = incoming
? '<-- '
: '--> ';
var direction = incoming
? '<--'
: '-->';
var packetName = packet.constructor.name;
var threadId = connection && connection.threadId !== null
? ' (' + connection.threadId + ')'
: '';
if (connection && connection.threadId !== null) {
headline += '(' + connection.threadId + ') ';
}
headline += packet.constructor.name;
// check for debug packet restriction
if (Array.isArray(this._config.debug) && this._config.debug.indexOf(packet.constructor.name) === -1) {
if (Array.isArray(this._config.debug) && this._config.debug.indexOf(packetName) === -1) {
return;
}
console.log(headline);
console.log(packet);
console.log('');
var packetPayload = Util.inspect(packet).replace(/^[^{]+/, '');
console.log('%s%s %s %s\n', direction, threadId, packetName, packetPayload);
};

@@ -18,2 +18,10 @@ var Sequence = require('./Sequence');

ChangeUser.prototype.determinePacket = function determinePacket(firstByte) {
switch (firstByte) {
case 0xfe: return Packets.AuthSwitchRequestPacket;
case 0xff: return Packets.ErrorPacket;
default: return undefined;
}
};
ChangeUser.prototype.start = function(handshakeInitializationPacket) {

@@ -38,2 +46,20 @@ var scrambleBuff = handshakeInitializationPacket.scrambleBuff();

ChangeUser.prototype['AuthSwitchRequestPacket'] = function (packet) {
var name = packet.authMethodName;
var data = Auth.auth(name, packet.authMethodData, {
password: this._password
});
if (data !== undefined) {
this.emit('packet', new Packets.AuthSwitchResponsePacket({
data: data
}));
} else {
var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
err.code = 'UNSUPPORTED_AUTH_METHOD';
err.fatal = true;
this.end(err);
}
};
ChangeUser.prototype['ErrorPacket'] = function(packet) {

@@ -40,0 +66,0 @@ var err = this._packetToError(packet);

@@ -37,16 +37,15 @@ var Sequence = require('./Sequence');

Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) {
if (packet.authMethodName === 'mysql_native_password') {
var challenge = packet.authMethodData.slice(0, 20);
var name = packet.authMethodName;
var data = Auth.auth(name, packet.authMethodData, {
password: this._config.password
});
if (data !== undefined) {
this.emit('packet', new Packets.AuthSwitchResponsePacket({
data: Auth.token(this._config.password, challenge)
data: data
}));
} else {
var err = new Error(
'MySQL is requesting the ' + packet.authMethodName + ' authentication method, which is not supported.'
);
err.code = 'UNSUPPORTED_AUTH_METHOD';
var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
err.code = 'UNSUPPORTED_AUTH_METHOD';
err.fatal = true;
this.end(err);

@@ -53,0 +52,0 @@ }

{
"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.16.0",
"version": "2.17.0",
"license": "MIT",

@@ -16,3 +16,3 @@ "author": "Felix Geisendörfer <felix@debuggable.com> (http://debuggable.com/)",

"dependencies": {
"bignumber.js": "4.1.0",
"bignumber.js": "6.0.0",
"readable-stream": "2.3.6",

@@ -24,5 +24,4 @@ "safe-buffer": "5.1.2",

"after": "0.8.2",
"eslint": "4.19.1",
"nyc": "10.3.2",
"seedrandom": "2.4.3",
"eslint": "5.15.1",
"seedrandom": "3.0.1",
"timezone-mock": "0.0.7",

@@ -45,6 +44,6 @@ "urun": "0.0.8",

"test": "node test/run.js",
"test-ci": "nyc --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"test-ci": "node tool/install-nyc.js --nyc-optional --reporter=text -- npm test",
"test-cov": "node tool/install-nyc.js --reporter=html --reporter=text -- npm test",
"version": "node tool/version-changes.js && git add Changes.md"
}
}
# mysql
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Linux Build][travis-image]][travis-url]

@@ -224,3 +224,3 @@ [![Windows Build][appveyor-image]][appveyor-url]

Number objects. This option is ignored if `supportBigNumbers` is disabled.
* `dateStrings`: Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then
* `dateStrings`: Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather than
inflated into JavaScript Date objects. Can be `true`/`false` or an array of type names to keep as

@@ -1159,7 +1159,10 @@ strings. (Default: `false`)

* `err.code`: Either a [MySQL server error][] (e.g.
`'ER_ACCESS_DENIED_ERROR'`), a Node.js error (e.g. `'ECONNREFUSED'`) or an
internal error (e.g. `'PROTOCOL_CONNECTION_LOST'`).
* `err.code`: String, contains the MySQL server error symbol if the error is
a [MySQL server error][] (e.g. `'ER_ACCESS_DENIED_ERROR'`), a Node.js error
code if it is a Node.js error (e.g. `'ECONNREFUSED'`), or an internal error
code (e.g. `'PROTOCOL_CONNECTION_LOST'`).
* `err.errno`: Number, contains the MySQL server error number. Only populated
from [MySQL server error][].
* `err.fatal`: Boolean, indicating if this error is terminal to the connection
object. If the error is not from a MySQL protocol operation, this properly
object. If the error is not from a MySQL protocol operation, this property
will not be defined.

@@ -1174,3 +1177,3 @@ * `err.sql`: String, contains the full SQL of the failed query. This can be

[Error]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error
[MySQL server error]: http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
[MySQL server error]: https://dev.mysql.com/doc/refman/5.5/en/server-error-reference.html

@@ -1309,34 +1312,55 @@ Fatal errors are propagated to *all* pending callbacks. In the example below, a

### Custom type casting
You can also pass a function and handle type casting yourself. You're given some
column information like database, table and name and also type and length. If you
just want to apply a custom type casting to a specific type you can do it and then
fallback to the default. Here's an example of converting `TINYINT(1)` to boolean:
fallback to the default.
The function is provided two arguments `field` and `next` and is expected to
return the value for the given field by invoking the parser functions through
the `field` object.
The `field` argument is a `Field` object and contains data about the field that
need to be parsed. The following are some of the properties on a `Field` object:
* `db` - a string of the database the field came from.
* `table` - a string of the table the field came from.
* `name` - a string of the field name.
* `type` - a string of the field type in all caps.
* `length` - a number of the field length, as given by the database.
The `next` argument is a `function` that, when called, will return the default
type conversaion for the given field.
When getting the field data, the following helper methods are present on the
`field` object:
* `.string()` - parse the field into a string.
* `.buffer()` - parse the field into a `Buffer`.
* `.geometry()` - parse the field as a geometry value.
The MySQL protocol is a text-based protocol. This means that over the wire, all
field types are represented as a string, which is why only string-like functions
are available on the `field` object. Based on the type information (like `INT`),
the type cast should convert the string field into a different JavaScript type
(like a `number`).
Here's an example of converting `TINYINT(1)` to boolean:
```js
connection.query({
sql: '...',
connection = mysql.createConnection({
typeCast: function (field, next) {
if (field.type == 'TINY' && field.length == 1) {
return (field.string() == '1'); // 1 = true, 0 = false
if (field.type === 'TINY' && field.length === 1) {
return (field.string() === '1'); // 1 = true, 0 = false
} else {
return next();
}
return next();
}
});
```
__WARNING: YOU MUST INVOKE the parser using one of these three field functions in your custom typeCast callback. They can only be called once. (see [#539](https://github.com/mysqljs/mysql/issues/539) for discussion)__
```
field.string()
field.buffer()
field.geometry()
```
are aliases for
```
parser.parseLengthCodedString()
parser.parseLengthCodedBuffer()
parser.parseGeometryValue()
```
__You can find which field function you need to use by looking at: [RowDataPacket.prototype._typeCast](https://github.com/mysqljs/mysql/blob/master/lib/protocol/packets/RowDataPacket.js#L41)__
__WARNING: YOU MUST INVOKE the parser using one of these three field functions
in your custom typeCast callback. They can only be called once.__
## Connection Flags

@@ -1437,4 +1461,4 @@

An ideal report would include a clear indication of what the security issue is
and how it would be exploited, ideally with an accompaning proof of concept
("PoC") for collaborators to work again and validate potentional fixes against.
and how it would be exploited, ideally with an accompanying proof of concept
("PoC") for collaborators to work against and validate potentional fixes against.

@@ -1498,13 +1522,12 @@ ## Contributing

[npm-image]: https://img.shields.io/npm/v/mysql.svg
[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/node-mysql/master?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/node-mysql
[coveralls-image]: https://badgen.net/coveralls/c/github/mysqljs/mysql/master
[coveralls-url]: https://coveralls.io/r/mysqljs/mysql?branch=master
[node-image]: https://badgen.net/npm/node/mysql
[node-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/mysql
[npm-url]: https://npmjs.org/package/mysql
[node-version-image]: https://img.shields.io/node/v/mysql.svg
[node-version-url]: https://nodejs.org/en/download/
[travis-image]: https://img.shields.io/travis/mysqljs/mysql/master.svg?label=linux
[npm-version-image]: https://badgen.net/npm/v/mysql
[travis-image]: https://badgen.net/travis/mysqljs/mysql/master
[travis-url]: https://travis-ci.org/mysqljs/mysql
[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/node-mysql/master.svg?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/node-mysql
[coveralls-image]: https://img.shields.io/coveralls/mysqljs/mysql/master.svg
[coveralls-url]: https://coveralls.io/r/mysqljs/mysql?branch=master
[downloads-image]: https://img.shields.io/npm/dm/mysql.svg
[downloads-url]: https://npmjs.org/package/mysql
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc