From b6bbff8782f4ad2d725d67ea5dd43702aeed7c91 Mon Sep 17 00:00:00 2001 From: Christopher Wellons Date: Wed, 11 Feb 2026 21:39:45 -0500 Subject: [PATCH] Fix overflow parsing large float exponents Parsing huge exponents results in a signed overflow (UB). In practice it likely wraps to an incorrect KDL number for the input. The fix includes a test that fails without it. --- src/parser.c | 5 ++++- tests/parser_test.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/parser.c b/src/parser.c index d51341d..ca70853 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1048,7 +1048,10 @@ static bool _parse_decimal_float(kdl_str number, kdl_value* val, kdl_owned_strin int digit = c - '0'; if (state == exponent || state == exponent_nodigit) { state = exponent; - explicit_exponent = explicit_exponent * 10 + digit; + // stop parsing beyond rough heuristic, avoids overflow + if (explicit_exponent < 285) { + explicit_exponent = explicit_exponent * 10 + digit; + } } else { decimal_mantissa = decimal_mantissa * 10 + digit; if (state == before_decimal) { diff --git a/tests/parser_test.c b/tests/parser_test.c index 5940b8c..81f4ebf 100644 --- a/tests/parser_test.c +++ b/tests/parser_test.c @@ -388,6 +388,33 @@ static void test_parser_detects_version(void) kdl_destroy_parser(parser_v2); } +static void test_extreme_float(void) +{ + char const* const kdl_text = "node1 1e4294967296"; + + kdl_str doc = kdl_str_from_cstr(kdl_text); + kdl_parser* parser = kdl_create_string_parser(doc, 0); + + // test all events + kdl_event_data* ev; + + ev = kdl_parser_next_event(parser); + ASSERT(ev->event == KDL_EVENT_START_NODE); + + ev = kdl_parser_next_event(parser); + ASSERT(ev->event == KDL_EVENT_ARGUMENT); + ASSERT(ev->value.type == KDL_TYPE_NUMBER); + ASSERT(ev->value.number.type == KDL_NUMBER_TYPE_STRING_ENCODED); + + ev = kdl_parser_next_event(parser); + ASSERT(ev->event == KDL_EVENT_END_NODE); + + ev = kdl_parser_next_event(parser); + ASSERT(ev->event == KDL_EVENT_EOF); + + kdl_destroy_parser(parser); +} + void TEST_MAIN(void) { run_test("Parser: basics", &test_basics); @@ -399,4 +426,5 @@ void TEST_MAIN(void) run_test("Parser: type can't be number", &test_number_type); run_test("Parser: BOM treated as whitespace", &test_bom); run_test("Parser: KDLv1 and KDLv2 both supported", &test_parser_detects_version); + run_test("Parser: parse extreme floating point", &test_extreme_float); }