Add object.validate API

This commit is contained in:
Kagami Hiiragi 2015-02-16 19:47:19 +03:00
parent c2cd98fe7f
commit 49e4aa4158
2 changed files with 66 additions and 6 deletions

View File

@ -316,12 +316,13 @@ var object = exports.object = {
* @param {Object=} opts - Decoding options
* @param {boolean} opts.allowExpired - Allow expired objects
* @param {boolean} opts.skipPow - Do not validate object POW
* @return {DecodeResult}
* [Decoded `object` structure.]{@link module:bitmessage/structs.object.DecodeResult}
* @return {DecodeResult} [Decoded `object` structure.]{@link
* module:bitmessage/structs.object.DecodeResult}
* @throws {Error} Invalid object
*/
decode: function(buf, opts) {
var decoded = message.decode(buf);
assert(decoded.command === "object", "Bad command");
assert(decoded.command === "object", "Given message is not an object");
return object.decodePayload(decoded.payload, opts);
},
@ -331,11 +332,15 @@ var object = exports.object = {
*/
decodePayload: function(buf, opts) {
opts = opts || {};
// 8 + 8 + 4 + (1+) + (1+)
assert(buf.length >= 22, "object message payload is too small");
assert(buf.length <= 262144, "object message payload is too big");
var nonce = new Buffer(8);
buf.copy(nonce, 0, 0, 8);
var nonce;
if (!opts._validate) {
nonce = new Buffer(8);
buf.copy(nonce, 0, 0, 8);
}
// TTL.
var expiresTime = util.readTimestamp64BE(buf.slice(8, 16));
@ -358,6 +363,9 @@ var object = exports.object = {
var decodedVersion = var_int.decode(buf.slice(20));
var decodedStream = var_int.decode(decodedVersion.rest);
var headerLength = 20 + decodedVersion.length + decodedStream.length;
if (opts._validate) { return; }
var objectPayload = new Buffer(decodedStream.rest.length);
decodedStream.rest.copy(objectPayload);
@ -372,6 +380,41 @@ var object = exports.object = {
};
},
/**
* Check whether given `object` message is valid.
* @param {Buffer} buf - Message
* @param {Object=} opts - Any of [object.decode]{@link
* module:bitmessage/structs.object.decode} options
* @return {?Error} Return an error with description if object is
* invalid.
*/
validate: function(buf, opts) {
var decoded;
try {
decoded = message.decode(buf);
} catch(e) {
return e;
}
if (decoded.command !== "object") {
return new Error("Given message is not an object");
}
return object.validatePayload(decoded.payload, opts);
},
/**
* Check whether `object` message payload is valid.
* The same as [validate]{@link
* module:bitmessage/structs.object.validate}.
*/
validatePayload: function(buf, opts) {
opts = objectAssign({}, opts, {_validate: true});
try {
object.decodePayload(buf, opts);
} catch(e) {
return e;
}
},
/**
* Encode `object` message.
* @param {Object} opts - Object options

View File

@ -114,7 +114,6 @@ describe("Crypto", function() {
});
});
// TODO(Kagami): Add tests for encodePayload/decodePayload as well.
describe("Common structures", function() {
describe("message", function() {
it("should decode", function() {
@ -246,6 +245,24 @@ describe("Common structures", function() {
objectPayload: Buffer("test"),
}))).to.throw(/insufficient/i);
});
it("should allow to validate object", function() {
var verackmsg = message.encode("verack");
var err = object.validate(verackmsg);
expect(err.message).to.match(/not an object/i);
var obj = object.encodePayload({
nonce: Buffer(8),
ttl: 111,
type: object.MSG,
version: 1,
objectPayload: Buffer(0),
});
err = object.validatePayload(obj);
expect(err.message).to.match(/insufficient pow/i);
expect(object.validatePayload(obj, {skipPow: true})).to.not.exist;
});
});
describe("var_int", function() {