Skip to content
Snippets Groups Projects
Commit 9b344628 authored by Nick Mathewson's avatar Nick Mathewson :game_die:
Browse files

Handle out-of-range values in tor_parse_* integer functions

The underlying strtoX functions handle overflow by saturating and
setting errno to ERANGE.  If the min/max arguments to the
tor_parse_* functions are equal to the minimum/maximum of the
underlying type, then with the old approach, we wouldn't treat a
too-large value as genuinely broken.

Found this while looking at bug 5786; bugfix on 19da1f36 (in Tor
0.0.9), which introduced these functions.
parent f6afd4ef
No related branches found
No related tags found
No related merge requests found
o Minor bugfixes:
- Make our number-parsing functions always treat too-large values
as an error, even when those values exceed the width of the
underlying type. Previously, if the caller provided these
functions with minima or maxima set to the extreme values of the
underlying integer type, these functions would return those
values on overflow rather than treating overflow as an error.
Fix for part of bug 5786; bugfix on Tor 0.0.9.
\ No newline at end of file
......@@ -764,6 +764,9 @@ tor_digest256_is_zero(const char *digest)
/* Helper: common code to check whether the result of a strtol or strtoul or
* strtoll is correct. */
#define CHECK_STRTOX_RESULT() \
/* Did an overflow occur? */ \
if (errno == ERANGE) \
goto err; \
/* Was at least one character converted? */ \
if (endptr == s) \
goto err; \
......@@ -800,6 +803,7 @@ tor_parse_long(const char *s, int base, long min, long max,
char *endptr;
long r;
errno = 0;
r = strtol(s, &endptr, base);
CHECK_STRTOX_RESULT();
}
......@@ -812,6 +816,7 @@ tor_parse_ulong(const char *s, int base, unsigned long min,
char *endptr;
unsigned long r;
errno = 0;
r = strtoul(s, &endptr, base);
CHECK_STRTOX_RESULT();
}
......@@ -823,6 +828,7 @@ tor_parse_double(const char *s, double min, double max, int *ok, char **next)
char *endptr;
double r;
errno = 0;
r = strtod(s, &endptr);
CHECK_STRTOX_RESULT();
}
......@@ -836,6 +842,7 @@ tor_parse_uint64(const char *s, int base, uint64_t min,
char *endptr;
uint64_t r;
errno = 0;
#ifdef HAVE_STRTOULL
r = (uint64_t)strtoull(s, &endptr, base);
#elif defined(MS_WINDOWS)
......
......@@ -283,6 +283,21 @@ test_util_strmisc(void)
test_assert(i == 1);
}
{
/* Test tor_parse_* where we overflow/underflow the underlying type. */
/* This string should overflow 64-bit ints. */
#define TOOBIG "100000000000000000000000000"
test_eq(0L, tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
test_eq(i, 0);
test_eq(0L, tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
test_eq(i, 0);
test_eq(0UL, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
test_eq(i, 0);
test_eq(U64_LITERAL(0), tor_parse_uint64(TOOBIG, 10,
0, UINT64_MAX, &i, NULL));
test_eq(i, 0);
}
/* Test failing snprintf cases */
test_eq(-1, tor_snprintf(buf, 0, "Foo"));
test_eq(-1, tor_snprintf(buf, 2, "Foo"));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment