Skip to content

Commit

Permalink
Fixed BigNumber string validation (#935).
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Jul 8, 2020
1 parent 4124a56 commit 7e56f3d
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 21 deletions.
2 changes: 1 addition & 1 deletion packages/bignumber/src.ts/bignumber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export class BigNumber implements Hexable {
if (value instanceof BigNumber) { return value; }

if (typeof(value) === "string") {
if (value.match(/-?0x[0-9a-f]+/i)) {
if (value.match(/^-?0x[0-9a-f]+$/i)) {
return new BigNumber(_constructorGuard, toHex(value));
}

Expand Down
13 changes: 13 additions & 0 deletions packages/testcases/ingest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use strict";

const fs = require("fs");
const { resolve } = require("path");

const { saveTests } = require("./lib/index");

function ingest(tag) {
const data = JSON.parse(fs.readFileSync(resolve(__dirname, "input", tag + ".json")).toString());
saveTests(tag, data);
}

ingest("bignumber")
187 changes: 187 additions & 0 deletions packages/testcases/input/bignumber.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
[
{
"testcase": "HexStrings - Zero; odd-length",
"value": "0x0",
"expectedValue": "0x00"
},
{
"testcase": "HexStrings - Zero; padded",
"value": "0x00",
"expectedValue": "0x00"
},
{
"testcase": "HexStrings - Negative Zero",
"value": "-0x00",
"expectedValue": "0x00"
},
{
"testcase": "HexStrings - One",
"value": "0x1",
"expectedValue": "0x01"
},
{
"testcase": "HexStrings - Negative One",
"value": "-0x1",
"expectedValue": "-0x01"
},
{
"testcase": "HexStrings - Over 32-bits",
"value": "0xdeadbeef1",
"expectedValue": "0x0deadbeef1"
},
{
"testcase": "HexStrings - Over 32-bits (negative)",
"value": "-0xdeadbeef1",
"expectedValue": "-0x0deadbeef1"
},
{
"testcase": "HexStrings - Over 53-bits",
"value": "0xfffffffffffffff",
"expectedValue": "0x0fffffffffffffff"
},
{
"testcase": "HexStrings - Over 53-bits (negative)",
"value": "-0xfffffffffffffff",
"expectedValue": "-0x0fffffffffffffff"
},
{
"testcase": "HexStrings - Over 64-bits",
"value": "0xdeadbeefdeadbeef1",
"expectedValue": "0x0deadbeefdeadbeef1"
},
{
"testcase": "HexStrings - Over 64-bits (negative)",
"value": "-0xdeadbeefdeadbeef1",
"expectedValue": "-0x0deadbeefdeadbeef1"
},
{
"testcase": "DecimalStrings - Zero",
"value": "0",
"expectedValue": "0x00"
},
{
"testcase": "DecimalStrings - One",
"value": "1",
"expectedValue": "0x01"
},
{
"testcase": "DecimalStrings - Negative One",
"value": "-1",
"expectedValue": "-0x01"
},
{
"testcase": "DecimalStrings - Life and such",
"value": "42",
"expectedValue": "0x2a"
},
{
"testcase": "DecimalStrings - Life and such (negative)",
"value": "-42",
"expectedValue": "-0x2a"
},
{
"testcase": "DecimalStrings - MAX_SAFE_INTEGER",
"value": "9007199254740991",
"expectedValue": "0x1fffffffffffff"
},
{
"testcase": "DecimalStrings - MAX_SAFE_INTEGER (negative)",
"value": "-9007199254740991",
"expectedValue": "-0x1fffffffffffff"
},
{
"testcase": "DecimalStrings - High value not on compact boundary",
"value": "9007199254740995",
"expectedValue": "0x20000000000003"
},
{
"testcase": "DecimalStrings - Low value not on compact boundary",
"value": "-9007199254740995",
"expectedValue": "-0x20000000000003"
},
{
"testcase": "Numbers - Zero",
"value": 0,
"expectedValue": "0x00"
},
{
"testcase": "Numbers - One",
"value": 1,
"expectedValue": "0x01"
},
{
"testcase": "Numbers - Negative One",
"value": -1,
"expectedValue": "-0x01"
},
{
"testcase": "Numbers - BigNumber Safe",
"value": 9007199254740990,
"expectedValue": "0x1ffffffffffffe"
},
{
"testcase": "Numbers - BigNumber Safe (negative)",
"value": -9007199254740990,
"expectedValue": "-0x1ffffffffffffe"
},
{
"testcase": "Invalid - Empty value",
"value": "0x",
"expectedValue": null
},
{
"testcase": "Invalid - The x of 0x0",
"value": "x",
"expectedValue": null
},
{
"testcase": "Invalid - Negative at the end",
"value": "0123-",
"expectedValue": null
},
{
"testcase": "Invalid - Negative in middle",
"value": "0123-456",
"expectedValue": null
},
{
"testcase": "Invalid - Double negative",
"value": "--123",
"expectedValue": null
},
{
"testcase": "Invalid - MAX_SAFE_INTEGER",
"value": 9007199254740991,
"expectedValue": null
},
{
"testcase": "Invalid - -MAX_SAFE_INTEGER",
"value": -9007199254740991,
"expectedValue": null
},
{
"testcase": "Invalid - Too high; safe value",
"value": 9007199254740996,
"expectedValue": null
},
{
"testcase": "Invalid - Too low; save value",
"value": -9007199254740996,
"expectedValue": null
},
{
"testcase": "Invalid - Random text",
"value": "hello world",
"expectedValue": null
},
{
"testcase": "Invalid - Bad hex character",
"value": "0x123g",
"expectedValue": null
},
{
"testcase": "Invalid - See #935",
"value": "0-0x1 whatever",
"expectedValue": null
}
]
6 changes: 6 additions & 0 deletions packages/testcases/src.ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import { randomBytes, randomHexString, randomNumber } from "./random";
export { randomBytes, randomHexString, randomNumber };

export module TestCase {
export type BigNumber = {
testcase: string;
value: string | number;
expectedValue: string;
};

export type HDWalletNode = {
path: string;
address: string;
Expand Down
Binary file added packages/testcases/testcases/bignumber.json.gz
Binary file not shown.
64 changes: 44 additions & 20 deletions packages/tests/src.ts/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,26 +441,6 @@ describe('Test Bytes32String coder', function() {
});
});

describe('Test BigNumber', function() {
it("computes absolute values", function() {
function testAbs(test: { expected: string, value: string }) {
let value = ethers.BigNumber.from(test.value);
let expected = ethers.BigNumber.from(test.expected);
assert.ok(value.abs().eq(expected), 'BigNumber.abs - ' + test.value);
}

[
{ value: "0x0", expected: "0x0" },
{ value: "-0x0", expected: "0x0" },
{ value: "0x5", expected: "0x5" },
{ value: "-0x5", expected: "0x5" },
{ value: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
{ value: "-0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
{ value: "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
{ value: "-0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
].forEach(testAbs);
});
});

function getHex(value: string): string {
return "0x" + Buffer.from(value).toString("hex");
Expand Down Expand Up @@ -537,3 +517,47 @@ describe("Test Signature Manipulation", function() {
});
});
});

describe("BigNumber", function() {
const tests: Array<TestCase.BigNumber> = loadTests("bignumber");
tests.forEach((test) => {
if (test.expectedValue == null) {
it(test.testcase, function() {
assert.throws(() => {
const value = ethers.BigNumber.from(test.value);
console.log("ERROR", value);
}, (error: Error) => {
return true;
});
});
} else {
it(test.testcase, function() {
const value = ethers.BigNumber.from(test.value);
assert.equal(value.toHexString(), test.expectedValue);

const value2 = ethers.BigNumber.from(value)
assert.equal(value2.toHexString(), test.expectedValue);
});
}
});

[
{ value: "0x0", expected: "0x0" },
{ value: "-0x0", expected: "0x0" },
{ value: "0x5", expected: "0x5" },
{ value: "-0x5", expected: "0x5" },
{ value: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
{ value: "-0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
{ value: "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
{ value: "-0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" },
].forEach((test) => {
it(`absolute value (${ test.value })`, function() {
const value = ethers.BigNumber.from(test.value);
const expected = ethers.BigNumber.from(test.expected);
assert.ok(value.abs().eq(expected));
});
});

// @TODO: Add more tests here

});

0 comments on commit 7e56f3d

Please sign in to comment.