exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 07925374e5445f61febd3d597978654a8ac9a0bd
parent 050fb32d5336bc957e45cbfa3e4b66411a9a8062
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Fri, 14 Aug 2026 22:28:06 +0200

fix leaks and currency validation

Diffstat:
Msrc/util/amount.c | 38+++++++++++++++++++++++++++++---------
Msrc/util/config.c | 21++++-----------------
Msrc/util/iban.c | 1+
3 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/src/util/amount.c b/src/util/amount.c @@ -115,9 +115,7 @@ TALER_string_to_amount (const char *str, if (GNUNET_OK != TALER_check_currency (amount->currency)) { - memset (&amount->currency[0], - 0, - colon - str); + invalidate (amount); return GNUNET_SYSERR; } /* skip colon */ @@ -619,11 +617,16 @@ TALER_amount_to_string (const struct TALER_Amount *amount) char *result; struct TALER_Amount norm; - if (GNUNET_YES != TALER_amount_is_valid (amount)) + if (GNUNET_YES != + TALER_amount_is_valid (amount)) return NULL; norm = *amount; - GNUNET_break (GNUNET_SYSERR != - TALER_amount_normalize (&norm)); + if (GNUNET_SYSERR == + TALER_amount_normalize (&norm)) + { + GNUNET_break (0); + return NULL; + } if (0 != norm.fraction) { char tail[TALER_AMOUNT_FRAC_LEN + 1]; @@ -655,11 +658,16 @@ TALER_amount2s (const struct TALER_Amount *amount) + TALER_CURRENCY_LEN + 3 + 24]; struct TALER_Amount norm; - if (GNUNET_YES != TALER_amount_is_valid (amount)) + if (GNUNET_YES != + TALER_amount_is_valid (amount)) return NULL; norm = *amount; - GNUNET_break (GNUNET_SYSERR != - TALER_amount_normalize (&norm)); + if (GNUNET_SYSERR == + TALER_amount_normalize (&norm)) + { + GNUNET_break (0); + return NULL; + } if (0 != norm.fraction) { char tail[TALER_AMOUNT_FRAC_LEN + 1]; @@ -777,7 +785,10 @@ TALER_amount_multiply (struct TALER_Amount *result, if (GNUNET_SYSERR == TALER_amount_normalize (&in)) + { + invalidate (result); return TALER_AAR_INVALID_NORMALIZATION_FAILED; + } GNUNET_memcpy (result->currency, amount->currency, TALER_CURRENCY_LEN); @@ -791,7 +802,10 @@ TALER_amount_multiply (struct TALER_Amount *result, } result->value = in.value * ((uint64_t) factor); if (in.value != result->value / factor) + { + invalidate (result); return TALER_AAR_INVALID_RESULT_OVERFLOW; + } { /* This multiplication cannot overflow since both inputs are 32-bit values */ uint64_t tmp = ((uint64_t) factor) * ((uint64_t) in.fraction); @@ -800,12 +814,18 @@ TALER_amount_multiply (struct TALER_Amount *result, res = tmp / TALER_AMOUNT_FRAC_BASE; /* check for overflow */ if (result->value + res < result->value) + { + invalidate (result); return TALER_AAR_INVALID_RESULT_OVERFLOW; + } result->value += res; result->fraction = tmp % TALER_AMOUNT_FRAC_BASE; } if (result->value > TALER_AMOUNT_MAX_VALUE) + { + invalidate (result); return TALER_AAR_INVALID_RESULT_OVERFLOW; + } /* This check should be redundant... */ GNUNET_assert (GNUNET_SYSERR != TALER_amount_normalize (result)); diff --git a/src/util/config.c b/src/util/config.c @@ -165,8 +165,6 @@ TALER_config_get_currency (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, char **currency) { - size_t slen; - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, @@ -178,27 +176,16 @@ TALER_config_get_currency (const struct GNUNET_CONFIGURATION_Handle *cfg, "CURRENCY"); return GNUNET_SYSERR; } - slen = strlen (*currency); - if (slen >= TALER_CURRENCY_LEN) + if (GNUNET_OK != + TALER_check_currency (*currency)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Currency `%s' longer than the allowed limit of %u characters.", - *currency, - (unsigned int) TALER_CURRENCY_LEN); + "Currency `%s' must only use characters from the A-Z range.", + *currency); GNUNET_free (*currency); *currency = NULL; return GNUNET_SYSERR; } - for (size_t i = 0; i<slen; i++) - if (! isalpha ((unsigned char) (*currency)[i])) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Currency `%s' must only use characters from the A-Z range.", - *currency); - GNUNET_free (*currency); - *currency = NULL; - return GNUNET_SYSERR; - } return GNUNET_OK; } diff --git a/src/util/iban.c b/src/util/iban.c @@ -270,6 +270,7 @@ TALER_iban_validate (const char *iban) (ibancpy[i] - 'A' + 10))) { GNUNET_break (0); + GNUNET_free (nbuf); return GNUNET_strdup ("internal invariant violation"); } j += 2;