From 4e9624f4415d91f97ba2adcf3d08087a573f2bc4 Mon Sep 17 00:00:00 2001 From: eeshsaxena Date: Wed, 12 Aug 2026 20:56:35 +0530 Subject: [PATCH] fix: raise ValueError for an out-of-range epoch in to_datetime to_datetime parses number-like values as millisecond epochs via datetime.fromtimestamp(epoch / 1000). A non-finite value ('inf', '-inf') or one large enough to be out of range (1e30, a huge millis integer) passes float() but overflows fromtimestamp, leaking OverflowError or OSError. The function documents ValueError as its failure mode (and to_timestamp / to_date wrap it), so catch those and fall through to the existing ValueError. --- sqlmesh/utils/date.py | 8 +++++++- tests/utils/test_date.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sqlmesh/utils/date.py b/sqlmesh/utils/date.py index 5358719abe..f8df65c352 100644 --- a/sqlmesh/utils/date.py +++ b/sqlmesh/utils/date.py @@ -194,7 +194,13 @@ def to_datetime( try: dt = datetime.strptime(str(value), DATE_INT_FMT) except ValueError: - dt = datetime.fromtimestamp(epoch / 1000.0, tz=UTC) + try: + dt = datetime.fromtimestamp(epoch / 1000.0, tz=UTC) + except (OverflowError, OSError, ValueError): + # A non-finite or out-of-range epoch (e.g. "inf", 1e30, or a + # huge millis value) overflows fromtimestamp. Fall through to + # the ValueError below rather than leaking OverflowError/OSError. + dt = None if dt is None: raise ValueError(f"Could not convert `{value}` to datetime.") diff --git a/tests/utils/test_date.py b/tests/utils/test_date.py index bbd5bdf63a..c926507ccd 100644 --- a/tests/utils/test_date.py +++ b/tests/utils/test_date.py @@ -41,6 +41,17 @@ def test_to_datetime() -> None: assert to_datetime("31536000000") == target +@pytest.mark.parametrize( + "value", + ["inf", "-inf", "1e30", "99999999999999999999", float("inf")], +) +def test_to_datetime_out_of_range_raises(value: t.Any) -> None: + # A non-finite or out-of-range epoch overflows fromtimestamp; it must raise + # the documented ValueError rather than leaking OverflowError/OSError. + with pytest.raises(ValueError): + to_datetime(value) + + @pytest.mark.parametrize( "expression, result", [