Skip to content

Commit f6a2209

Browse files
dougwilsonseangarner
authored andcommitted
Fix stray protocol packet errors to be catchable
fixes mysqljs#867
1 parent cb127ef commit f6a2209

File tree

4 files changed

+95
-2
lines changed

4 files changed

+95
-2
lines changed

Changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ you spot any mistakes.
66

77
## HEAD
88

9+
* Fix stray protocol packet errors to be catchable #867
910
* Fix timing of fatal protocol errors bubbling to user #879
1011

1112
## v2.4.1 (2014-07-17)

lib/protocol/Protocol.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,18 @@ Protocol.prototype._validateEnqueue = function(sequence) {
221221

222222
Protocol.prototype._parsePacket = function() {
223223
var sequence = this._queue[0];
224-
var Packet = this._determinePacket(sequence);
225-
var packet = new Packet({
224+
225+
if (!sequence) {
226+
var err = new Error('Received packet with no active sequence.');
227+
err.code = 'PROTOCOL_STRAY_PACKET';
228+
err.fatal = true;
229+
230+
this._delegateError(err);
231+
return;
232+
}
233+
234+
var Packet = this._determinePacket(sequence);
235+
var packet = new Packet({
226236
protocol41: this._config.protocol41
227237
});
228238

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
var assert = require('assert');
2+
var common = require('../../common');
3+
var connection = common.createConnection({port: common.fakeServerPort});
4+
var server = common.createFakeServer();
5+
6+
server.listen(common.fakeServerPort, function (err) {
7+
assert.ifError(err);
8+
9+
connection.on('error', function (err) {
10+
assert.equal(err.code, 'PROTOCOL_STRAY_PACKET');
11+
assert.equal(err.fatal, true);
12+
connection.destroy();
13+
server.destroy();
14+
});
15+
16+
connection.query('SELECT 1', assert.ifError);
17+
});
18+
19+
server.on('connection', function(conn) {
20+
conn.handshake();
21+
conn.on('query', function(packet) {
22+
var resetPacketNumber = this._parser.resetPacketNumber;
23+
24+
// Prevent packet number from being reset
25+
this._parser.resetPacketNumber = function () {};
26+
this._handleQueryPacket(packet);
27+
28+
this._parser.resetPacketNumber = resetPacketNumber;
29+
this._sendPacket(new common.Packets.ResultSetHeaderPacket({
30+
fieldCount: 1
31+
}));
32+
});
33+
});
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
var assert = require('assert');
2+
var common = require('../../common');
3+
var pool = common.createPool({port: common.fakeServerPort});
4+
var server = common.createFakeServer();
5+
6+
var connCount = 0;
7+
8+
server.listen(common.fakeServerPort, function (err) {
9+
assert.ifError(err);
10+
11+
pool.on('error', function (err) {
12+
assert.equal(err.code, 'PROTOCOL_STRAY_PACKET');
13+
assert.equal(err.fatal, true);
14+
connection.destroy();
15+
server.destroy();
16+
});
17+
18+
pool.query('SELECT 1', function (err) {
19+
assert.ifError(err);
20+
21+
pool.getConnection(function (err) {
22+
assert.ifError(err);
23+
assert.equal(connCount, 2);
24+
25+
pool.end(function (err) {
26+
assert.ifError(err);
27+
server.destroy();
28+
});
29+
});
30+
});
31+
});
32+
33+
server.on('connection', function (conn) {
34+
connCount++;
35+
conn.handshake();
36+
conn.on('query', function(packet) {
37+
var resetPacketNumber = this._parser.resetPacketNumber;
38+
39+
// Prevent packet number from being reset
40+
this._parser.resetPacketNumber = function () {};
41+
this._handleQueryPacket(packet);
42+
43+
this._parser.resetPacketNumber = resetPacketNumber;
44+
this._sendPacket(new common.Packets.ResultSetHeaderPacket({
45+
fieldCount: 1
46+
}));
47+
this._parser.resetPacketNumber();
48+
});
49+
});

0 commit comments

Comments
 (0)