common: set errno=0 before calling strto{l,ul,ull}

The strto{l,ul,ull} functions do not set errno upon a successful return, so a
successful return from a maximally valued input could be misinterpreted as an
overflow error if errno happened already to be set to ERANGE before the call.
To guard against this edge case, always set errno to zero before calling these
functions if checking errno afterward.

Changelog-None
This commit is contained in:
Matt Whitlock
2025-07-12 11:38:38 -04:00
committed by Rusty Russell
parent 22b452ad19
commit ea2feccbf8
3 changed files with 6 additions and 1 deletions

View File

@@ -833,6 +833,7 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
* anything except a `multiplier` (see table above)... MUST fail the
* payment.
**/
errno = 0;
amount = strtoull(amountstr, &end, 10);
if (amount == ULLONG_MAX && errno == ERANGE)
return decode_fail(b11, fail,

View File

@@ -233,6 +233,7 @@ static void parse_number(const char **guide, u32 *number)
char *endp;
long int l;
errno = 0;
l = strtol(*guide, &endp, 10);
assert(endp != *guide);
assert(errno != ERANGE);
@@ -518,6 +519,7 @@ bool json_to_bitcoin_amount(const char *buffer, const jsmntok_t *tok,
char *end;
unsigned long btc, sat;
errno = 0;
btc = strtoul(buffer + tok->start, &end, 10);
if (btc == ULONG_MAX && errno == ERANGE)
return false;

View File

@@ -66,6 +66,7 @@ bool json_to_u64(const char *buffer, const jsmntok_t *tok, u64 *num)
char *end;
unsigned long long l;
errno = 0;
l = strtoull(buffer + tok->start, &end, 0);
if (end != buffer + tok->end)
return false;
@@ -88,6 +89,7 @@ bool json_to_s64(const char *buffer, const jsmntok_t *tok, s64 *num)
char *end;
long long l;
errno = 0;
l = strtoll(buffer + tok->start, &end, 0);
if (end != buffer + tok->end)
return false;
@@ -129,7 +131,7 @@ bool json_to_double(const char *buffer, const jsmntok_t *tok, double *num)
if (end != buffer + tok->end)
return false;
/* Check for overflow */
/* Check for overflow/underflow */
if (errno == ERANGE)
return false;