From 27b4fb318ebef45255ce01c1e80f8a524044ab20 Mon Sep 17 00:00:00 2001 From: mohammed arib Date: Fri, 3 Jul 2026 14:34:34 +0530 Subject: [PATCH] fix quadratic backtracking in timestamp parse regex --- arrow/parser.py | 2 +- tests/test_parser.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arrow/parser.py b/arrow/parser.py index fc3774b09..993212858 100644 --- a/arrow/parser.py +++ b/arrow/parser.py @@ -166,7 +166,7 @@ class DateTimeParser: _TZ_NAME_RE: ClassVar[Pattern[str]] = re.compile(r"\w[\w+\-/]+") # NOTE: timestamps cannot be parsed from natural language strings (by removing the ^...$) because it will # break cases like "15 Jul 2000" and a format list (see issue #447) - _TIMESTAMP_RE: ClassVar[Pattern[str]] = re.compile(r"^\-?\d+\.?\d+$") + _TIMESTAMP_RE: ClassVar[Pattern[str]] = re.compile(r"^\-?(?:\d+\.\d+|\d{2,})$") _TIMESTAMP_EXPANDED_RE: ClassVar[Pattern[str]] = re.compile(r"^\-?\d+$") _TIME_RE: ClassVar[Pattern[str]] = re.compile( r"^(\d{2})(?:\:?(\d{2}))?(?:\:?(\d{2}))?(?:([\.\,])(\d+))?$" diff --git a/tests/test_parser.py b/tests/test_parser.py index 7038d880f..14111f237 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -244,6 +244,15 @@ def test_parse_timestamp(self): with pytest.raises(ParserError): self.parser.parse(".1565982019", "X") + def test_parse_timestamp_long_invalid_input(self): + # a long digit run followed by a non-digit character used to trigger + # quadratic backtracking in the timestamp regex (_TIMESTAMP_RE) + malformed = "9" * 50000 + "!" + start = time.perf_counter() + with pytest.raises(ParserError): + self.parser.parse(malformed, "X") + assert time.perf_counter() - start < 1.0 + # NOTE: negative timestamps cannot be handled by datetime on Windows # Must use timedelta to handle them: https://stackoverflow.com/questions/36179914 @pytest.mark.skipif(