more type checking.

This commit is contained in:
Christopher Jeffrey 2016-07-05 16:08:05 -07:00
parent bbe8943bf4
commit f8fadb73a7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 141 additions and 41 deletions

View File

@ -73,49 +73,73 @@ function KeyRing(options) {
KeyRing.prototype.fromOptions = function fromOptions(options) {
var i;
assert(options.key);
if (options.network)
this.network = bcoin.network.get(options.network);
if (options.type)
if (options.type) {
assert(options.type === 'pubkeyhash' || options.type === 'multisig');
this.type = options.type;
}
if (options.m)
if (options.m != null) {
assert(utils.isNumber(options.m));
this.m = options.m;
}
if (options.n)
if (options.n != null) {
assert(utils.isNumber(options.n));
this.n = options.n;
}
if (options.witness != null)
if (options.witness != null) {
assert(typeof options.witness === 'boolean');
this.witness = options.witness;
}
if (options.id)
if (options.id) {
assert(utils.isAlpha(options.id));
this.id = options.id;
}
if (options.name)
if (options.name) {
assert(utils.isAlpha(options.name));
this.name = options.name;
}
if (options.account != null)
if (options.account != null) {
assert(utils.isNumber(options.account));
this.account = options.account;
}
if (options.change != null)
if (options.change != null) {
assert(utils.isNumber(options.change));
this.change = options.change;
}
if (options.index != null)
if (options.index != null) {
assert(utils.isNumber(options.index));
this.index = options.index;
}
this.key = options.key;
if (this.key.getPublicKey)
this.key = this.key.getPublicKey();
assert(Buffer.isBuffer(this.key));
if (this.n > 1)
this.type = 'multisig';
assert(this.type === 'pubkeyhash' || this.type === 'multisig');
if (this.m < 1 || this.m > this.n)
throw new Error('m ranges between 1 and n');
this.addKey(this.key);
if (options.keys) {
assert(Array.isArray(options.keys));
for (i = 0; i < options.keys.length; i++)
this.addKey(options.keys[i]);
}
@ -139,6 +163,8 @@ KeyRing.fromOptions = function fromOptions(options) {
*/
KeyRing.prototype.addKey = function addKey(key) {
assert(Buffer.isBuffer(key));
if (utils.indexOf(this.keys, key) !== -1)
return;
@ -154,6 +180,8 @@ KeyRing.prototype.addKey = function addKey(key) {
*/
KeyRing.prototype.removeKey = function removeKey(key) {
assert(Buffer.isBuffer(key));
if (this.keys.length === this.n)
throw new Error('Cannot remove key.');
@ -639,12 +667,12 @@ KeyRing.prototype.fromJSON = function fromJSON(json) {
assert(json);
assert(typeof json.network === 'string');
assert(typeof json.type === 'string');
assert(json.type === 'pubkeyhash' || json.type === 'multisig');
assert(utils.isNumber(json.m));
assert(utils.isNumber(json.n));
assert(typeof json.witness === 'boolean');
assert(!json.id || typeof json.id === 'string');
assert(!json.name || typeof json.name === 'string');
assert(!json.id || utils.isAlpha(json.id));
assert(!json.name || utils.isAlpha(json.name));
assert(utils.isNumber(json.account));
assert(utils.isNumber(json.change));
assert(utils.isNumber(json.index));

View File

@ -2621,3 +2621,17 @@ utils.mkdir = function mkdir(path, dirname) {
*/
utils._paths = {};
/**
* Test whether a string is alphanumeric
* enough to use as a leveldb key.
* @param {String} key
* @returns {Boolean}
*/
utils.isAlpha = function isAlpha(key) {
if (typeof key !== 'string')
return false;
// We allow /-~ (exclusive), 0-} (inclusive)
return /^[\u0030-\u007d]+$/.test(key);
};

View File

@ -83,9 +83,24 @@ Wallet.prototype.fromOptions = function fromOptions(options) {
master = MasterKey.fromKey(master);
this.master = master;
this.initialized = options.initialized || false;
this.accountDepth = options.accountDepth || 0;
this.id = options.id || this.getID();
if (options.initialized != null) {
assert(typeof options.initialized === 'boolean');
this.initialized = options.initialized;
}
if (options.accountDepth != null) {
assert(utils.isNumber(options.accountDepth));
this.accountDepth = options.accountDepth;
}
if (options.id) {
assert(utils.isAlpha(options.id), 'Wallet ID must be alphanumeric.');
this.id = options.id;
}
if (!this.id)
this.id = this.getID();
return this;
};
@ -1452,11 +1467,16 @@ Wallet.prototype.toJSON = function toJSON() {
*/
Wallet.prototype.fromJSON = function fromJSON(json) {
assert(utils.isAlpha(json.id), 'Wallet ID must be alphanumeric.');
assert(typeof json.initialized === 'boolean');
assert(utils.isNumber(json.accountDepth));
this.network = bcoin.network.get(json.network);
this.id = json.id;
this.initialized = json.initialized;
this.accountDepth = json.accountDepth;
this.master = MasterKey.fromJSON(json.master);
return this;
};
@ -1599,45 +1619,59 @@ Account.prototype.fromOptions = function fromOptions(options) {
var i;
assert(options, 'Options are required.');
assert(options.id, 'Wallet ID is required.');
assert(options.accountKey, 'Account key is required.');
assert(utils.isAlpha(options.id), 'Wallet ID must be alphanumeric.');
assert(utils.isAlpha(options.name), 'Account name must be alphanumeric.');
assert(bcoin.hd.isHD(options.accountKey), 'Account key is required.');
assert(utils.isNumber(options.accountIndex), 'Account index is required.');
this.id = options.id;
this.name = options.name;
if (options.witness != null)
if (options.witness != null) {
assert(typeof options.witness === 'boolean');
this.witness = options.witness;
}
this.accountKey = options.accountKey;
if (options.accountIndex != null)
if (options.accountIndex != null) {
assert(utils.isNumber(options.accountIndex));
this.accountIndex = options.accountIndex;
}
if (options.receiveDepth != null)
if (options.receiveDepth != null) {
assert(utils.isNumber(options.receiveDepth));
this.receiveDepth = options.receiveDepth;
}
if (options.changeDepth != null)
if (options.changeDepth != null) {
assert(utils.isNumber(options.changeDepth));
this.changeDepth = options.changeDepth;
}
if (options.type)
if (options.type) {
assert(options.type === 'pubkeyhash' || options.type === 'multisig');
this.type = options.type;
}
if (options.m)
if (options.m != null) {
assert(utils.isNumber(options.m));
this.m = options.m;
}
if (options.n)
if (options.n != null) {
assert(utils.isNumber(options.n));
this.n = options.n;
}
if (options.initialized != null)
if (options.initialized != null) {
assert(typeof options.initialized === 'boolean');
this.initialized = options.initialized;
}
if (this.n > 1)
this.type = 'multisig';
assert(this.type === 'pubkeyhash' || this.type === 'multisig',
'`type` must be multisig or pubkeyhash.');
if (this.m < 1 || this.m > this.n)
throw new Error('m ranges between 1 and n');
@ -1647,6 +1681,7 @@ Account.prototype.fromOptions = function fromOptions(options) {
this.pushKey(this.accountKey);
if (options.keys) {
assert(Array.isArray(options.keys));
for (i = 0; i < options.keys.length; i++)
this.pushKey(options.keys[i]);
}
@ -2258,6 +2293,17 @@ Account.prototype.fromJSON = function fromJSON(json) {
var i;
assert.equal(json.network, this.network.type);
assert(utils.isAlpha(json.id), 'Wallet ID must be alphanumeric.');
assert(utils.isAlpha(json.name), 'Account name must be alphanumeric.');
assert(typeof json.initialized === 'boolean');
assert(json.type === 'pubkeyhash' || json.type === 'multisig');
assert(utils.isNumber(json.m));
assert(utils.isNumber(json.n));
assert(typeof json.witness === 'boolean');
assert(utils.isNumber(json.accountIndex));
assert(utils.isNumber(json.receiveDepth));
assert(utils.isNumber(json.changeDepth));
assert(Array.isArray(json.keys));
this.id = json.id;
this.name = json.name;
@ -2405,10 +2451,27 @@ function MasterKey(options) {
*/
MasterKey.prototype.fromOptions = function fromOptions(options) {
this.encrypted = !!options.encrypted;
this.iv = options.iv;
this.ciphertext = options.ciphertext;
this.key = options.key || null;
assert(options);
if (options.encrypted != null) {
assert(typeof options.encrypted === 'boolean');
this.encrypted = options.encrypted;
}
if (options.iv) {
assert(Buffer.isBuffer(options.iv));
this.iv = options.iv;
}
if (options.ciphertext) {
assert(Buffer.isBuffer(options.ciphertext));
this.ciphertext = options.ciphertext;
}
if (options.key) {
assert(Buffer.isBuffer(options.key));
this.key = options.key;
}
assert(this.encrypted ? !this.key : this.key);

View File

@ -468,7 +468,7 @@ WalletDB.prototype.get = function get(id, callback) {
*/
WalletDB.prototype.save = function save(wallet, callback) {
if (!isAlpha(wallet.id))
if (!utils.isAlpha(wallet.id))
return callback(new Error('Wallet IDs must be alphanumeric.'));
this.db.put('w/' + wallet.id, wallet.toRaw(), callback);
@ -664,7 +664,7 @@ WalletDB.prototype.getAccountIndex = function getAccountIndex(id, name, callback
WalletDB.prototype.saveAccount = function saveAccount(account, callback) {
var index, batch;
if (!isAlpha(account.name))
if (!utils.isAlpha(account.name))
return callback(new Error('Account names must be alphanumeric.'));
batch = this.db.batch();
@ -1464,11 +1464,6 @@ function serializePaths(out) {
return p.render();
}
function isAlpha(key) {
// We allow /-~ (exclusive), 0-} (inclusive)
return /^[\u0030-\u007d]+$/.test(key);
}
function ReadLock(parent) {
if (!(this instanceof ReadLock))
return new ReadLock(parent);