From 17fc45626625040c435d5d31e53a4c3e9bdab68f Mon Sep 17 00:00:00 2001 From: netliomax25-code Date: Mon, 22 Jun 2026 16:33:12 +0530 Subject: [PATCH] reject overlong decimal integer instead of coercing to inf --- tests/test_parser.py | 15 +++++++++++++++ tomlkit/parser.py | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/test_parser.py b/tests/test_parser.py index 375932e..b2f8310 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -2,9 +2,11 @@ from tomlkit.exceptions import EmptyTableNameError from tomlkit.exceptions import InternalParserError +from tomlkit.exceptions import InvalidNumberError from tomlkit.exceptions import InvalidUnicodeValueError from tomlkit.exceptions import ParseError from tomlkit.exceptions import UnexpectedCharError +from tomlkit.items import Integer from tomlkit.items import StringType from tomlkit.parser import Parser @@ -197,3 +199,16 @@ def test_parser_rejects_aot_header_missing_second_bracket(content: str) -> None: parser = Parser(content) with pytest.raises(ParseError): parser.parse() + + +def test_parser_rejects_overlong_decimal_integer() -> None: + # A decimal integer with more digits than Python's int-from-string limit + # raises ValueError in int(); it must be reported as an invalid number, not + # silently fall through to float() and become inf. + parser = Parser("a = " + "9" * 4301) + with pytest.raises(InvalidNumberError): + parser.parse() + + # the value just under the limit is still a normal integer + value = Parser("a = " + "9" * 4300).parse()["a"] + assert isinstance(value, Integer) diff --git a/tomlkit/parser.py b/tomlkit/parser.py index b952b36..b55e177 100644 --- a/tomlkit/parser.py +++ b/tomlkit/parser.py @@ -786,11 +786,20 @@ def _parse_number(self, raw: str, trivia: Trivia) -> Item | None: try: return Integer(int(sign + clean, base), trivia, sign + raw) except ValueError: + pass + + # Only fall back to float for an actual float literal (a fractional + # dot, a base-10 exponent, or inf/nan). A decimal integer whose digit + # count exceeds Python's int-from-string conversion limit also raises + # ValueError above; it must be rejected, not silently coerced to inf. + if base == 10 and ("." in clean or "e" in clean or clean in ("inf", "nan")): try: return Float(float(sign + clean), trivia, sign + raw) except ValueError: return None + return None + def _parse_literal_string(self) -> String: with self._state: return self._parse_string(StringType.SLL)