Add object.validate API
This commit is contained in:
parent
c2cd98fe7f
commit
49e4aa4158
|
@ -316,12 +316,13 @@ var object = exports.object = {
|
||||||
* @param {Object=} opts - Decoding options
|
* @param {Object=} opts - Decoding options
|
||||||
* @param {boolean} opts.allowExpired - Allow expired objects
|
* @param {boolean} opts.allowExpired - Allow expired objects
|
||||||
* @param {boolean} opts.skipPow - Do not validate object POW
|
* @param {boolean} opts.skipPow - Do not validate object POW
|
||||||
* @return {DecodeResult}
|
* @return {DecodeResult} [Decoded `object` structure.]{@link
|
||||||
* [Decoded `object` structure.]{@link module:bitmessage/structs.object.DecodeResult}
|
* module:bitmessage/structs.object.DecodeResult}
|
||||||
|
* @throws {Error} Invalid object
|
||||||
*/
|
*/
|
||||||
decode: function(buf, opts) {
|
decode: function(buf, opts) {
|
||||||
var decoded = message.decode(buf);
|
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);
|
return object.decodePayload(decoded.payload, opts);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -331,11 +332,15 @@ var object = exports.object = {
|
||||||
*/
|
*/
|
||||||
decodePayload: function(buf, opts) {
|
decodePayload: function(buf, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
// 8 + 8 + 4 + (1+) + (1+)
|
// 8 + 8 + 4 + (1+) + (1+)
|
||||||
assert(buf.length >= 22, "object message payload is too small");
|
assert(buf.length >= 22, "object message payload is too small");
|
||||||
assert(buf.length <= 262144, "object message payload is too big");
|
assert(buf.length <= 262144, "object message payload is too big");
|
||||||
var nonce = new Buffer(8);
|
var nonce;
|
||||||
|
if (!opts._validate) {
|
||||||
|
nonce = new Buffer(8);
|
||||||
buf.copy(nonce, 0, 0, 8);
|
buf.copy(nonce, 0, 0, 8);
|
||||||
|
}
|
||||||
|
|
||||||
// TTL.
|
// TTL.
|
||||||
var expiresTime = util.readTimestamp64BE(buf.slice(8, 16));
|
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 decodedVersion = var_int.decode(buf.slice(20));
|
||||||
var decodedStream = var_int.decode(decodedVersion.rest);
|
var decodedStream = var_int.decode(decodedVersion.rest);
|
||||||
var headerLength = 20 + decodedVersion.length + decodedStream.length;
|
var headerLength = 20 + decodedVersion.length + decodedStream.length;
|
||||||
|
|
||||||
|
if (opts._validate) { return; }
|
||||||
|
|
||||||
var objectPayload = new Buffer(decodedStream.rest.length);
|
var objectPayload = new Buffer(decodedStream.rest.length);
|
||||||
decodedStream.rest.copy(objectPayload);
|
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.
|
* Encode `object` message.
|
||||||
* @param {Object} opts - Object options
|
* @param {Object} opts - Object options
|
||||||
|
|
|
@ -114,7 +114,6 @@ describe("Crypto", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(Kagami): Add tests for encodePayload/decodePayload as well.
|
|
||||||
describe("Common structures", function() {
|
describe("Common structures", function() {
|
||||||
describe("message", function() {
|
describe("message", function() {
|
||||||
it("should decode", function() {
|
it("should decode", function() {
|
||||||
|
@ -246,6 +245,24 @@ describe("Common structures", function() {
|
||||||
objectPayload: Buffer("test"),
|
objectPayload: Buffer("test"),
|
||||||
}))).to.throw(/insufficient/i);
|
}))).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() {
|
describe("var_int", function() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user