Skip to content

Commit 50f0b8a

Browse files
committed
Trapped parse error when garbage comes down the socket
1 parent 9b59bbc commit 50f0b8a

File tree

5 files changed

+39
-13
lines changed

5 files changed

+39
-13
lines changed

HISTORY

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* Fixes for handling of errors during shutdown off a socket connection
2121
* Correctly applies socket options including timeout
2222
* Cleanup of test management code to close connections correctly
23+
* Handle parser errors better, closing down the connection and emitting an error
2324

2425
0.9.7 2011-11-10
2526
* Added priority setting to replicaset manager

lib/mongodb/connection/connection.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,15 @@ var createDataHandler = exports.Connection.createDataHandler = function(self) {
205205
if(data.length > 4) {
206206
// Retrieve the message size
207207
var sizeOfMessage = binaryutils.decodeUInt32(data, 0);
208+
// If we have a negative sizeOfMessage emit error and return
209+
if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) {
210+
// We got a parse Error fire it off then keep going
211+
self.emit("parseError", {err:"socketHandler", trace:'', bin:self.buffer, parseState:{
212+
sizeOfMessage:sizeOfMessage,
213+
bytesRead:self.bytesRead,
214+
stubBuffer:self.stubBuffer}});
215+
return;
216+
}
208217

209218
// Ensure that the size of message is larger than 0 and less than the max allowed
210219
if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage > data.length) {
@@ -255,14 +264,22 @@ var createDataHandler = exports.Connection.createDataHandler = function(self) {
255264
data = new Buffer(0);
256265

257266
} else {
258-
self.emit("message", data.slice(0, sizeOfMessage));
259-
// Reset state of buffer
260-
self.buffer = null;
261-
self.sizeOfMessage = 0;
262-
self.bytesRead = 0;
263-
self.stubBuffer = null;
264-
// Copy rest of message
265-
data = data.slice(sizeOfMessage);
267+
try {
268+
self.emit("message", data.slice(0, sizeOfMessage));
269+
// Reset state of buffer
270+
self.buffer = null;
271+
self.sizeOfMessage = 0;
272+
self.bytesRead = 0;
273+
self.stubBuffer = null;
274+
// Copy rest of message
275+
data = data.slice(sizeOfMessage);
276+
} catch (err) {
277+
// We got a parse Error fire it off then keep going
278+
self.emit("parseError", {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
279+
sizeOfMessage:sizeOfMessage,
280+
bytesRead:self.bytesRead,
281+
stubBuffer:self.stubBuffer}});
282+
}
266283

267284
}
268285
} else {

lib/mongodb/connection/repl_set_servers.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ ReplSetServers.prototype.allServerInstances = function() {
274274
}
275275

276276
ReplSetServers.prototype.connect = function(parent, options, callback) {
277+
console.log("----------------------------------------------------------------------------------- connect")
277278
if('function' === typeof options) callback = options, options = {};
278279
if(options == null) options = {};
279280
if(!('function' === typeof callback)) callback = null;
@@ -349,7 +350,7 @@ ReplSetServers.prototype.connect = function(parent, options, callback) {
349350
var tags = document.tags ? document.tags : {};
350351
var primary = document.primary;
351352
var me = document.me;
352-
353+
353354
// Error handler for the servers, this handles unexpected errors coming from
354355
// a wrong callback or something else
355356
var errorHandler = function(err) {
@@ -542,6 +543,11 @@ ReplSetServers.prototype.connect = function(parent, options, callback) {
542543
replSetSelf._state.errorMessages.push(err);
543544
}
544545
}
546+
547+
// Check if we have an error in the inital set of servers and callback with error
548+
if(replSetSelf._state.errorMessages.length > 0 && firstCall) {
549+
callback(replSetSelf._state.errorMessages[0], null);
550+
}
545551
}
546552

547553
ReplSetServers.prototype.checkoutWriter = function() {

lib/mongodb/connection/server.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,13 @@ Server.prototype.connect = function(dbInstance, options, callback) {
255255
}
256256
});
257257

258-
// Handle errors
258+
// If we have a parser error we are in an unknown state, close everything and emit
259+
// error
259260
connectionPool.on("parseError", function(message) {
260261
// Force close the pool
261-
if(connectionPool.isConnected()) self.stop();
262+
if(connectionPool.isConnected()) self.stop();
263+
// Emit error
264+
server.emit("error", message);
262265
});
263266

264267
// Boot up connection poole, pass in a locator of callbacks

test/replicaset/connect_test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,13 @@ module.exports = testCase({
143143

144144
new Db('integration_test_', replSet).open(function(err, db) {
145145
test.equal(null, err);
146-
var dbCloseCount = 0;//, serverCloseCount = 0;
146+
var dbCloseCount = 0;
147147
db.on('close', function() { ++dbCloseCount; });
148148

149149
db.close(function() {
150150
// Let all events fire.
151151
process.nextTick(function() {
152152
test.equal(dbCloseCount, 0);
153-
// test.equal(serverCloseCount, db.serverConfig.servers.length);
154153
test.done();
155154
});
156155
});

0 commit comments

Comments
 (0)