diff --git a/CHANGELOG.md b/CHANGELOG.md index 26adc443..d4f9bde7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,9 +21,11 @@ and this project adheres to query ([#1170]). - @cosmjs/tendermint-rpc: Fix decoding validator updates due to slashing ([#1177]). +- @cosmjs/math: Check for negative values in `Decimal.fromAtomics` ([#1188]). [#1170]: https://github.com/cosmos/cosmjs/issues/1170 [#1177]: https://github.com/cosmos/cosmjs/issues/1177 +[#1188]: https://github.com/cosmos/cosmjs/pull/1188 ### Changed diff --git a/packages/math/src/decimal.spec.ts b/packages/math/src/decimal.spec.ts index 52b876f7..dcefcad3 100644 --- a/packages/math/src/decimal.spec.ts +++ b/packages/math/src/decimal.spec.ts @@ -31,6 +31,18 @@ describe("Decimal", () => { expect(Decimal.fromAtomics("44", 3).toString()).toEqual("0.044"); expect(Decimal.fromAtomics("44", 4).toString()).toEqual("0.0044"); }); + + it("throws for atomics that are not non-negative integers", () => { + expect(() => Decimal.fromAtomics("0xAA", 0)).toThrowError( + "Invalid string format. Only non-negative integers in decimal representation supported.", + ); + expect(() => Decimal.fromAtomics("", 0)).toThrowError( + "Invalid string format. Only non-negative integers in decimal representation supported.", + ); + expect(() => Decimal.fromAtomics("-1", 0)).toThrowError( + "Invalid string format. Only non-negative integers in decimal representation supported.", + ); + }); }); describe("fromUserInput", () => { diff --git a/packages/math/src/decimal.ts b/packages/math/src/decimal.ts index 91ec2cc1..6e23489c 100644 --- a/packages/math/src/decimal.ts +++ b/packages/math/src/decimal.ts @@ -24,7 +24,10 @@ export class Decimal { let whole: string; let fractional: string; - if (input.search(/\./) === -1) { + if (input === "") { + whole = "0"; + fractional = ""; + } else if (input.search(/\./) === -1) { // integer format, no separator whole = input; fractional = ""; @@ -107,6 +110,12 @@ export class Decimal { }; private constructor(atomics: string, fractionalDigits: number) { + if (!atomics.match(/^[0-9]+$/)) { + throw new Error( + "Invalid string format. Only non-negative integers in decimal representation supported.", + ); + } + this.data = { atomics: new BN(atomics), fractionalDigits: fractionalDigits,