From b100859a1e2ff1b89193c2cdbb484c199c56b591 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Tue, 6 Oct 2020 09:00:53 -0500 Subject: [PATCH] Limit magnitudes of From for PluralOperands to prevent overflow. (#293) --- components/pluralrules/src/operands.rs | 7 +++-- .../pluralrules/tests/fixtures/operands.json | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/components/pluralrules/src/operands.rs b/components/pluralrules/src/operands.rs index ea28c914729..389e2770be0 100644 --- a/components/pluralrules/src/operands.rs +++ b/components/pluralrules/src/operands.rs @@ -201,11 +201,12 @@ impl_integer_type!(u8 u16 u32 u64 u128 usize); impl_signed_integer_type!(i8 i16 i32 i64 i128 isize); impl From<&FixedDecimal> for PluralOperands { - /// Converts a [icu_num_util::FixedDecimal] to [PluralOperands] + /// Converts a [icu_num_util::FixedDecimal] to [PluralOperands]. Retains at most 18 + /// digits each from the integer and fraction parts. fn from(dec: &FixedDecimal) -> Self { let mag_range = dec.magnitude_range(); - let mag_high = *mag_range.end(); - let mag_low = *mag_range.start(); + let mag_high = std::cmp::min(17, *mag_range.end()); + let mag_low = std::cmp::max(-18, *mag_range.start()); let mut i: u64 = 0; for magnitude in (0..=mag_high).rev() { diff --git a/components/pluralrules/tests/fixtures/operands.json b/components/pluralrules/tests/fixtures/operands.json index a2c5feb31cd..a40cbf8fa81 100644 --- a/components/pluralrules/tests/fixtures/operands.json +++ b/components/pluralrules/tests/fixtures/operands.json @@ -215,6 +215,34 @@ "f": 0, "t": 0 } + }, + { + "input": { + "from": 9876543010, + "pow10": 10 + }, + "expected": { + "n": 765430100000000000, + "i": 765430100000000000, + "v": 0, + "w": 0, + "f": 0, + "t": 0 + } + }, + { + "input": { + "from": 9876543010, + "pow10": -20 + }, + "expected": { + "n": 0.000000000098765430, + "i": 0, + "v": 18, + "w": 17, + "f": 98765430, + "t": 9876543 + } } ] }