From 0938eadab5466b73de12bb020fb6a942934cef8f Mon Sep 17 00:00:00 2001 From: eordano Date: Wed, 18 Feb 2015 12:53:02 -0300 Subject: [PATCH 1/3] Add precondition checks to HDPrivateKey.from* --- lib/hdprivatekey.js | 14 +++++++++++++- lib/util/js.js | 3 +++ test/hdprivatekey.js | 37 +++++++++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/lib/hdprivatekey.js b/lib/hdprivatekey.js index 230dc03..989a723 100644 --- a/lib/hdprivatekey.js +++ b/lib/hdprivatekey.js @@ -4,6 +4,7 @@ var assert = require('assert'); var buffer = require('buffer'); var _ = require('lodash'); +var $ = require('./util/preconditions'); var BN = require('./crypto/bn'); var Base58 = require('./encoding/base58'); @@ -277,7 +278,18 @@ HDPrivateKey._validateNetwork = function(data, networkArg) { return null; }; -HDPrivateKey.fromJSON = HDPrivateKey.fromObject = HDPrivateKey.fromString = function(arg) { +HDPrivateKey.fromJSON = function(arg) { + $.checkArgument(JSUtil.isValidJSON(arg), 'No valid JSON string was provided'); + return new HDPrivateKey(arg); +}; + +HDPrivateKey.fromString = function(arg) { + $.checkArgument(_.isString(arg), 'No valid string was provided'); + return new HDPrivateKey(arg); +}; + +HDPrivateKey.fromObject = function(arg) { + $.checkArgument(_.isObject(arg), 'No valid argument was provided'); return new HDPrivateKey(arg); }; diff --git a/lib/util/js.js b/lib/util/js.js index 9366510..be6f366 100644 --- a/lib/util/js.js +++ b/lib/util/js.js @@ -29,6 +29,9 @@ module.exports = { */ isValidJSON: function isValidJSON(arg) { var parsed; + if (!_.isString(arg)) { + return false; + } try { parsed = JSON.parse(arg); } catch (e) { diff --git a/test/hdprivatekey.js b/test/hdprivatekey.js index 665eb37..3c47898 100644 --- a/test/hdprivatekey.js +++ b/test/hdprivatekey.js @@ -78,14 +78,39 @@ describe('HDPrivate key interface', function() { )); }); - describe('should error with a nonsensical argument', function() { - it('like a number', function() { + describe('instantiation', function() { + it('invalid argument: can not instantiate from a number', function() { expectFailBuilding(1, hdErrors.UnrecognizedArgument); }); - }); - - it('allows no-new calling', function() { - HDPrivateKey(xprivkey).toString().should.equal(xprivkey); + it('allows no-new calling', function() { + HDPrivateKey(xprivkey).toString().should.equal(xprivkey); + }); + var expectStaticMethodFail = function(staticMethod, argument, message) { + expect(HDPrivateKey[staticMethod].bind(null, argument)).to.throw(message); + }; + it('fromJSON checks that a valid JSON is provided', function() { + var errorMessage = 'No valid JSON string was provided'; + var method = 'fromJSON'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, 'invalid JSON', errorMessage); + expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); + expectStaticMethodFail(method, {}, errorMessage); + }); + it('fromString checks that a string is provided', function() { + var errorMessage = 'No valid string was provided'; + var method = 'fromString'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, {}, errorMessage); + }); + it('fromObject checks that an object is provided', function() { + var errorMessage = 'No valid argument was provided'; + var method = 'fromObject'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, '', errorMessage); + }); }); it('inspect() displays correctly', function() { From 9c3170cb3a1da4121a31068491a5de9d88ed66f4 Mon Sep 17 00:00:00 2001 From: eordano Date: Wed, 18 Feb 2015 13:14:02 -0300 Subject: [PATCH 2/3] HDPublicKey: Add precondition checks for static methods --- lib/hdpublickey.js | 15 ++++++++++++++- test/hdprivatekey.js | 22 +++++++++++----------- test/hdpublickey.js | 30 +++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/lib/hdpublickey.js b/lib/hdpublickey.js index 2a85048..e23774a 100644 --- a/lib/hdpublickey.js +++ b/lib/hdpublickey.js @@ -1,6 +1,8 @@ 'use strict'; var _ = require('lodash'); +var $ = require('./util/preconditions'); + var BN = require('./crypto/bn'); var Base58 = require('./encoding/base58'); var Base58Check = require('./encoding/base58check'); @@ -356,7 +358,18 @@ HDPublicKey._validateBufferArguments = function (arg) { } }; -HDPublicKey.fromString = HDPublicKey.fromObject = HDPublicKey.fromJSON = function(arg) { +HDPublicKey.fromJSON = function(arg) { + $.checkArgument(JSUtil.isValidJSON(arg), 'No valid JSON string was provided'); + return new HDPublicKey(arg); +}; + +HDPublicKey.fromObject = function(arg) { + $.checkArgument(_.isObject(arg), 'No valid argument was provided'); + return new HDPublicKey(arg); +}; + +HDPublicKey.fromString = function(arg) { + $.checkArgument(_.isString(arg), 'No valid string was provided'); return new HDPublicKey(arg); }; diff --git a/test/hdprivatekey.js b/test/hdprivatekey.js index 3c47898..eabad67 100644 --- a/test/hdprivatekey.js +++ b/test/hdprivatekey.js @@ -91,25 +91,25 @@ describe('HDPrivate key interface', function() { it('fromJSON checks that a valid JSON is provided', function() { var errorMessage = 'No valid JSON string was provided'; var method = 'fromJSON'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, 'invalid JSON', errorMessage); - expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); - expectStaticMethodFail(method, {}, errorMessage); + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, 'invalid JSON', errorMessage); + expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); + expectStaticMethodFail(method, {}, errorMessage); }); it('fromString checks that a string is provided', function() { var errorMessage = 'No valid string was provided'; var method = 'fromString'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, {}, errorMessage); + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, {}, errorMessage); }); it('fromObject checks that an object is provided', function() { var errorMessage = 'No valid argument was provided'; var method = 'fromObject'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, '', errorMessage); + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, '', errorMessage); }); }); diff --git a/test/hdpublickey.js b/test/hdpublickey.js index df4faf5..54816b0 100644 --- a/test/hdpublickey.js +++ b/test/hdpublickey.js @@ -122,7 +122,35 @@ describe('HDPublicKey interface', function() { return new HDPublicKey(buffers); }, errors.InvalidB58Checksum); }); + }); + describe('building with static methods', function() { + var expectStaticMethodFail = function(staticMethod, argument, message) { + expect(HDPublicKey[staticMethod].bind(null, argument)).to.throw(message); + }; + it('fromJSON checks that a valid JSON is provided', function() { + var errorMessage = 'No valid JSON string was provided'; + var method = 'fromJSON'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, 'invalid JSON', errorMessage); + expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); + expectStaticMethodFail(method, {}, errorMessage); + }); + it('fromString checks that a string is provided', function() { + var errorMessage = 'No valid string was provided'; + var method = 'fromString'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, {}, errorMessage); + }); + it('fromObject checks that an object is provided', function() { + var errorMessage = 'No valid argument was provided'; + var method = 'fromObject'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, '', errorMessage); + }); }); describe('error checking on serialization', function() { @@ -246,7 +274,7 @@ describe('HDPublicKey interface', function() { it('rejects illegal paths', function() { var valid; - + valid = HDPublicKey.isValidPath('m/-1/12'); valid.should.equal(false); From eb8f59aa277f82f87232aeec4eff837ed6578d05 Mon Sep 17 00:00:00 2001 From: eordano Date: Wed, 18 Feb 2015 13:19:34 -0300 Subject: [PATCH 3/3] Drop duplicated code --- test/hdkeys.js | 36 ++++++++++++++++++++++++++++++++++++ test/hdprivatekey.js | 26 -------------------------- test/hdpublickey.js | 29 ----------------------------- 3 files changed, 36 insertions(+), 55 deletions(-) diff --git a/test/hdkeys.js b/test/hdkeys.js index d941eda..36900a0 100644 --- a/test/hdkeys.js +++ b/test/hdkeys.js @@ -10,12 +10,48 @@ /* jshint maxstatements: 100 */ /* jshint unused: false */ +var _ = require('lodash'); var should = require('chai').should(); +var expect = require('chai').expect; var bitcore = require('..'); var Networks = bitcore.Networks; var HDPrivateKey = bitcore.HDPrivateKey; var HDPublicKey = bitcore.HDPublicKey; +describe('HDKeys building with static methods', function() { + var classes = [HDPublicKey, HDPrivateKey]; + var clazz, index; + + _.each(classes, function(clazz) { + var expectStaticMethodFail = function(staticMethod, argument, message) { + expect(clazz[staticMethod].bind(null, argument)).to.throw(message); + }; + it(clazz.name + ' fromJSON checks that a valid JSON is provided', function() { + var errorMessage = 'No valid JSON string was provided'; + var method = 'fromJSON'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, 'invalid JSON', errorMessage); + expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); + expectStaticMethodFail(method, {}, errorMessage); + }); + it(clazz.name + ' fromString checks that a string is provided', function() { + var errorMessage = 'No valid string was provided'; + var method = 'fromString'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, {}, errorMessage); + }); + it(clazz.name + ' fromObject checks that an object is provided', function() { + var errorMessage = 'No valid argument was provided'; + var method = 'fromObject'; + expectStaticMethodFail(method, undefined, errorMessage); + expectStaticMethodFail(method, null, errorMessage); + expectStaticMethodFail(method, '', errorMessage); + }); + }); +}); + describe('BIP32 compliance', function() { it('should initialize test vector 1 from the extended public key', function() { diff --git a/test/hdprivatekey.js b/test/hdprivatekey.js index eabad67..b41ab9f 100644 --- a/test/hdprivatekey.js +++ b/test/hdprivatekey.js @@ -85,32 +85,6 @@ describe('HDPrivate key interface', function() { it('allows no-new calling', function() { HDPrivateKey(xprivkey).toString().should.equal(xprivkey); }); - var expectStaticMethodFail = function(staticMethod, argument, message) { - expect(HDPrivateKey[staticMethod].bind(null, argument)).to.throw(message); - }; - it('fromJSON checks that a valid JSON is provided', function() { - var errorMessage = 'No valid JSON string was provided'; - var method = 'fromJSON'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, 'invalid JSON', errorMessage); - expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); - expectStaticMethodFail(method, {}, errorMessage); - }); - it('fromString checks that a string is provided', function() { - var errorMessage = 'No valid string was provided'; - var method = 'fromString'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, {}, errorMessage); - }); - it('fromObject checks that an object is provided', function() { - var errorMessage = 'No valid argument was provided'; - var method = 'fromObject'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, '', errorMessage); - }); }); it('inspect() displays correctly', function() { diff --git a/test/hdpublickey.js b/test/hdpublickey.js index 54816b0..c0e4938 100644 --- a/test/hdpublickey.js +++ b/test/hdpublickey.js @@ -124,35 +124,6 @@ describe('HDPublicKey interface', function() { }); }); - describe('building with static methods', function() { - var expectStaticMethodFail = function(staticMethod, argument, message) { - expect(HDPublicKey[staticMethod].bind(null, argument)).to.throw(message); - }; - it('fromJSON checks that a valid JSON is provided', function() { - var errorMessage = 'No valid JSON string was provided'; - var method = 'fromJSON'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, 'invalid JSON', errorMessage); - expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); - expectStaticMethodFail(method, {}, errorMessage); - }); - it('fromString checks that a string is provided', function() { - var errorMessage = 'No valid string was provided'; - var method = 'fromString'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, {}, errorMessage); - }); - it('fromObject checks that an object is provided', function() { - var errorMessage = 'No valid argument was provided'; - var method = 'fromObject'; - expectStaticMethodFail(method, undefined, errorMessage); - expectStaticMethodFail(method, null, errorMessage); - expectStaticMethodFail(method, '', errorMessage); - }); - }); - describe('error checking on serialization', function() { var compareType = function(a, b) { expect(a instanceof b).to.equal(true);