From 722cd4ec5d7f7ba6d7cf8e0a0e09f95c622482b4 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 6 Jan 2026 18:07:31 -0500 Subject: [PATCH 1/7] add integer check --- packages/ripple-binary-codec/src/types/uint-16.ts | 2 +- packages/ripple-binary-codec/src/types/uint-32.ts | 2 +- packages/ripple-binary-codec/src/types/uint-64.ts | 2 +- packages/ripple-binary-codec/src/types/uint-8.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ripple-binary-codec/src/types/uint-16.ts b/packages/ripple-binary-codec/src/types/uint-16.ts index 5d680384e2..f7c7abfb74 100644 --- a/packages/ripple-binary-codec/src/types/uint-16.ts +++ b/packages/ripple-binary-codec/src/types/uint-16.ts @@ -29,7 +29,7 @@ class UInt16 extends UInt { return val } - if (typeof val === 'number') { + if (typeof val === 'number' && Number.isInteger(val)) { UInt16.checkUintRange(val, 0, 0xffff) const buf = new Uint8Array(UInt16.width) diff --git a/packages/ripple-binary-codec/src/types/uint-32.ts b/packages/ripple-binary-codec/src/types/uint-32.ts index abb5d8a987..e188ae910c 100644 --- a/packages/ripple-binary-codec/src/types/uint-32.ts +++ b/packages/ripple-binary-codec/src/types/uint-32.ts @@ -37,7 +37,7 @@ class UInt32 extends UInt { return new UInt32(buf) } - if (typeof val === 'number') { + if (typeof val === 'number' && Number.isInteger(val)) { UInt32.checkUintRange(val, 0, 0xffffffff) writeUInt32BE(buf, val, 0) return new UInt32(buf) diff --git a/packages/ripple-binary-codec/src/types/uint-64.ts b/packages/ripple-binary-codec/src/types/uint-64.ts index 4c6ccca90e..bb18e6775a 100644 --- a/packages/ripple-binary-codec/src/types/uint-64.ts +++ b/packages/ripple-binary-codec/src/types/uint-64.ts @@ -53,7 +53,7 @@ class UInt64 extends UInt { let buf = new Uint8Array(UInt64.width) - if (typeof val === 'number') { + if (typeof val === 'number' && Number.isInteger(val)) { if (val < 0) { throw new Error('value must be an unsigned integer') } diff --git a/packages/ripple-binary-codec/src/types/uint-8.ts b/packages/ripple-binary-codec/src/types/uint-8.ts index 50c4cff773..7d7ae9753f 100644 --- a/packages/ripple-binary-codec/src/types/uint-8.ts +++ b/packages/ripple-binary-codec/src/types/uint-8.ts @@ -28,7 +28,7 @@ class UInt8 extends UInt { return val } - if (typeof val === 'number') { + if (typeof val === 'number' && Number.isInteger(val)) { UInt8.checkUintRange(val, 0, 0xff) const buf = new Uint8Array(UInt8.width) From ce107d47970f669e88b1ded2ce7e17314141cddf Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 6 Jan 2026 18:09:55 -0500 Subject: [PATCH 2/7] fix test --- .../xrpl/test/integration/transactions/lendingProtocol.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xrpl/test/integration/transactions/lendingProtocol.test.ts b/packages/xrpl/test/integration/transactions/lendingProtocol.test.ts index b991bcb4a0..734aa8e167 100644 --- a/packages/xrpl/test/integration/transactions/lendingProtocol.test.ts +++ b/packages/xrpl/test/integration/transactions/lendingProtocol.test.ts @@ -186,7 +186,7 @@ describe('Lending Protocol IT', () => { Account: loanBrokerWallet.address, LoanBrokerID: loanBrokerObjectId, PrincipalRequested: '100000', - InterestRate: 0.1, + InterestRate: 0, Counterparty: borrowerWallet.address, PaymentTotal: 1, } From 878cbe821fabfc933f14f236b87cc05c82d866bf Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 6 Jan 2026 18:10:31 -0500 Subject: [PATCH 3/7] update changelog --- packages/ripple-binary-codec/HISTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/ripple-binary-codec/HISTORY.md b/packages/ripple-binary-codec/HISTORY.md index 6a1a7352aa..689b305e24 100644 --- a/packages/ripple-binary-codec/HISTORY.md +++ b/packages/ripple-binary-codec/HISTORY.md @@ -2,6 +2,9 @@ ## Unreleased +### Fixed +* Error if a decimal is passed into a `UInt`-typed field. + ## 2.6.0 (2025-12-16) ### Added From 522b00495c6003a2169450cd68108255a3e1240c Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 6 Jan 2026 18:27:27 -0500 Subject: [PATCH 4/7] add tests --- .../ripple-binary-codec/test/uint.test.ts | 108 +++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/packages/ripple-binary-codec/test/uint.test.ts b/packages/ripple-binary-codec/test/uint.test.ts index e3165fa1ed..d5256d3126 100644 --- a/packages/ripple-binary-codec/test/uint.test.ts +++ b/packages/ripple-binary-codec/test/uint.test.ts @@ -1,4 +1,4 @@ -import { UInt8, UInt64 } from '../src/types' +import { UInt8, UInt16, UInt32, UInt64 } from '../src/types' import { encode, decode } from '../src' const binary = @@ -195,3 +195,109 @@ it('UInt64 is parsed as base 10 for MPT amounts', () => { expect(typeof decodedToken.MPTAmount).toBe('string') expect(decodedToken.MPTAmount).toBe('100') }) + +describe('UInt decimal validation', () => { + describe('UInt8', () => { + it('should throw error when passed a decimal number', () => { + expect(() => UInt8.from(1.5)).toThrow( + 'Cannot construct UInt8 from given value', + ) + }) + + it('should throw error when passed a negative decimal', () => { + expect(() => UInt8.from(-1.5)).toThrow( + 'Cannot construct UInt8 from given value', + ) + }) + + it('should throw error when passed a small decimal', () => { + expect(() => UInt8.from(0.1)).toThrow( + 'Cannot construct UInt8 from given value', + ) + }) + + it('should accept valid integer values', () => { + expect(() => UInt8.from(0)).not.toThrow() + expect(() => UInt8.from(1)).not.toThrow() + expect(() => UInt8.from(255)).not.toThrow() + }) + }) + + describe('UInt16', () => { + it('should throw error when passed a decimal number', () => { + expect(() => UInt16.from(100.5)).toThrow( + 'Can not construct UInt16 with given value', + ) + }) + + it('should throw error when passed a negative decimal', () => { + expect(() => UInt16.from(-100.5)).toThrow( + 'Can not construct UInt16 with given value', + ) + }) + + it('should throw error when passed a small decimal', () => { + expect(() => UInt16.from(0.001)).toThrow( + 'Can not construct UInt16 with given value', + ) + }) + + it('should accept valid integer values', () => { + expect(() => UInt16.from(0)).not.toThrow() + expect(() => UInt16.from(1000)).not.toThrow() + expect(() => UInt16.from(65535)).not.toThrow() + }) + }) + + describe('UInt32', () => { + it('should throw error when passed a decimal number', () => { + expect(() => UInt32.from(1000.5)).toThrow( + 'Cannot construct UInt32 from given value', + ) + }) + + it('should throw error when passed a negative decimal', () => { + expect(() => UInt32.from(-1000.5)).toThrow( + 'Cannot construct UInt32 from given value', + ) + }) + + it('should throw error when passed a small decimal', () => { + expect(() => UInt32.from(0.0001)).toThrow( + 'Cannot construct UInt32 from given value', + ) + }) + + it('should accept valid integer values', () => { + expect(() => UInt32.from(0)).not.toThrow() + expect(() => UInt32.from(100000)).not.toThrow() + expect(() => UInt32.from(4294967295)).not.toThrow() + }) + }) + + describe('UInt64', () => { + it('should throw error when passed a decimal number', () => { + expect(() => UInt64.from(10000.5)).toThrow( + 'Cannot construct UInt64 from given value', + ) + }) + + it('should throw error when passed a negative decimal', () => { + expect(() => UInt64.from(-10000.5)).toThrow( + 'Cannot construct UInt64 from given value', + ) + }) + + it('should throw error when passed a small decimal', () => { + expect(() => UInt64.from(0.00001)).toThrow( + 'Cannot construct UInt64 from given value', + ) + }) + + it('should accept valid integer values', () => { + expect(() => UInt64.from(0)).not.toThrow() + expect(() => UInt64.from(1000000)).not.toThrow() + expect(() => UInt64.from(BigInt('9223372036854775807'))).not.toThrow() + }) + }) +}) From 01b5f03095c1b0a26e04ccb69694051587590d7b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 7 Jan 2026 11:21:16 -0500 Subject: [PATCH 5/7] fix browser tests --- .../ripple-binary-codec/test/uint.test.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/ripple-binary-codec/test/uint.test.ts b/packages/ripple-binary-codec/test/uint.test.ts index d5256d3126..69b2075b05 100644 --- a/packages/ripple-binary-codec/test/uint.test.ts +++ b/packages/ripple-binary-codec/test/uint.test.ts @@ -200,19 +200,19 @@ describe('UInt decimal validation', () => { describe('UInt8', () => { it('should throw error when passed a decimal number', () => { expect(() => UInt8.from(1.5)).toThrow( - 'Cannot construct UInt8 from given value', + new Error('Cannot construct UInt8 from given value'), ) }) it('should throw error when passed a negative decimal', () => { expect(() => UInt8.from(-1.5)).toThrow( - 'Cannot construct UInt8 from given value', + new Error('Cannot construct UInt8 from given value'), ) }) it('should throw error when passed a small decimal', () => { expect(() => UInt8.from(0.1)).toThrow( - 'Cannot construct UInt8 from given value', + new Error('Cannot construct UInt8 from given value'), ) }) @@ -226,19 +226,19 @@ describe('UInt decimal validation', () => { describe('UInt16', () => { it('should throw error when passed a decimal number', () => { expect(() => UInt16.from(100.5)).toThrow( - 'Can not construct UInt16 with given value', + new Error('Can not construct UInt16 with given value'), ) }) it('should throw error when passed a negative decimal', () => { expect(() => UInt16.from(-100.5)).toThrow( - 'Can not construct UInt16 with given value', + new Error('Can not construct UInt16 with given value'), ) }) it('should throw error when passed a small decimal', () => { expect(() => UInt16.from(0.001)).toThrow( - 'Can not construct UInt16 with given value', + new Error('Can not construct UInt16 with given value'), ) }) @@ -252,19 +252,19 @@ describe('UInt decimal validation', () => { describe('UInt32', () => { it('should throw error when passed a decimal number', () => { expect(() => UInt32.from(1000.5)).toThrow( - 'Cannot construct UInt32 from given value', + new Error('Cannot construct UInt32 from given value'), ) }) it('should throw error when passed a negative decimal', () => { expect(() => UInt32.from(-1000.5)).toThrow( - 'Cannot construct UInt32 from given value', + new Error('Cannot construct UInt32 from given value'), ) }) it('should throw error when passed a small decimal', () => { expect(() => UInt32.from(0.0001)).toThrow( - 'Cannot construct UInt32 from given value', + new Error('Cannot construct UInt32 from given value'), ) }) @@ -278,19 +278,19 @@ describe('UInt decimal validation', () => { describe('UInt64', () => { it('should throw error when passed a decimal number', () => { expect(() => UInt64.from(10000.5)).toThrow( - 'Cannot construct UInt64 from given value', + new Error('Cannot construct UInt64 from given value'), ) }) it('should throw error when passed a negative decimal', () => { expect(() => UInt64.from(-10000.5)).toThrow( - 'Cannot construct UInt64 from given value', + new Error('Cannot construct UInt64 from given value'), ) }) it('should throw error when passed a small decimal', () => { expect(() => UInt64.from(0.00001)).toThrow( - 'Cannot construct UInt64 from given value', + new Error('Cannot construct UInt64 from given value'), ) }) From 3576ce904b12dd4abc418ade76f001ee0dd5a0a2 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 7 Jan 2026 11:45:33 -0500 Subject: [PATCH 6/7] align error messages --- packages/ripple-binary-codec/src/types/uint-16.ts | 2 +- packages/ripple-binary-codec/test/uint.test.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ripple-binary-codec/src/types/uint-16.ts b/packages/ripple-binary-codec/src/types/uint-16.ts index f7c7abfb74..7db2946cc5 100644 --- a/packages/ripple-binary-codec/src/types/uint-16.ts +++ b/packages/ripple-binary-codec/src/types/uint-16.ts @@ -37,7 +37,7 @@ class UInt16 extends UInt { return new UInt16(buf) } - throw new Error('Can not construct UInt16 with given value') + throw new Error('Can not construct UInt16 from given value') } /** diff --git a/packages/ripple-binary-codec/test/uint.test.ts b/packages/ripple-binary-codec/test/uint.test.ts index 69b2075b05..78bc0f4308 100644 --- a/packages/ripple-binary-codec/test/uint.test.ts +++ b/packages/ripple-binary-codec/test/uint.test.ts @@ -226,19 +226,19 @@ describe('UInt decimal validation', () => { describe('UInt16', () => { it('should throw error when passed a decimal number', () => { expect(() => UInt16.from(100.5)).toThrow( - new Error('Can not construct UInt16 with given value'), + new Error('Can not construct UInt16 from given value'), ) }) it('should throw error when passed a negative decimal', () => { expect(() => UInt16.from(-100.5)).toThrow( - new Error('Can not construct UInt16 with given value'), + new Error('Can not construct UInt16 from given value'), ) }) it('should throw error when passed a small decimal', () => { expect(() => UInt16.from(0.001)).toThrow( - new Error('Can not construct UInt16 with given value'), + new Error('Can not construct UInt16 from given value'), ) }) From 56f013eb9f5035c2171c482df7eaab461371eff2 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 7 Jan 2026 11:53:39 -0500 Subject: [PATCH 7/7] more alignment --- packages/ripple-binary-codec/src/types/uint-16.ts | 2 +- packages/ripple-binary-codec/test/uint.test.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ripple-binary-codec/src/types/uint-16.ts b/packages/ripple-binary-codec/src/types/uint-16.ts index 7db2946cc5..a217333d5b 100644 --- a/packages/ripple-binary-codec/src/types/uint-16.ts +++ b/packages/ripple-binary-codec/src/types/uint-16.ts @@ -37,7 +37,7 @@ class UInt16 extends UInt { return new UInt16(buf) } - throw new Error('Can not construct UInt16 from given value') + throw new Error('Cannot construct UInt16 from given value') } /** diff --git a/packages/ripple-binary-codec/test/uint.test.ts b/packages/ripple-binary-codec/test/uint.test.ts index 78bc0f4308..c737344da8 100644 --- a/packages/ripple-binary-codec/test/uint.test.ts +++ b/packages/ripple-binary-codec/test/uint.test.ts @@ -226,19 +226,19 @@ describe('UInt decimal validation', () => { describe('UInt16', () => { it('should throw error when passed a decimal number', () => { expect(() => UInt16.from(100.5)).toThrow( - new Error('Can not construct UInt16 from given value'), + new Error('Cannot construct UInt16 from given value'), ) }) it('should throw error when passed a negative decimal', () => { expect(() => UInt16.from(-100.5)).toThrow( - new Error('Can not construct UInt16 from given value'), + new Error('Cannot construct UInt16 from given value'), ) }) it('should throw error when passed a small decimal', () => { expect(() => UInt16.from(0.001)).toThrow( - new Error('Can not construct UInt16 from given value'), + new Error('Cannot construct UInt16 from given value'), ) })