diff options
Diffstat (limited to 'src/util/amount.c')
-rw-r--r-- | src/util/amount.c | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/src/util/amount.c b/src/util/amount.c index 43116af85..cce84d73a 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -40,6 +40,31 @@ invalidate (struct TALER_Amount *a) enum GNUNET_GenericReturnValue +TALER_check_currency (const char *str) +{ + if (strlen (str) >= TALER_CURRENCY_LEN) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Currency code name `%s' is too long\n", + str); + return GNUNET_SYSERR; + } + /* validate str has only legal characters in it! */ + for (unsigned int i = 0; '\0' != str[i]; i++) + { + if ( ('A' > str[i]) || ('Z' < str[i]) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Currency code name `%s' contains illegal characters (only A-Z allowed)\n", + str); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + +enum GNUNET_GenericReturnValue TALER_string_to_amount (const char *str, struct TALER_Amount *amount) { @@ -62,6 +87,7 @@ TALER_string_to_amount (const char *str, /* parse currency */ colon = strchr (str, (int) ':'); if ( (NULL == colon) || + (colon == str) || ((colon - str) >= TALER_CURRENCY_LEN) ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -72,14 +98,15 @@ TALER_string_to_amount (const char *str, } GNUNET_assert (TALER_CURRENCY_LEN > (colon - str)); - memcpy (amount->currency, - str, - colon - str); + for (unsigned int i = 0; i<colon - str; i++) + amount->currency[i] = str[i]; /* 0-terminate *and* normalize buffer by setting everything to '\0' */ memset (&amount->currency [colon - str], 0, TALER_CURRENCY_LEN - (colon - str)); - + if (GNUNET_OK != + TALER_check_currency (amount->currency)) + return GNUNET_SYSERR; /* skip colon */ value = colon + 1; if ('\0' == value[0]) @@ -193,9 +220,8 @@ TALER_amount_hton (struct TALER_AmountNBO *res, TALER_amount_is_valid (d)); res->value = GNUNET_htonll (d->value); res->fraction = htonl (d->fraction); - memcpy (res->currency, - d->currency, - TALER_CURRENCY_LEN); + for (unsigned int i = 0; i<TALER_CURRENCY_LEN; i++) + res->currency[i] = d->currency[i]; } @@ -205,9 +231,9 @@ TALER_amount_ntoh (struct TALER_Amount *res, { res->value = GNUNET_ntohll (dn->value); res->fraction = ntohl (dn->fraction); - memcpy (res->currency, - dn->currency, - TALER_CURRENCY_LEN); + GNUNET_memcpy (res->currency, + dn->currency, + TALER_CURRENCY_LEN); GNUNET_assert (GNUNET_YES == TALER_amount_is_valid (res)); } @@ -219,15 +245,15 @@ TALER_amount_set_zero (const char *cur, { size_t slen; - slen = strlen (cur); - if (slen >= TALER_CURRENCY_LEN) + if (GNUNET_OK != + TALER_check_currency (cur)) return GNUNET_SYSERR; + slen = strlen (cur); memset (amount, 0, sizeof (struct TALER_Amount)); - memcpy (amount->currency, - cur, - slen); + for (unsigned int i = 0; i<slen; i++) + amount->currency[i] = cur[i]; return GNUNET_OK; } @@ -236,7 +262,10 @@ enum GNUNET_GenericReturnValue TALER_amount_is_valid (const struct TALER_Amount *amount) { if (amount->value > TALER_AMOUNT_MAX_VALUE) + { + GNUNET_break (0); return GNUNET_SYSERR; + } return ('\0' != amount->currency[0]) ? GNUNET_OK : GNUNET_NO; } @@ -553,8 +582,8 @@ const char * TALER_amount2s (const struct TALER_Amount *amount) { /* 24 is sufficient for a uint64_t value in decimal; 3 is for ":.\0" */ - static GNUNET_THREAD_LOCAL char result[TALER_AMOUNT_FRAC_LEN - + TALER_CURRENCY_LEN + 3 + 24]; + static TALER_THREAD_LOCAL char result[TALER_AMOUNT_FRAC_LEN + + TALER_CURRENCY_LEN + 3 + 24]; struct TALER_Amount norm; if (GNUNET_YES != TALER_amount_is_valid (amount)) @@ -680,9 +709,9 @@ TALER_amount_multiply (struct TALER_Amount *result, if (GNUNET_SYSERR == TALER_amount_normalize (&in)) return TALER_AAR_INVALID_NORMALIZATION_FAILED; - memcpy (result->currency, - amount->currency, - TALER_CURRENCY_LEN); + GNUNET_memcpy (result->currency, + amount->currency, + TALER_CURRENCY_LEN); if ( (0 == factor) || ( (0 == in.value) && (0 == in.fraction) ) ) |