commit 8b447f66974602c4f86f23d6005f473bd9653e99
parent b07c3624b4efd8b759dac60254e357532a2edfa5
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 13 Oct 2026 00:09:53 +0200
handle extreme cases in amount_divide2
Diffstat:
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/src/util/amount.c b/src/util/amount.c
@@ -761,10 +761,15 @@ TALER_amount_divide2 (const struct TALER_Amount *dividend,
/* in practice, this loop will only run for one or two iterations */
while (1)
{
- GNUNET_assert (0 <=
- TALER_amount_add (&nxt,
- &tmp,
- divisor));
+ enum TALER_AmountArithmeticResult aar;
+
+ aar = TALER_amount_add (&nxt,
+ &tmp,
+ divisor);
+ if (TALER_AAR_INVALID_RESULT_OVERFLOW == aar)
+ break; /* nxt would exceed TALER_AMOUNT_MAX_VALUE, and thus
+ certainly the (presumed valid) dividend */
+ GNUNET_assert (0 <= aar);
if (1 ==
TALER_amount_cmp (&nxt,
dividend))
diff --git a/src/util/test_amount.c b/src/util/test_amount.c
@@ -506,6 +506,17 @@ main (int argc,
GNUNET_assert (999 ==
TALER_amount_divide2 (&r,
&a1));
+ /* division must not overflow when dividend + divisor
+ exceeds TALER_AMOUNT_MAX_VALUE */
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount ("BTC:4503599627370496",
+ &r));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount ("BTC:2251799813685248",
+ &a1));
+ GNUNET_assert (2 ==
+ TALER_amount_divide2 (&r,
+ &a1));
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("BTC:0",
&a1));