Merge rust-bitcoin/rust-bitcoin#2281: Allow `SignedAmount` parse values equal to `i64::MIN`

daa47b2061 Allow `SignedAmount` parse values equal to i64::MIN (Jiri Jakes)

Pull request description:

  Fixes #2267.

  Previously, parsing such textual value returned 'too big' error. This change fixes it and adds relevant tests. Without this patch, the newly added tests fail with `TooBig`.

ACKs for top commit:
  Kixunil:
    ACK daa47b2061
  apoelstra:
    ACK daa47b2061

Tree-SHA512: b6e4ee8ed3fa15ecb988b3a6f32f16a17ba9c6de0b99c8a198254d85d263cfffa0498487a3f47b7ddc2c976cade128ac6a7952baecc8721d5d45e057c0eb87b4
This commit is contained in:
Andrew Poelstra 2023-12-12 17:56:09 +00:00
commit 24bc6aaad2
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 9 additions and 7 deletions

View File

@ -938,14 +938,14 @@ impl SignedAmount {
/// Note: This only parses the value string. If you want to parse a value
/// with denomination, use [FromStr].
pub fn from_str_in(s: &str, denom: Denomination) -> Result<SignedAmount, ParseAmountError> {
let (negative, satoshi) = parse_signed_to_satoshi(s, denom)?;
if satoshi > i64::MAX as u64 {
return Err(ParseAmountError::TooBig);
match parse_signed_to_satoshi(s, denom)? {
// (negative, amount)
(false, sat) if sat > i64::MAX as u64 => Err(ParseAmountError::TooBig),
(false, sat) => Ok(SignedAmount(sat as i64)),
(true, sat) if sat == i64::MAX as u64 + 1 => Ok(SignedAmount(i64::MIN)),
(true, sat) if sat > i64::MAX as u64 + 1 => Err(ParseAmountError::TooBig),
(true, sat) => Ok(SignedAmount(-(sat as i64))),
}
Ok(match negative {
true => SignedAmount(-(satoshi as i64)),
false => SignedAmount(satoshi as i64),
})
}
/// Parses amounts with denomination suffix like they are produced with
@ -1762,6 +1762,7 @@ mod tests {
assert_eq!(p("1", btc), Ok(Amount::from_sat(1_000_000_00)));
assert_eq!(sp("-.5", btc), Ok(SignedAmount::from_sat(-500_000_00)));
assert_eq!(sp(&i64::MIN.to_string(), sat), Ok(SignedAmount::from_sat(i64::MIN)));
assert_eq!(p("1.1", btc), Ok(Amount::from_sat(1_100_000_00)));
assert_eq!(p("100", sat), Ok(Amount::from_sat(100)));
assert_eq!(p("55", sat), Ok(Amount::from_sat(55)));
@ -2067,6 +2068,7 @@ mod tests {
scase("-5 satoshi", Ok(SignedAmount::from_sat(-5)));
case("0.10000000 BTC", Ok(Amount::from_sat(100_000_00)));
scase("-100 bits", Ok(SignedAmount::from_sat(-10_000)));
scase(&format!("{} SAT", i64::MIN), Ok(SignedAmount::from_sat(i64::MIN)));
}
#[test]