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 33ba9a2f..d52a32cf 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)) | 
