diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-11-02 17:40:14 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-11-02 17:40:14 +0100 |
commit | 84998f9d052d49839a3bba75a91c3419acd87a86 (patch) | |
tree | 6de79fa2682edcbcc534ac80e820c9505ba0d1e3 /src | |
parent | 9236f3aaa085086f93f2b5987b737300e37fbd88 (diff) |
fix #5167
Diffstat (limited to 'src')
-rw-r--r-- | src/util/amount.c | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/src/util/amount.c b/src/util/amount.c index 33ba9a2f7..d52a32cf6 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -29,6 +29,25 @@ #endif #include <gcrypt.h> +/** + * Maximum legal 'value' for an amount, based on IEEE double (for JavaScript compatibility). + */ +#define MAX_AMOUNT_VALUE (1LLU << 53) + + +/** + * Set @a a to "invalid". + * + * @param a amount to set to invalid + */ +static void +invalidate (struct TALER_Amount *a) +{ + memset (a, + 0, + sizeof (struct TALER_Amount)); +} + /** * Parse money amount description, in the format "A:B.C". @@ -48,9 +67,7 @@ TALER_string_to_amount (const char *str, const char *colon; const char *value; - memset (denom, - 0, - sizeof (struct TALER_Amount)); + invalidate (denom); /* skip leading whitespace */ while (isspace( (unsigned char) str[0])) str++; @@ -139,6 +156,12 @@ TALER_string_to_amount (const char *str, b /= 10; i++; } + if (denom->value > MAX_AMOUNT_VALUE) + { + /* too large to be legal */ + invalidate (denom); + return GNUNET_SYSERR; + } return GNUNET_OK; fail: @@ -238,20 +261,6 @@ TALER_amount_get_zero (const char *cur, /** - * Set @a a to "invalid". - * - * @param a amount to set to invalid - */ -static void -invalidate (struct TALER_Amount *a) -{ - memset (a, - 0, - sizeof (struct TALER_Amount)); -} - - -/** * Test if the given amount is valid. * * @param amount amount to check @@ -472,6 +481,12 @@ TALER_amount_add (struct TALER_Amount *sum, invalidate (sum); return GNUNET_SYSERR; } + if (res.value > MAX_AMOUNT_VALUE) + { + /* too large to be legal */ + invalidate (sum); + return GNUNET_SYSERR; + } res.fraction = n1.fraction + n2.fraction; if (GNUNET_SYSERR == TALER_amount_normalize (&res)) |