From 3f0b881a58febd977654e21f3fdedacc4ace7f86 Mon Sep 17 00:00:00 2001 From: Kagami Hiiragi Date: Wed, 11 Feb 2015 17:53:49 +0300 Subject: [PATCH] Use Buffer type for vector in error encode/decode --- lib/messages.js | 28 ++++++++++++++++++++-------- lib/structs.js | 2 +- tests/unit.js | 9 +++++---- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/messages.js b/lib/messages.js index 5e3d16c..dc8243e 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -282,6 +282,7 @@ var inv = exports.inv = { */ encodePayload: function(inventory) { assert(inventory.length <= 50000, "Too many inventory entires"); + // TODO(Kagami): Validate vectors length. var bufs = [structs.var_int.encode(inventory.length)].concat(inventory); return Buffer.concat(bufs); }, @@ -378,18 +379,28 @@ var error = exports.error = { assert(buf.length >= 4, "Buffer is too small"); var decodedFatal = structs.var_int.decode(buf); var decodedBanTime = structs.var_int.decode(decodedFatal.rest); - var decodedVector = structs.var_str.decode(decodedBanTime.rest); - var decodedErrorText = structs.var_str.decode(decodedVector.rest); + + var decodedVectorLength = structs.var_int.decode(decodedBanTime.rest); + // NOTE(Kagami): Inventory vector should be only 32-byte in size but + // currently we don't ensure it. + var vectorLength = decodedVectorLength.value; + var rest = decodedVectorLength.rest; + assert(rest.length >= vectorLength, "Buffer is too small"); + var vector = new Buffer(vectorLength); + rest.copy(vector); + rest = rest.slice(vectorLength); + + var decodedErrorText = structs.var_str.decode(rest); var length = ( decodedFatal.length + decodedBanTime.length + - decodedVector.length + + decodedVectorLength.length + vectorLength + decodedErrorText.length ); return { fatal: decodedFatal.value, banTime: decodedBanTime.value, - vector: decodedVector.str, + vector: vector, errorText: decodedErrorText.str, // Real data length. length: length, @@ -414,13 +425,14 @@ var error = exports.error = { encodePayload: function(opts) { var fatal = opts.fatal || error.WARNING; var banTime = opts.banTime || 0; - var vector = opts.vector || ""; - var errorText = opts.errorText || ""; + // TODO(Kagami): Validate vector length. + var vector = opts.vector || new Buffer(0); return Buffer.concat([ structs.var_int.encode(fatal), structs.var_int.encode(banTime), - structs.var_str.encode(vector), - structs.var_str.encode(errorText), + structs.var_int.encode(vector.length), + vector, + structs.var_str.encode(opts.errorText), ]); }, }; diff --git a/lib/structs.js b/lib/structs.js index 8f34638..b3f6f4f 100644 --- a/lib/structs.js +++ b/lib/structs.js @@ -821,7 +821,7 @@ exports.inv_vect = { /** * Encode inventory vector. * @param {Buffer} buf - Payload to calculate the inventory vector for - * @return {Buffer} Encoded `inv_vect`. + * @return {Buffer} A 32-byte encoded `inv_vect`. */ encode: function(buf) { return bmcrypto.sha512(bmcrypto.sha512(buf)).slice(0, 32); diff --git a/tests/unit.js b/tests/unit.js index 7288276..8f1b004 100644 --- a/tests/unit.js +++ b/tests/unit.js @@ -576,21 +576,22 @@ describe("Message types", function() { var res = error.decode(encoded); expect(res.fatal).to.equal(0); expect(res.banTime).to.equal(0); - expect(res.vector).to.equal(""); + expect(res.vector).to.have.length(0); expect(res.errorText).to.equal("test"); expect(res.length).to.equal(8); + var vector = inv_vect.encode(Buffer("test")); var res = error.decode(error.encode({ fatal: error.FATAL, banTime: 120, - vector: "123", + vector: vector, errorText: "fatal error", })); expect(res.fatal).to.equal(2); expect(res.banTime).to.equal(120); - expect(res.vector).to.equal("123"); + expect(bufferEqual(res.vector, vector)).to.be.true; expect(res.errorText).to.equal("fatal error"); - expect(res.length).to.equal(18); + expect(res.length).to.equal(47); }); }); });