From 2ad6a1a77e393d9ca3dd01b55c18aeb3d9dba7a1 Mon Sep 17 00:00:00 2001 From: wltsmrz Date: Thu, 18 Jun 2015 13:50:11 -0700 Subject: [PATCH] Validate UInt hex input --- src/core/serializedobject.js | 14 +- src/core/uint.js | 83 +- test/fixtures/uint.json | 1675 ++++++++++++++++++++++++++++++++++ test/uint-test.js | 113 ++- 4 files changed, 1831 insertions(+), 54 deletions(-) create mode 100644 test/fixtures/uint.json diff --git a/src/core/serializedobject.js b/src/core/serializedobject.js index 8d778911..b6c3b1bb 100644 --- a/src/core/serializedobject.js +++ b/src/core/serializedobject.js @@ -54,7 +54,7 @@ SerializedObject.from_json = function(obj_) { // Create a copy of the object so we don't modify it const obj = extend(true, {}, obj_); - let so = new SerializedObject(); + const so = new SerializedObject(); let typedef; if (typeof obj.TransactionType === 'number') { @@ -216,7 +216,7 @@ SerializedObject.prototype.to_json = function() { this.resetPointer(); - let output = { }; + const output = { }; while (this.pointer < this.buffer.length) { const key_and_value = stypes.parse(this); @@ -265,10 +265,10 @@ SerializedObject.jsonify_structure = function(structure, field_name) { // new Array or Object output = new structure.constructor(); - let keys = Object.keys(structure); + const keys = Object.keys(structure); for (let i = 0, l = keys.length; i < l; i++) { - let key = keys[i]; + const key = keys[i]; output[key] = SerializedObject.jsonify_structure(structure[key], key); } } @@ -297,7 +297,7 @@ SerializedObject.prototype.serialize = function(typedef, obj) { }; SerializedObject.prototype.hash = function(prefix) { - let sign_buffer = new SerializedObject(); + const sign_buffer = new SerializedObject(); // Add hashing prefix if (typeof prefix !== 'undefined') { @@ -310,7 +310,7 @@ SerializedObject.prototype.hash = function(prefix) { const bits = sjcl.codec.bytes.toBits(sign_buffer.buffer); const sha512hex = sjcl.codec.hex.fromBits(sjcl.hash.sha512.hash(bits)); - return UInt256.from_hex(sha512hex.substr(0, 64)); + return UInt256.from_hex(sha512hex.substr(0, 64).toUpperCase()); }; // DEPRECATED @@ -334,7 +334,7 @@ SerializedObject.prototype.serialize_field = function(spec, obj) { }; SerializedObject.get_field_header = function(type_id, field_id) { - let buffer = [0]; + const buffer = [0]; if (type_id > 0xF) { buffer.push(type_id & 0xFF); diff --git a/src/core/uint.js b/src/core/uint.js index 8dafd6d2..291c9954 100644 --- a/src/core/uint.js +++ b/src/core/uint.js @@ -2,8 +2,10 @@ /*eslint new-cap: 1*/ -var utils = require('./utils'); -var sjcl = utils.sjcl; +const assert = require('assert'); +const lodash = require('lodash'); +const utils = require('./utils'); +const sjcl = utils.sjcl; // // Abstract UInt class @@ -14,7 +16,6 @@ var sjcl = utils.sjcl; function UInt() { // Internal form: NaN or sjcl.bn this._value = NaN; - this._update(); } UInt.json_rewrite = function(j, opts) { @@ -26,6 +27,7 @@ UInt.from_generic = function(j) { if (j instanceof this) { return j.clone(); } + return (new this()).parse_generic(j); }; @@ -34,6 +36,7 @@ UInt.from_hex = function(j) { if (j instanceof this) { return j.clone(); } + return (new this()).parse_hex(j); }; @@ -42,6 +45,7 @@ UInt.from_json = function(j) { if (j instanceof this) { return j.clone(); } + return (new this()).parse_json(j); }; @@ -50,6 +54,7 @@ UInt.from_bits = function(j) { if (j instanceof this) { return j.clone(); } + return (new this()).parse_bits(j); }; @@ -58,6 +63,7 @@ UInt.from_bytes = function(j) { if (j instanceof this) { return j.clone(); } + return (new this()).parse_bytes(j); }; @@ -66,6 +72,7 @@ UInt.from_bn = function(j) { if (j instanceof this) { return j.clone(); } + return (new this()).parse_bn(j); }; @@ -74,6 +81,7 @@ UInt.from_number = function(j) { if (j instanceof this) { return j.clone(); } + return (new this()).parse_number(j); }; @@ -130,34 +138,46 @@ UInt.prototype._update = function() { // value = NaN on error. UInt.prototype.parse_generic = function(j) { + const subclass = this.constructor; + + assert(typeof subclass.width === 'number', 'UInt missing width'); + + this._value = NaN; + switch (j) { case undefined: case '0': - case this.constructor.STR_ZERO: - case this.constructor.ACCOUNT_ZERO: - case this.constructor.HEX_ZERO: + case subclass.STR_ZERO: + case subclass.ACCOUNT_ZERO: + case subclass.HEX_ZERO: this._value = new sjcl.bn(0); break; case '1': - case this.constructor.STR_ONE: - case this.constructor.ACCOUNT_ONE: - case this.constructor.HEX_ONE: + case subclass.STR_ONE: + case subclass.ACCOUNT_ONE: + case subclass.HEX_ONE: this._value = new sjcl.bn(1); break; default: - if (typeof j !== 'string') { - this._value = NaN; - } else if (this.constructor.width === j.length) { - var hex = utils.arrayToHex(utils.stringToArray(j)); - this._value = new sjcl.bn(hex, 16); - } else if ((this.constructor.width * 2) === j.length) { - // XXX Check char set! - this._value = new sjcl.bn(j, 16); - } else { - this._value = NaN; + if (lodash.isString(j)) { + switch (j.length) { + case subclass.width: + const hex = utils.arrayToHex(utils.stringToArray(j)); + this._value = new sjcl.bn(hex, 16); + break; + case subclass.width * 2: + // Assume hex, check char set + this.parse_hex(j); + break; } + } else if (lodash.isNumber(j)) { + this.parse_number(j); + } else if (lodash.isArray(j)) { + // Assume bytes array + this.parse_bytes(j); + } } this._update(); @@ -166,7 +186,7 @@ UInt.prototype.parse_generic = function(j) { }; UInt.prototype.parse_hex = function(j) { - if (typeof j === 'string' && j.length === (this.constructor.width * 2)) { + if (new RegExp(`^[0-9A-Fa-f]{${this.constructor.width * 2}}$`).test(j)) { this._value = new sjcl.bn(j, 16); } else { this._value = NaN; @@ -178,12 +198,12 @@ UInt.prototype.parse_hex = function(j) { }; UInt.prototype.parse_bits = function(j) { - if (sjcl.bitArray.bitLength(j) !== this.constructor.width * 8) { - this._value = NaN; - } else { + if (sjcl.bitArray.bitLength(j) === this.constructor.width * 8) { this._value = sjcl.bn.fromBits(j); - // var bytes = sjcl.codec.bytes.fromBits(j); + // let bytes = sjcl.codec.bytes.fromBits(j); // this.parse_bytes(bytes); + } else { + this._value = NaN; } this._update(); @@ -193,11 +213,11 @@ UInt.prototype.parse_bits = function(j) { UInt.prototype.parse_bytes = function(j) { - if (!Array.isArray(j) || j.length !== this.constructor.width) { - this._value = NaN; - } else { - var bits = sjcl.codec.bytes.toBits(j); + if (Array.isArray(j) && j.length === this.constructor.width) { + const bits = sjcl.codec.bytes.toBits(j); this._value = sjcl.bn.fromBits(bits); + } else { + this._value = NaN; } this._update(); @@ -209,8 +229,7 @@ UInt.prototype.parse_bytes = function(j) { UInt.prototype.parse_json = UInt.prototype.parse_hex; UInt.prototype.parse_bn = function(j) { - if ((j instanceof sjcl.bn) && - j.bitLength() <= this.constructor.width * 8) { + if ((j instanceof sjcl.bn) && j.bitLength() <= this.constructor.width * 8) { this._value = new sjcl.bn(j); } else { this._value = NaN; @@ -238,6 +257,7 @@ UInt.prototype.to_bytes = function() { if (!this.is_valid()) { return null; } + return sjcl.codec.bytes.fromBits(this.to_bits()); }; @@ -245,6 +265,7 @@ UInt.prototype.to_hex = function() { if (!this.is_valid()) { return null; } + return sjcl.codec.hex.fromBits(this.to_bits()).toUpperCase(); }; @@ -263,7 +284,7 @@ UInt.prototype.to_bn = function() { return null; } - var bits = this.to_bits(); + const bits = this.to_bits(); return sjcl.bn.fromBits(bits); }; diff --git a/test/fixtures/uint.json b/test/fixtures/uint.json new file mode 100644 index 00000000..24010c40 --- /dev/null +++ b/test/fixtures/uint.json @@ -0,0 +1,1675 @@ +{ + "UInt128": { + "from_json().to_json()": [ + { + "input": "00000000000000000000000000000000", + "expected": "00000000000000000000000000000000" + }, + { + "input": "00000000000000000000000000000001", + "expected": "00000000000000000000000000000001" + }, + { + "input": "01", + "expected": null + }, + { + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "input": "A2A66C43AA2A0CB7F82D41D63A5746E7", + "expected": "A2A66C43AA2A0CB7F82D41D63A5746E7" + }, + { + "input": "ffffffffffffffffffffffffffffffff", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "expected": null + }, + { + "input": 0, + "expected": null + } + ], + "from_json().to_bytes()": [ + { + "input": "00000000000000000000000000000000", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "input": "00000000000000000000000000000001", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "input": "01", + "expected": null + }, + { + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "input": "E1E5D55926E17089C1EBAED2F8698F79", + "expected": [ + 225, + 229, + 213, + 89, + 38, + 225, + 112, + 137, + 193, + 235, + 174, + 210, + 248, + 105, + 143, + 121 + ] + }, + { + "input": "ffffffffffffffffffffffffffffffff", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "input": 0, + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_number().to_json()": [ + { + "input": 0, + "expected": "00000000000000000000000000000000" + }, + { + "input": 1, + "expected": "00000000000000000000000000000001" + }, + { + "input": 4294967295, + "expected": "000000000000000000000000FFFFFFFF" + }, + { + "input": -1, + "expected": null + }, + { + "input": "0", + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_number().to_hex()": [ + { + "input": 0, + "expected": "00000000000000000000000000000000" + }, + { + "input": 1, + "expected": "00000000000000000000000000000001" + }, + { + "input": 4294967295, + "expected": "000000000000000000000000FFFFFFFF" + }, + { + "input": -1, + "expected": null + }, + { + "input": "0", + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_generic().to_*()": [ + { + "outputMethod": "to_json", + "input": "00000000000000000000000000000000", + "expected": "00000000000000000000000000000000" + }, + { + "outputMethod": "to_json", + "input": "00000000000000000000000000000001", + "expected": "00000000000000000000000000000001" + }, + { + "outputMethod": "to_json", + "input": "01", + "expected": null + }, + { + "outputMethod": "to_json", + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": "A2A66C43AA2A0CB7F82D41D63A5746E7", + "expected": "A2A66C43AA2A0CB7F82D41D63A5746E7" + }, + { + "outputMethod": "to_json", + "input": "ffffffffffffffffffffffffffffffff", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "outputMethod": "to_json", + "expected": null + }, + { + "outputMethod": "to_json", + "input": 0, + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": "00000000000000000000000000000000", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "outputMethod": "to_bytes", + "input": "00000000000000000000000000000001", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "outputMethod": "to_bytes", + "input": "01", + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "outputMethod": "to_bytes", + "input": "E1E5D55926E17089C1EBAED2F8698F79", + "expected": [ + 225, + 229, + 213, + 89, + 38, + 225, + 112, + 137, + 193, + 235, + 174, + 210, + 248, + 105, + 143, + 121 + ] + }, + { + "outputMethod": "to_bytes", + "input": "ffffffffffffffffffffffffffffffff", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "outputMethod": "to_bytes", + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": 0, + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": null, + "expected": null + }, + { + "outputMethod": "to_bytes", + "expected": null + }, + { + "outputMethod": "to_json", + "input": 0, + "expected": "00000000000000000000000000000000" + }, + { + "outputMethod": "to_json", + "input": 1, + "expected": "00000000000000000000000000000001" + }, + { + "outputMethod": "to_json", + "input": 4294967295, + "expected": "000000000000000000000000FFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": -1, + "expected": null + }, + { + "outputMethod": "to_json", + "input": "0", + "expected": null + }, + { + "outputMethod": "to_json", + "input": null, + "expected": null + }, + { + "outputMethod": "to_json", + "expected": null + }, + { + "outputMethod": "to_hex", + "input": 0, + "expected": "00000000000000000000000000000000" + }, + { + "outputMethod": "to_hex", + "input": 1, + "expected": "00000000000000000000000000000001" + }, + { + "outputMethod": "to_hex", + "input": 4294967295, + "expected": "000000000000000000000000FFFFFFFF" + }, + { + "outputMethod": "to_hex", + "input": -1, + "expected": null + }, + { + "outputMethod": "to_hex", + "input": "0", + "expected": null + }, + { + "outputMethod": "to_hex", + "input": null, + "expected": null + }, + { + "outputMethod": "to_hex", + "expected": null + } + ] + }, + "UInt256": { + "from_json().to_json()": [ + { + "input": "0000000000000000000000000000000000000000000000000000000000000000", + "expected": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "input": "0000000000000000000000000000000000000000000000000000000000000001", + "expected": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "input": "01", + "expected": null + }, + { + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "input": "A73C7FEE9216BD5201A3EAD1A9412D3FC1E5E9FA6ACFDDF679CB32EE056B1C79", + "expected": "A73C7FEE9216BD5201A3EAD1A9412D3FC1E5E9FA6ACFDDF679CB32EE056B1C79" + }, + { + "input": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + }, + { + "input": 0, + "expected": null + } + ], + "from_json().to_bytes()": [ + { + "input": "0000000000000000000000000000000000000000000000000000000000000000", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "input": "0000000000000000000000000000000000000000000000000000000000000001", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "input": "01", + "expected": null + }, + { + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "input": "2A7C44CFE813E367923451B8F5BE0E70C97C42DD6B088B2AD62E3E5FA73BF934", + "expected": [ + 42, + 124, + 68, + 207, + 232, + 19, + 227, + 103, + 146, + 52, + 81, + 184, + 245, + 190, + 14, + 112, + 201, + 124, + 66, + 221, + 107, + 8, + 139, + 42, + 214, + 46, + 62, + 95, + 167, + 59, + 249, + 52 + ] + }, + { + "input": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "input": 0, + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_number().to_json()": [ + { + "input": 0, + "expected": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "input": 1, + "expected": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "input": 4294967295, + "expected": "00000000000000000000000000000000000000000000000000000000FFFFFFFF" + }, + { + "input": -1, + "expected": null + }, + { + "input": "0", + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_number().to_hex()": [ + { + "input": 0, + "expected": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "input": 1, + "expected": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "input": 4294967295, + "expected": "00000000000000000000000000000000000000000000000000000000FFFFFFFF" + }, + { + "input": -1, + "expected": null + }, + { + "input": "0", + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_generic().to_*()": [ + { + "outputMethod": "to_json", + "input": "0000000000000000000000000000000000000000000000000000000000000000", + "expected": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "outputMethod": "to_json", + "input": "0000000000000000000000000000000000000000000000000000000000000001", + "expected": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "outputMethod": "to_json", + "input": "01", + "expected": null + }, + { + "outputMethod": "to_json", + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": "A73C7FEE9216BD5201A3EAD1A9412D3FC1E5E9FA6ACFDDF679CB32EE056B1C79", + "expected": "A73C7FEE9216BD5201A3EAD1A9412D3FC1E5E9FA6ACFDDF679CB32EE056B1C79" + }, + { + "outputMethod": "to_json", + "input": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "outputMethod": "to_json", + "input": null, + "expected": null + }, + { + "outputMethod": "to_json", + "expected": null + }, + { + "outputMethod": "to_json", + "input": 0, + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": "0000000000000000000000000000000000000000000000000000000000000000", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "outputMethod": "to_bytes", + "input": "0000000000000000000000000000000000000000000000000000000000000001", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "outputMethod": "to_bytes", + "input": "01", + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "outputMethod": "to_bytes", + "input": "2A7C44CFE813E367923451B8F5BE0E70C97C42DD6B088B2AD62E3E5FA73BF934", + "expected": [ + 42, + 124, + 68, + 207, + 232, + 19, + 227, + 103, + 146, + 52, + 81, + 184, + 245, + 190, + 14, + 112, + 201, + 124, + 66, + 221, + 107, + 8, + 139, + 42, + 214, + 46, + 62, + 95, + 167, + 59, + 249, + 52 + ] + }, + { + "outputMethod": "to_bytes", + "input": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "outputMethod": "to_bytes", + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": 0, + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": null, + "expected": null + }, + { + "outputMethod": "to_bytes", + "expected": null + }, + { + "outputMethod": "to_json", + "input": 0, + "expected": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "outputMethod": "to_json", + "input": 1, + "expected": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "outputMethod": "to_json", + "input": 4294967295, + "expected": "00000000000000000000000000000000000000000000000000000000FFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": -1, + "expected": null + }, + { + "outputMethod": "to_json", + "input": "0", + "expected": null + }, + { + "outputMethod": "to_json", + "input": null, + "expected": null + }, + { + "outputMethod": "to_json", + "expected": null + }, + { + "outputMethod": "to_hex", + "input": 0, + "expected": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "outputMethod": "to_hex", + "input": 1, + "expected": "0000000000000000000000000000000000000000000000000000000000000001" + }, + { + "outputMethod": "to_hex", + "input": 4294967295, + "expected": "00000000000000000000000000000000000000000000000000000000FFFFFFFF" + }, + { + "outputMethod": "to_hex", + "input": -1, + "expected": null + }, + { + "outputMethod": "to_hex", + "input": "0", + "expected": null + }, + { + "outputMethod": "to_hex", + "input": null, + "expected": null + }, + { + "outputMethod": "to_hex", + "expected": null + } + ] + }, + "UInt160": { + "from_json().to_json()": [ + { + "input": "0000000000000000000000000000000000000000", + "expected": "0000000000000000000000000000000000000000" + }, + { + "input": "0000000000000000000000000000000000000001", + "expected": "0000000000000000000000000000000000000001" + }, + { + "input": "01", + "expected": "null" + }, + { + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "input": "1F7555E865C5B1E33D6AA02836B16A2433A0D430", + "expected": "1F7555E865C5B1E33D6AA02836B16A2433A0D430" + }, + { + "input": "ffffffffffffffffffffffffffffffffffffffff", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": "null" + }, + { + "input": null, + "expected": "null" + }, + { + "expected": "null" + }, + { + "input": 0, + "expected": "rrrrrrrrrrrrrrrrrrrrrhoLvTp" + } + ], + "from_json().to_bytes()": [ + { + "input": "0000000000000000000000000000000000000000", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "input": "0000000000000000000000000000000000000001", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "input": "01", + "expected": null + }, + { + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "input": "9311AE068894B74095A865AB8F9E52A7534B522D", + "expected": [ + 147, + 17, + 174, + 6, + 136, + 148, + 183, + 64, + 149, + 168, + 101, + 171, + 143, + 158, + 82, + 167, + 83, + 75, + 82, + 45 + ] + }, + { + "input": "ffffffffffffffffffffffffffffffffffffffff", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "input": 0, + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_number().to_json()": [ + { + "input": 0, + "expected": "0000000000000000000000000000000000000000" + }, + { + "input": 1, + "expected": "0000000000000000000000000000000000000001" + }, + { + "input": 4294967295, + "expected": "00000000000000000000000000000000FFFFFFFF" + }, + { + "input": -1, + "expected": "null" + }, + { + "input": "0", + "expected": "null" + }, + { + "input": null, + "expected": "null" + }, + { + "expected": "null" + } + ], + "from_number().to_hex()": [ + { + "input": 0, + "expected": "0000000000000000000000000000000000000000" + }, + { + "input": 1, + "expected": "0000000000000000000000000000000000000001" + }, + { + "input": 4294967295, + "expected": "00000000000000000000000000000000FFFFFFFF" + }, + { + "input": -1, + "expected": null + }, + { + "input": "0", + "expected": null + }, + { + "input": null, + "expected": null + }, + { + "expected": null + } + ], + "from_generic().to_*()": [ + { + "outputMethod": "to_json", + "input": "0000000000000000000000000000000000000000", + "expected": "0000000000000000000000000000000000000000" + }, + { + "outputMethod": "to_json", + "input": "0000000000000000000000000000000000000001", + "expected": "0000000000000000000000000000000000000001" + }, + { + "outputMethod": "to_json", + "input": "01", + "expected": "null" + }, + { + "outputMethod": "to_json", + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": "1F7555E865C5B1E33D6AA02836B16A2433A0D430", + "expected": "1F7555E865C5B1E33D6AA02836B16A2433A0D430" + }, + { + "outputMethod": "to_json", + "input": "ffffffffffffffffffffffffffffffffffffffff", + "expected": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": "null" + }, + { + "outputMethod": "to_json", + "input": null, + "expected": "null" + }, + { + "outputMethod": "to_json", + "expected": "null" + }, + { + "outputMethod": "to_json", + "input": 0, + "expected": "rrrrrrrrrrrrrrrrrrrrrhoLvTp" + }, + { + "outputMethod": "to_bytes", + "input": "0000000000000000000000000000000000000000", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "outputMethod": "to_bytes", + "input": "0000000000000000000000000000000000000001", + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "outputMethod": "to_bytes", + "input": "01", + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "outputMethod": "to_bytes", + "input": "9311AE068894B74095A865AB8F9E52A7534B522D", + "expected": [ + 147, + 17, + 174, + 6, + 136, + 148, + 183, + 64, + 149, + 168, + 101, + 171, + 143, + 158, + 82, + 167, + 83, + 75, + 82, + 45 + ] + }, + { + "outputMethod": "to_bytes", + "input": "ffffffffffffffffffffffffffffffffffffffff", + "expected": [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255 + ] + }, + { + "outputMethod": "to_bytes", + "input": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "expected": null + }, + { + "outputMethod": "to_bytes", + "input": 0, + "expected": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "outputMethod": "to_bytes", + "input": null, + "expected": null + }, + { + "outputMethod": "to_bytes", + "expected": null + }, + { + "outputMethod": "to_json", + "input": 0, + "expected": "0000000000000000000000000000000000000000" + }, + { + "outputMethod": "to_json", + "input": 1, + "expected": "0000000000000000000000000000000000000001" + }, + { + "outputMethod": "to_json", + "input": 4294967295, + "expected": "00000000000000000000000000000000FFFFFFFF" + }, + { + "outputMethod": "to_json", + "input": -1, + "expected": "null" + }, + { + "outputMethod": "to_json", + "input": "0", + "expected": "null" + }, + { + "outputMethod": "to_json", + "input": null, + "expected": "null" + }, + { + "outputMethod": "to_json", + "expected": "null" + }, + { + "outputMethod": "to_hex", + "input": 0, + "expected": "0000000000000000000000000000000000000000" + }, + { + "outputMethod": "to_hex", + "input": 1, + "expected": "0000000000000000000000000000000000000001" + }, + { + "outputMethod": "to_hex", + "input": 4294967295, + "expected": "00000000000000000000000000000000FFFFFFFF" + }, + { + "outputMethod": "to_hex", + "input": -1, + "expected": null + }, + { + "outputMethod": "to_hex", + "input": "0", + "expected": null + }, + { + "outputMethod": "to_hex", + "input": null, + "expected": null + }, + { + "outputMethod": "to_hex", + "expected": null + } + ] + } +} \ No newline at end of file diff --git a/test/uint-test.js b/test/uint-test.js index 29026bf0..596aef3f 100644 --- a/test/uint-test.js +++ b/test/uint-test.js @@ -1,23 +1,104 @@ -var assert = require('assert'); -var UInt128 = require('ripple-lib').UInt128; +'use strict'; -describe('UInt', function() { - describe('128', function() { - describe('#parse_number', function () { - it('should create 00000000000000000000000000000000 when called with 0', function () { - var val = UInt128.from_number(0); - assert.strictEqual(val.to_hex(), '00000000000000000000000000000000'); +/* eslint-disable max-len */ + +const assert = require('assert-diff'); +const lodash = require('lodash'); +const ripple = require('ripple-lib'); +const fixtures = require('./fixtures/uint'); + +function resultError(test, result) { + function type(e) { + return Object.prototype.toString.call(e); + } + return `Expected ${type(test.input)}: ${test.input} to yield ${type(test.expected)}: ${test.expected === 'null' ? NaN : test.expected}. Actual: ${type(result)}: ${result}`; +} + +function makeTests(uIntType) { + describe(uIntType, function() { + const rippleType = ripple[uIntType]; + const tests = fixtures[uIntType]; + + it('from_json().to_json()', function() { + tests['from_json().to_json()'].forEach(function(test) { + let result = rippleType.from_json(test.input); + assert.strictEqual(result.is_valid(), String(test.expected) !== 'null', `Validity check failed: ${test.input}`); + result = result.to_json(); + + if (test.expected === 'null') { + // XXX + // UInt160.to_json() returns NaN rather than null if input is invalid + assert.strictEqual(lodash.isNaN(result), true, resultError(test, result)); + } else { + assert.strictEqual(result, test.expected, resultError(test, result)); + } }); - it('should create 00000000000000000000000000000001 when called with 1', function () { - var val = UInt128.from_number(1); - assert.strictEqual(val.to_hex(), '00000000000000000000000000000001'); + }); + it('from_json().to_bytes()', function() { + tests['from_json().to_bytes()'].forEach(function(test) { + const result = rippleType.from_json(test.input); + assert.strictEqual(result.is_valid(), String(test.expected) !== 'null', `Validity check failed: ${test.input}`); + assert.deepEqual(result.to_bytes(), test.expected, resultError(test, result)); }); - it('should create 000000000000000000000000FFFFFFFF when called with 0xFFFFFFFF', function () { - var val = UInt128.from_number(0xFFFFFFFF); - assert.strictEqual(val.to_hex(), '000000000000000000000000FFFFFFFF'); + }); + it('from_number().to_json()', function() { + tests['from_number().to_json()'].forEach(function(test) { + let result = rippleType.from_number(test.input); + assert.strictEqual(result.is_valid(), String(test.expected) !== 'null', `Validity check failed: ${test.input}`); + result = result.to_json(); + + if (test.expected === 'null') { + // XXX + // UInt160.to_json() returns NaN rather than null if input is invalid + assert.strictEqual(lodash.isNaN(result), true, resultError(test, result)); + } else { + assert.strictEqual(result, test.expected, resultError(test, result)); + } + }); + }); + it('from_number().to_hex()', function() { + tests['from_number().to_hex()'].forEach(function(test) { + const result = rippleType.from_number(test.input); + assert.strictEqual(result.is_valid(), String(test.expected) !== 'null', `Validity check failed: ${test.input}`); + assert.strictEqual(result.to_hex(), test.expected, resultError(test, result)); + }); + }); + it('from_generic().to_*()', function() { + tests['from_generic().to_*()'].forEach(function(test) { + let result = rippleType.from_generic(test.input); + + switch (test.input) { + // XXX + // from_generic() accepts these as "zero" + case 0: + case '0': + case undefined: + switch (test.outputMethod) { + case 'to_bytes': + test.expected = Array(rippleType.width).fill(0); + break; + case 'to_json': + case 'to_hex': + test.expected = Array(rippleType.width * 2).fill(0).join(''); + break; + } + } + + assert.strictEqual(result.is_valid(), String(test.expected) !== 'null', + `Validity check failed: ${test.input} > ${test.expected}`); + + result = result[test.outputMethod](); + + if (test.expected === 'null') { + // XXX + // UInt160.to_json() returns NaN rather than null if input is invalid + assert.strictEqual(lodash.isNaN(result), true, resultError(test, result)); + } else { + assert.deepEqual(result, test.expected, resultError(test, result)); + } }); }); }); -}); +} -// vim:sw=2:sts=2:ts=8:et +['UInt128', 'UInt160', 'UInt256'].forEach(makeTests);