From d9f42182623d4473d605a387805c533011b04aee Mon Sep 17 00:00:00 2001 From: Jessica Lord Date: Wed, 22 Nov 2017 14:36:53 -0500 Subject: [PATCH] fix(url parser): only 1 txt record allowed with 2 possible options --- lib/url_parser.js | 22 ++++++++++++-------- test/functional/url_parser_tests.js | 32 +++++++++++------------------ 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/lib/url_parser.js b/lib/url_parser.js index 63621d119c3..331988de177 100644 --- a/lib/url_parser.js +++ b/lib/url_parser.js @@ -58,18 +58,22 @@ module.exports = function(url, options, callback) { let connectionString = connectionStrings.join(',') + '/?'; - dns.resolveTxt(result.host, function(err, records) { + dns.resolveTxt(result.host, function(err, record) { if (err && err.code !== 'ENODATA') return callback(err); - if (err && err.code === 'ENODATA') records = null; + if (err && err.code === 'ENODATA') record = null; + if (record) { + if (record.length > 1) { + return callback(new Error('multiple text records not allowed')); + } + record = record[0]; + if (record.length > 1) record = record.join(''); + else record = record[0]; - if (records) { - let concatRecords = records.map(function(record) { - // A single record with multiple strings gets concatenated - if (record.length > 1) return record.join(''); - else return record; - }); + if (!record.includes('authSource') && !record.includes('replicaSet')) { + return callback(new Error('text record must only set `authSource` or `replicaSet`')); + } - connectionString += concatRecords.join('&'); + connectionString += record; } parseHandler(connectionString, options, callback); diff --git a/test/functional/url_parser_tests.js b/test/functional/url_parser_tests.js index e6bfcc76cb0..e048a3b8487 100644 --- a/test/functional/url_parser_tests.js +++ b/test/functional/url_parser_tests.js @@ -1118,13 +1118,10 @@ describe('Url SRV Parser', function() { }, test: function(done) { // This text record contains two options - // connectTimeoutMS=300000&socketTimeoutMS=300000 parse('mongodb+srv://test5.test.build.10gen.cc', {}, function(err, object) { - var serverOptions = { - socketOptions: { connectTimeoutMS: 300000, socketTimeoutMS: 300000 } - }; expect(err).to.be.null; - expect(object.server_options).to.deep.equal(serverOptions); + expect(object.rs_options.rs_name).to.equal('repl0'); + expect(object.db_options.authSource).to.equal('thisDB'); done(); }); } @@ -1133,7 +1130,7 @@ describe('Url SRV Parser', function() { /** * @ignore */ - it('should build a connection string based on a SRV with multiple TXT records', { + it('should fail if multiple TXT records', { metadata: { requires: { topology: ['single'] } }, @@ -1141,12 +1138,8 @@ describe('Url SRV Parser', function() { // This url has a text record with multiple records // mongodb://localhost.build.10gen.cc:27017/?connectTimeoutMS=200000&socketTimeoutMS=200000 parse('mongodb+srv://test6.test.build.10gen.cc', {}, function(err, object) { - expect(err).to.be.null; - expect(object).to.exist; - expect(object.servers[0].host).to.equal('localhost.test.build.10gen.cc'); - expect(object.servers[0].port).to.equal(27017); - expect(object.server_options.socketOptions.connectTimeoutMS).to.equal(200000); - expect(object.server_options.socketOptions.socketTimeoutMS).to.equal(200000); + expect(err).to.exist; + expect(err.message).to.equal('multiple text records not allowed'); done(); }); } @@ -1155,11 +1148,13 @@ describe('Url SRV Parser', function() { /** * @ignore */ - it('should build a connection string based on SRV, TXT records and options override', { + it.skip('should build a connection string based on SRV, TXT records and options override', { metadata: { requires: { topology: ['single'] } }, test: function(done) { + // TODO this url should error because of multiple text records but need a + // test to check options override // This url has srv and txt records and options passed in through api parse('mongodb+srv://test6.test.build.10gen.cc', { connectTimeoutMS: 250000 }, function( err, @@ -1189,10 +1184,10 @@ describe('Url SRV Parser', function() { }, test: function(done) { // This text record contains a key with no value - // readPreference + // authSource parse('mongodb+srv://test8.test.build.10gen.cc', {}, function(err) { expect(err).to.exist; - expect(err.message).to.equal('query parameter readPreference is an incomplete value pair'); + expect(err.message).to.equal('query parameter authSource is an incomplete value pair'); done(); }); } @@ -1229,13 +1224,10 @@ describe('Url SRV Parser', function() { }, test: function(done) { // This text record contains multiple strings - // "connectTime" "outMS=150000" "&socketT" "imeoutMS" "=" "250000" + // 'replicaS' 'et=rep' 'l0' parse('mongodb+srv://test11.test.build.10gen.cc', function(err, object) { - var serverOptions = { - socketOptions: { connectTimeoutMS: 150000, socketTimeoutMS: 250000 } - }; expect(err).to.be.null; - expect(object.server_options).to.deep.equal(serverOptions); + expect(object.rs_options.rs_name).to.equal('repl0'); done(); }); }