clean up amount logic, fix 2^53 check
This commit is contained in:
parent
1f5c814b73
commit
5da9cfc51c
@ -66,8 +66,8 @@ BANK_URL=http://localhost:${BANK_PORT}/
|
|||||||
AUDITOR_URL=http://localhost:8083/
|
AUDITOR_URL=http://localhost:8083/
|
||||||
|
|
||||||
# patch configuration
|
# patch configuration
|
||||||
taler-config -c $CONF -s EXCHANGE -o MASTER_PUBLIC_KEY -V $MASTER_PUB
|
taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB
|
||||||
taler-config -c $CONF -s EXCHANGE-DEFAULT -o MASTER_KEY -V $MASTER_PUB
|
taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB
|
||||||
taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||||
taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||||
taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||||
|
@ -61,13 +61,11 @@ int
|
|||||||
TALER_string_to_amount (const char *str,
|
TALER_string_to_amount (const char *str,
|
||||||
struct TALER_Amount *denom)
|
struct TALER_Amount *denom)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
int n;
|
int n;
|
||||||
uint32_t b;
|
uint32_t b;
|
||||||
const char *colon;
|
const char *colon;
|
||||||
const char *value;
|
const char *value;
|
||||||
|
|
||||||
invalidate (denom);
|
|
||||||
/* skip leading whitespace */
|
/* skip leading whitespace */
|
||||||
while (isspace ( (unsigned char) str[0]))
|
while (isspace ( (unsigned char) str[0]))
|
||||||
str++;
|
str++;
|
||||||
@ -75,8 +73,10 @@ TALER_string_to_amount (const char *str,
|
|||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Null before currency\n");
|
"Null before currency\n");
|
||||||
|
invalidate (denom);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse currency */
|
/* parse currency */
|
||||||
colon = strchr (str, (int) ':');
|
colon = strchr (str, (int) ':');
|
||||||
if ( (NULL == colon) ||
|
if ( (NULL == colon) ||
|
||||||
@ -85,91 +85,103 @@ TALER_string_to_amount (const char *str,
|
|||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Invalid currency specified before colon: `%s'\n",
|
"Invalid currency specified before colon: `%s'\n",
|
||||||
str);
|
str);
|
||||||
goto fail;
|
invalidate (denom);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GNUNET_assert (TALER_CURRENCY_LEN > (colon - str));
|
||||||
memcpy (denom->currency,
|
memcpy (denom->currency,
|
||||||
str,
|
str,
|
||||||
colon - str);
|
colon - str);
|
||||||
|
/* 0-terminate *and* normalize buffer by setting everything to '\0' */
|
||||||
|
memset (&denom->currency [colon - str],
|
||||||
|
0,
|
||||||
|
TALER_CURRENCY_LEN - (colon - str));
|
||||||
|
|
||||||
/* skip colon */
|
/* skip colon */
|
||||||
value = colon + 1;
|
value = colon + 1;
|
||||||
if ('\0' == value[0])
|
if ('\0' == value[0])
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Null before value\n");
|
"Actual value missing in amount `%s'\n",
|
||||||
goto fail;
|
str);
|
||||||
|
invalidate (denom);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
denom->value = 0;
|
||||||
|
denom->fraction = 0;
|
||||||
|
|
||||||
/* parse value */
|
/* parse value */
|
||||||
i = 0;
|
while ('.' != *value)
|
||||||
while ('.' != value[i])
|
|
||||||
{
|
{
|
||||||
if ('\0' == value[i])
|
if ('\0' == *value)
|
||||||
{
|
{
|
||||||
|
/* we are done */
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
if ( (value[i] < '0') || (value[i] > '9') )
|
if ( (*value < '0') ||
|
||||||
|
(*value > '9') )
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Invalid character `%c'\n",
|
"Invalid character `%c' in amount `%s'\n",
|
||||||
value[i]);
|
(int) *value,
|
||||||
goto fail;
|
str);
|
||||||
|
invalidate (denom);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
n = value[i] - '0';
|
n = *value - '0';
|
||||||
if (denom->value * 10 + n < denom->value)
|
if ( (denom->value * 10 + n < denom->value) ||
|
||||||
|
(denom->value > MAX_AMOUNT_VALUE) )
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Value too large\n");
|
"Value specified in amount `%s' is too large\n",
|
||||||
goto fail;
|
str);
|
||||||
|
invalidate (denom);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
denom->value = (denom->value * 10) + n;
|
denom->value = (denom->value * 10) + n;
|
||||||
i++;
|
value++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip the dot */
|
/* skip the dot */
|
||||||
i++;
|
value++;
|
||||||
|
|
||||||
/* parse fraction */
|
/* parse fraction */
|
||||||
if ('\0' == value[i])
|
if ('\0' == *value)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Null after dot\n");
|
"Amount `%s' ends abruptly after `.'\n",
|
||||||
goto fail;
|
str);
|
||||||
|
invalidate (denom);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
b = TALER_AMOUNT_FRAC_BASE / 10;
|
b = TALER_AMOUNT_FRAC_BASE / 10;
|
||||||
while ('\0' != value[i])
|
while ('\0' != *value)
|
||||||
{
|
{
|
||||||
if (0 == b)
|
if (0 == b)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Fractional value too small (only %u digits supported)\n",
|
"Fractional value too small (only %u digits supported) in amount `%s'\n",
|
||||||
(unsigned int) TALER_AMOUNT_FRAC_LEN);
|
(unsigned int) TALER_AMOUNT_FRAC_LEN,
|
||||||
goto fail;
|
str);
|
||||||
|
invalidate (denom);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
if ( (value[i] < '0') || (value[i] > '9') )
|
if ( (*value < '0') ||
|
||||||
|
(*value > '9') )
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Error after dot\n");
|
"Error after dot\n");
|
||||||
goto fail;
|
invalidate (denom);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
n = value[i] - '0';
|
n = *value - '0';
|
||||||
denom->fraction += n * b;
|
denom->fraction += n * b;
|
||||||
b /= 10;
|
b /= 10;
|
||||||
i++;
|
value++;
|
||||||
}
|
|
||||||
if (denom->value > MAX_AMOUNT_VALUE)
|
|
||||||
{
|
|
||||||
/* too large to be legal */
|
|
||||||
invalidate (denom);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
}
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
|
||||||
fail:
|
|
||||||
/* set currency to 'invalid' to prevent accidental use */
|
|
||||||
memset (denom->currency,
|
|
||||||
0,
|
|
||||||
TALER_CURRENCY_LEN);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user