From 17fc45626625040c435d5d31e53a4c3e9bdab68f Mon Sep 17 00:00:00 2001 From: netliomax25-code Date: Mon, 22 Jun 2026 16:33:12 +0530 Subject: [PATCH 1/2] 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) From 6e7d1bb44cbc73d5176526ec5da1027b3f4274c7 Mon Sep 17 00:00:00 2001 From: Kartik Kenchi Date: Sun, 5 Jul 2026 19:07:38 +0530 Subject: [PATCH 2/2] skip overlong-integer test when the int digit limit is unavailable Python 3.9.13 and earlier lack the int-from-string conversion limit (backported in 3.9.14), so int() succeeds on any digit count and the parser never rejects the literal. The macOS and Windows 3.9 CI jobs run 3.9.13, which is why they failed while Ubuntu's 3.9 passed. --- tests/test_parser.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_parser.py b/tests/test_parser.py index b2f8310..d7f5c90 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1,3 +1,5 @@ +import sys + import pytest from tomlkit.exceptions import EmptyTableNameError @@ -201,6 +203,10 @@ def test_parser_rejects_aot_header_missing_second_bracket(content: str) -> None: parser.parse() +@pytest.mark.skipif( + not hasattr(sys, "get_int_max_str_digits"), + reason="requires the int-from-string digit limit (3.9.14+/3.10.7+/3.11+)", +) 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