From ea256a1316803bf342e21a2877706a3f7548e3b0 Mon Sep 17 00:00:00 2001 From: Matt Whitlock Date: Sat, 12 Jul 2025 11:38:38 -0400 Subject: [PATCH] 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 --- common/bolt11.c | 1 + common/json_parse.c | 2 ++ common/json_parse_simple.c | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/bolt11.c b/common/bolt11.c index db9209fdaa2f..ca9dce78cbf9 100644 --- a/common/bolt11.c +++ b/common/bolt11.c @@ -810,6 +810,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, diff --git a/common/json_parse.c b/common/json_parse.c index 1d272b1f0c6c..866fce50c8c5 100644 --- a/common/json_parse.c +++ b/common/json_parse.c @@ -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; diff --git a/common/json_parse_simple.c b/common/json_parse_simple.c index 7f9c630ebeb2..461a4b01e388 100644 --- a/common/json_parse_simple.c +++ b/common/json_parse_simple.c @@ -71,6 +71,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; @@ -93,6 +94,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; @@ -134,7 +136,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;