Refactor HDPublicKey path validation

This commit is contained in:
Yemel Jardi 2015-01-06 12:08:42 -03:00
parent f78ebeb46c
commit 0beed6efa4
2 changed files with 44 additions and 30 deletions

View File

@ -65,20 +65,23 @@ function HDPublicKey(arg) {
}
}
/**
* Verifies that a given path is valid.
*
* @param {string|number} arg
* @return {boolean}
*/
HDPublicKey.prototype.isValidPath = function(arg) {
try {
this.derive(arg);
return true;
} catch (err) {
return false;
HDPublicKey.isValidPath = function(arg) {
if (_.isString(arg)) {
var indexes = HDPrivateKey._getDerivationIndexes(arg);
return indexes !== null && _.all(indexes, HDPublicKey.isValidPath);
}
if (_.isNumber(arg)) {
return arg >= 0 && arg < HDPublicKey.Hardened;
}
return false;
};
/**
@ -149,25 +152,16 @@ HDPublicKey.prototype._deriveFromString = function (path) {
/* jshint maxcomplexity: 8 */
if (_.contains(path, "'")) {
throw new hdErrors.InvalidIndexCantDeriveHardened();
}
var steps = path.split('/');
// Special cases:
if (_.contains(HDPublicKey.RootElementAlias, path)) {
return this;
}
if (!_.contains(HDPublicKey.RootElementAlias, steps[0])) {
} else if (!HDPublicKey.isValidPath(path)) {
throw new hdErrors.InvalidPath(path);
}
steps = steps.slice(1);
var result = this;
for (var step in steps) {
var index = parseInt(steps[step]);
result = result._deriveWithNumber(index);
}
return result;
var indexes = HDPrivateKey._getDerivationIndexes(path);
var derived = indexes.reduce(function(prev, index) {
return prev._deriveWithNumber(index);
}, this);
return derived;
};
/**

View File

@ -221,20 +221,40 @@ describe('HDPublicKey interface', function() {
});
it('validates correct paths', function() {
var publicKey = new HDPublicKey(xpubkey);
var valid = publicKey.isValidPath('m/123/12');
var valid;
valid = HDPublicKey.isValidPath('m/123/12');
valid.should.equal(true);
var valid = publicKey.isValidPath(123, true);
valid = HDPublicKey.isValidPath('m');
valid.should.equal(true);
valid = HDPublicKey.isValidPath(123);
valid.should.equal(true);
});
it('validates illegal paths', function() {
var publicKey = new HDPublicKey(xpubkey);
var valid = publicKey.isValidPath('m/-1/12');
it('rejects illegal paths', function() {
var valid;
valid = HDPublicKey.isValidPath('m/-1/12');
valid.should.equal(false);
var valid = publicKey.isValidPath(HDPublicKey.Hardened);
valid = HDPublicKey.isValidPath("m/0'/12");
valid.should.equal(false);
valid = HDPublicKey.isValidPath("m/8000000000/12");
valid.should.equal(false);
valid = HDPublicKey.isValidPath('bad path');
valid.should.equal(false);
valid = HDPublicKey.isValidPath(-1);
valid.should.equal(false);
valid = HDPublicKey.isValidPath(8000000000);
valid.should.equal(false);
valid = HDPublicKey.isValidPath(HDPublicKey.Hardened);
valid.should.equal(false);
});