From 6174a7ce5779d2fc1ab00ecaa866659c2c494fa2 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Sun, 8 Jun 2025 21:16:31 +1000 Subject: [PATCH] Validate commodity strings in input --- src/db.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/db.ts b/src/db.ts index 8924760..270554d 100644 --- a/src/db.ts +++ b/src/db.ts @@ -177,6 +177,26 @@ function parseFloatStrict(quantity: string): number { return parseFloat(quantity); } +function validateCommodity(commodity: string) { + // Validate that the commodity is correctly formed + const commodityParts = commodity.split(' '); + if (commodityParts.length > 2) { + throw new DeserialiseAmountError('Invalid commodity (more spaces than expected): ' + commodity); + } + if (commodityParts.length === 2) { + // Validate that the second part is a cost basis + if (commodityParts[1].startsWith('{{') && commodityParts[1].endsWith('}}')) { + const costBase = commodityParts[1].substring(2, commodityParts[1].length - 2); + parseFloatStrict(costBase); + } else if (commodityParts[1].startsWith('{') && commodityParts[1].endsWith('}')) { + const costBase = commodityParts[1].substring(1, commodityParts[1].length - 1); + parseFloatStrict(costBase); + } else { + throw new DeserialiseAmountError('Invalid cost base: ' + commodityParts[1]); + } + } +} + export function deserialiseAmount(amount: string): { quantity: number, commodity: string } { const factor = Math.pow(10, db.metadata.dps); @@ -206,6 +226,7 @@ export function deserialiseAmount(amount: string): { quantity: number, commodity } if (!Number.isSafeInteger(quantity)) { throw new DeserialiseAmountError('Quantity not representable by safe integer: ' + amount); } + validateCommodity(commodity); return { 'quantity': quantity, @@ -232,6 +253,7 @@ export function deserialiseAmount(amount: string): { quantity: number, commodity if (!Number.isSafeInteger(quantity)) { throw new DeserialiseAmountError('Quantity not representable by safe integer: ' + amount); } const commodity = amount.substring(amount.indexOf(' ') + 1); + validateCommodity(commodity); return { 'quantity': quantity,