diff --git a/lib/messages.js b/lib/messages.js index d970f24..c621de5 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -72,6 +72,8 @@ var PAYLOAD_START = 16; * @returns{Message|undefined} A message or undefined if there is nothing to read. */ var parseMessage = function(network, dataBuffer) { + $.checkArgument(network); + $.checkArgument(dataBuffer); /* jshint maxstatements: 18 */ if (dataBuffer.length < 20) { return; @@ -112,13 +114,9 @@ module.exports.parseMessage = parseMessage; * @name P2P.Message#buildMessage */ Message.buildMessage = function(command, payload) { - try { - var CommandClass = Message.COMMANDS[command]; - return new CommandClass().fromBuffer(payload); - } catch (err) { - console.log('Error while parsing message', err); - throw err; - } + var CommandClass = Message.COMMANDS[command]; + $.checkState(CommandClass, 'Unsupported message command: ' + command); + return new CommandClass().fromBuffer(payload); }; /** diff --git a/test/messages.js b/test/messages.js index 98c6e38..204bfaf 100644 --- a/test/messages.js +++ b/test/messages.js @@ -4,11 +4,15 @@ var chai = require('chai'); var should = chai.should(); +var Buffers = require('buffers'); var bitcore = require('bitcore'); var Data = require('./data/messages'); var P2P = require('../'); var Messages = P2P.Messages; var Networks = bitcore.Networks; +var BufferUtils = bitcore.util.buffer; + +var network = Networks.livenet; describe('Messages', function() { @@ -67,4 +71,49 @@ describe('Messages', function() { }); }); + var buildMessage = function(hex) { + var m = Buffers(); + m.push(new Buffer(hex, 'hex')); + return m; + }; + it('fails with invalid command', function() { + var invalidCommand = 'f9beb4d96d616c6963696f757300000025000000bd5e830c' + + '0102000000ec3995c1bf7269ff728818a65e53af00cbbee6b6eca8ac9ce7bc79d87' + + '7041ed8'; + var fails = function() { + Messages.parseMessage(network, buildMessage(invalidCommand)); + }; + fails.should.throw('Unsupported message command: malicious'); + }); + + it('ignores malformed messages', function() { + var malformed1 = 'd8c4c3d976657273696f6e000000000065000000fc970f1772110' + + '1000100000000000000ba6288540000000001000000000000000000000000000000' + + '0000ffffba8886dceab0010000000000000000000000000000000000ffff0509552' + + '2208de7e1c1ef80a1cea70f2f5361746f7368693a302e392e312fa317050001'; + var malformed2 = 'f9beb4d967657464617461000000000089000000d88134740102' + + '0000006308e4a380c949dbad182747b0f7b6a89e874328ca41f37287f74a81b8f84' + + '86d'; + var malformed3 = 'f9beb4d967657464617461000000000025000000616263640102' + + '00000069ebcbc34a4f9890da9aea0f773beba883a9afb1ab9ad7647dd4a1cd346c3' + + '728'; + [malformed1, malformed2, malformed3].forEach(function(malformed) { + var ret = Messages.parseMessage(network, buildMessage(malformed)); + should.not.exist(ret); + }); + }); + + it('Inventory#from family methods work', function() { + var hash = 'eb951630aba498b9a0d10f72b5ea9e39d5ff04b03dc2231e662f52057f948aa1'; + [Messages.Inventory, Messages.GetData, Messages.NotFound].forEach(function(clazz) { + var b = clazz.forBlock(hash); + (b instanceof clazz).should.equal(true); + var t = clazz.forTransaction(hash); + (t instanceof clazz).should.equal(true); + clazz.forBlock(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(b); + clazz.forTransaction(BufferUtils.reverse(new Buffer(hash, 'hex'))).should.deep.equal(t); + }); + + }); + });