fix: bound money conversion after cents scaling
This commit is contained in:
+10
-7
@@ -7,8 +7,9 @@
|
||||
export type IskLike = string | bigint | number;
|
||||
|
||||
const INTEGER_TEXT = /^-?\d+$/;
|
||||
// The final lookahead makes the end assertion strict: JavaScript's `$` alone
|
||||
// would also accept a match immediately before one trailing newline.
|
||||
// The final lookahead makes the end assertion strict. This intentionally
|
||||
// tightens the old ESI regex, because JavaScript's `$` alone also accepts a
|
||||
// match immediately before one trailing newline.
|
||||
const DECIMAL_TEXT = /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$(?![\s\S])/;
|
||||
|
||||
/** Resource bounds for signed decimal ingestion. These reject excess input; no truncation is performed. */
|
||||
@@ -68,18 +69,20 @@ export function decimalIskToCents(value: string): string {
|
||||
}
|
||||
|
||||
const exponent = exponentText === undefined ? 0n : parseDecimalExponent(exponentText);
|
||||
const decimalPlaces = BigInt(fraction.length) - exponent;
|
||||
if (decimalPlaces < -MAX_DECIMAL_SHIFT || decimalPlaces > MAX_DECIMAL_SHIFT) {
|
||||
// Convert the decimal coefficient to cents before applying the resource
|
||||
// bound: value * 10^(exponent - fractionDigits) * 100.
|
||||
const centsShift = exponent + 2n - BigInt(fraction.length);
|
||||
if (centsShift < -MAX_DECIMAL_SHIFT || centsShift > MAX_DECIMAL_SHIFT) {
|
||||
throw new RangeError('ISK decimal shift exceeds resource bounds');
|
||||
}
|
||||
|
||||
const digits = `${whole}${fraction}`.replace(/^0+(?=\d)/, '');
|
||||
const significand = BigInt(digits);
|
||||
let magnitude: bigint;
|
||||
if (decimalPlaces <= 2n) {
|
||||
magnitude = significand * 10n ** (2n - decimalPlaces);
|
||||
if (centsShift >= 0n) {
|
||||
magnitude = significand * 10n ** centsShift;
|
||||
} else {
|
||||
const divisor = 10n ** (decimalPlaces - 2n);
|
||||
const divisor = 10n ** -centsShift;
|
||||
const quotient = significand / divisor;
|
||||
const remainder = significand % divisor;
|
||||
// Half-away-from-zero is half-up for this non-negative magnitude.
|
||||
|
||||
Reference in New Issue
Block a user