mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 22:58:50 +01:00
Detect overflow or underflow on double config values.
Any floating point value too positive or negative to distinguish from +/-Inf, or too small to distinguish from +/-0, is an over/underflow.
This commit is contained in:
parent
9d60495903
commit
bfc5f09979
2 changed files with 23 additions and 2 deletions
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
//////
|
//////
|
||||||
// CONFIG_TYPE_STRING
|
// CONFIG_TYPE_STRING
|
||||||
|
@ -284,15 +285,23 @@ double_parse(void *target, const char *value, char **errmsg,
|
||||||
(void)errmsg;
|
(void)errmsg;
|
||||||
double *v = (double*)target;
|
double *v = (double*)target;
|
||||||
char *endptr=NULL;
|
char *endptr=NULL;
|
||||||
|
errno = 0;
|
||||||
*v = strtod(value, &endptr);
|
*v = strtod(value, &endptr);
|
||||||
if (endptr == value || *endptr != '\0') {
|
if (endptr == value || *endptr != '\0') {
|
||||||
// Either there are no converted characters, or there were some characters
|
// Either there are no converted characters, or there were some characters
|
||||||
// that didn't get converted.
|
// that didn't get converted.
|
||||||
tor_asprintf(errmsg, "Could not convert %s to a number.", escaped(value));
|
tor_asprintf(errmsg, "Could not convert %s to a number.", escaped(value));
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
if (errno == ERANGE) {
|
||||||
|
// strtod will set errno to ERANGE on underflow or overflow.
|
||||||
|
bool underflow = -.00001 < *v && *v < .00001;
|
||||||
|
tor_asprintf(errmsg,
|
||||||
|
"%s is too %s to express as a floating-point number.",
|
||||||
|
escaped(value), underflow ? "small" : "large");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
|
|
@ -490,6 +490,14 @@ static const badval_test_t bv_negint = { "pos -10\n", "out of bounds" };
|
||||||
static const badval_test_t bv_badu64 = { "u64 u64\n", "malformed" };
|
static const badval_test_t bv_badu64 = { "u64 u64\n", "malformed" };
|
||||||
static const badval_test_t bv_dbl1 = { "dbl xxx\n", "Could not convert" };
|
static const badval_test_t bv_dbl1 = { "dbl xxx\n", "Could not convert" };
|
||||||
static const badval_test_t bv_dbl2 = { "dbl 1.0 xx\n", "Could not convert" };
|
static const badval_test_t bv_dbl2 = { "dbl 1.0 xx\n", "Could not convert" };
|
||||||
|
static const badval_test_t bv_dbl3 = {
|
||||||
|
"dbl 1e-10000\n", "too small to express" };
|
||||||
|
static const badval_test_t bv_dbl4 = {
|
||||||
|
"dbl 1e1000\n", "too large to express" };
|
||||||
|
static const badval_test_t bv_dbl5 = {
|
||||||
|
"dbl -1e-10000\n", "too small to express" };
|
||||||
|
static const badval_test_t bv_dbl6 = {
|
||||||
|
"dbl -1e1000\n", "too large to express" };
|
||||||
static const badval_test_t bv_badcsvi1 =
|
static const badval_test_t bv_badcsvi1 =
|
||||||
{ "csv_interval 10 wl\n", "malformed" };
|
{ "csv_interval 10 wl\n", "malformed" };
|
||||||
static const badval_test_t bv_badcsvi2 =
|
static const badval_test_t bv_badcsvi2 =
|
||||||
|
@ -1049,6 +1057,10 @@ struct testcase_t confparse_tests[] = {
|
||||||
BADVAL_TEST(badu64),
|
BADVAL_TEST(badu64),
|
||||||
BADVAL_TEST(dbl1),
|
BADVAL_TEST(dbl1),
|
||||||
BADVAL_TEST(dbl2),
|
BADVAL_TEST(dbl2),
|
||||||
|
BADVAL_TEST(dbl3),
|
||||||
|
BADVAL_TEST(dbl4),
|
||||||
|
BADVAL_TEST(dbl5),
|
||||||
|
BADVAL_TEST(dbl6),
|
||||||
BADVAL_TEST(badcsvi1),
|
BADVAL_TEST(badcsvi1),
|
||||||
BADVAL_TEST(badcsvi2),
|
BADVAL_TEST(badcsvi2),
|
||||||
BADVAL_TEST(nonoption),
|
BADVAL_TEST(nonoption),
|
||||||
|
|
Loading…
Add table
Reference in a new issue