commit 7dbf4d319487cc38e65eea1c8dc9c21d4dec47f6
parent d9da83c7896ea682afdf6b5f01eeac12146f4792
Author: Christian Grothoff <grothoff@gnunet.org>
Date: Fri, 14 Aug 2026 23:30:01 +0200
check tip currency matches
Diffstat:
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c b/src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c
@@ -1807,10 +1807,16 @@ handle_phase_compute_price (struct UseContext *uc)
GNUNET_assert (0);
}
primary_currency = uc->template_contract.currency;
- if (! uc->parse_request.no_amount)
- primary_currency = uc->parse_request.amount.currency;
if (! uc->parse_request.no_tip)
primary_currency = uc->parse_request.tip.currency;
+ /* An 'amount' given by the client takes precedence over the currency
+ of the 'tip': the total we compute here is later compared against
+ that 'amount' in #handle_phase_check_total(), which requires both
+ to be in the same currency. If the tip then uses a different
+ currency, #handle_phase_check_tip() rejects the request with a
+ proper error instead. */
+ if (! uc->parse_request.no_amount)
+ primary_currency = uc->parse_request.amount.currency;
if (NULL == primary_currency)
{
ret = compute_totals_per_currency (uc);
@@ -1944,9 +1950,20 @@ handle_phase_check_total (struct UseContext *uc)
if (! uc->parse_request.no_amount)
{
GNUNET_assert (1 == uc->compute_price.totals_len);
- GNUNET_assert (GNUNET_YES ==
- TALER_amount_cmp_currency (&uc->parse_request.amount,
- &uc->compute_price.totals[0]));
+ if (GNUNET_YES !=
+ TALER_amount_cmp_currency (&uc->parse_request.amount,
+ &uc->compute_price.totals[0]))
+ {
+ /* Must not be an assertion: the currency of the total we computed
+ is influenced by the client (via 'tip' and the selected
+ products), so a mismatch here is remotely triggerable. */
+ GNUNET_break_op (0);
+ use_reply_with_error (uc,
+ MHD_HTTP_CONFLICT,
+ TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH,
+ uc->compute_price.totals[0].currency);
+ return;
+ }
if (0 !=
TALER_amount_cmp (&uc->parse_request.amount,
&uc->compute_price.totals[0]))