diff --git a/packages/abstractions/kiota_abstractions/date_utils.py b/packages/abstractions/kiota_abstractions/date_utils.py index 05e9572d..eb0877fd 100644 --- a/packages/abstractions/kiota_abstractions/date_utils.py +++ b/packages/abstractions/kiota_abstractions/date_utils.py @@ -48,13 +48,16 @@ def parse_timedelta_from_iso_format(text: str) -> timedelta: raise ValueError("Combining weeks with other date/time parts is not supported") _total_days = (years * 365) + (months * 30) + days - return timedelta( - days=_total_days, - hours=hours, - minutes=minutes, - seconds=seconds, - weeks=weeks, - ) + try: + return timedelta( + days=_total_days, + hours=hours, + minutes=minutes, + seconds=seconds, + weeks=weeks, + ) + except OverflowError as exc: + raise ValueError(f"ISO8601 duration out of range: {text}") from exc _TIMEDELTA_PATTERN = re.compile(r"^(?P\d+):(?P\d+)(?::(?P\d+))?$") @@ -73,7 +76,10 @@ def parse_timedelta_string(text: str) -> timedelta: hours = int(m.group("hours")) minutes = int(m.group("minutes")) seconds = int(m.group("seconds") or 0) - return timedelta(hours=hours, minutes=minutes, seconds=seconds) + try: + return timedelta(hours=hours, minutes=minutes, seconds=seconds) + except OverflowError as overflow: + raise ValueError(f"Timedelta string out of range: {text}") from overflow _TIME_REPLACEMENT_PATTERN = re.compile(r'(\d)([.,])(\d+)') diff --git a/packages/abstractions/tests/test_date_utils.py b/packages/abstractions/tests/test_date_utils.py index 640a2393..df9fc495 100644 --- a/packages/abstractions/tests/test_date_utils.py +++ b/packages/abstractions/tests/test_date_utils.py @@ -84,3 +84,15 @@ def test_parse_timedelta_string_valid(text:str, expected_hours:int): result = parse_timedelta_string(text) assert result.days == 0 assert result.seconds == expected_hours * 3600 + + +@pytest.mark.parametrize("text", ["P1000000000D", "PT24000000000H", "P" + "9" * 400 + "D"]) +def test_parse_timedelta_from_iso_format_out_of_range(text: str): + with pytest.raises(ValueError, match="out of range"): + parse_timedelta_from_iso_format(text) + + +@pytest.mark.parametrize("text", ["50001140846:00021", "P1000000000D"]) +def test_parse_timedelta_string_out_of_range(text: str): + with pytest.raises(ValueError): + parse_timedelta_string(text) diff --git a/packages/serialization/form/tests/unit/test_form_parse_node.py b/packages/serialization/form/tests/unit/test_form_parse_node.py index 94dff9c4..51b4faf5 100644 --- a/packages/serialization/form/tests/unit/test_form_parse_node.py +++ b/packages/serialization/form/tests/unit/test_form_parse_node.py @@ -175,6 +175,13 @@ def test_get_object_value(): assert result.additional_data["mobilePhone"] assert result.additional_data["accountEnabled"] == "true" assert result.additional_data["jobTitle"] == "Auditor" + + +@pytest.mark.parametrize("value", ["50001140846:00021", "P1000000000D"]) +def test_get_object_value_keeps_out_of_range_duration_as_string(value): + parse_node = FormParseNode(f"jobTitle=Auditor&extra={value}") + result = parse_node.get_object_value(TestEntity) + assert result.additional_data["extra"] == value def returns_default_if_child_node_does_not_exist(): parse_node = FormParseNode(TEST_USER_FORM) diff --git a/packages/serialization/json/tests/unit/test_json_parse_node.py b/packages/serialization/json/tests/unit/test_json_parse_node.py index 4bc54713..c5d59dc8 100644 --- a/packages/serialization/json/tests/unit/test_json_parse_node.py +++ b/packages/serialization/json/tests/unit/test_json_parse_node.py @@ -105,6 +105,12 @@ def test_get_timedelta_value(): assert str(result) == "0:00:30" +@pytest.mark.parametrize("value", ["50001140846:00021", "P1000000000D"]) +def test_get_timedelta_value_out_of_range(value): + parse_node = JsonParseNode(value) + assert parse_node.get_timedelta_value() is None + + def test_get_collection_of_primitive_values(): parse_node = JsonParseNode([12.1, 12.2, 12.3, 12.4, 12.5]) result = parse_node.get_collection_of_primitive_values(float) diff --git a/packages/serialization/json/tests/unit/test_json_serialization_writer.py b/packages/serialization/json/tests/unit/test_json_serialization_writer.py index 207136c0..d115c1bc 100644 --- a/packages/serialization/json/tests/unit/test_json_serialization_writer.py +++ b/packages/serialization/json/tests/unit/test_json_serialization_writer.py @@ -150,6 +150,13 @@ def test_write_timedelta_value_invalid_string(): assert "Invalid timedelta string value found for property diff" in str(excinfo.value) +@pytest.mark.parametrize("value", ["50001140846:00021", "P1000000000D"]) +def test_write_timedelta_value_out_of_range_string(value): + json_serialization_writer = JsonSerializationWriter() + with pytest.raises(ValueError, match="Invalid timedelta string value found for property diff"): + json_serialization_writer.write_timedelta_value("diff", value) + + def test_write_date_value(): json_serialization_writer = JsonSerializationWriter() json_serialization_writer.write_date_value("birthday", date(2000,9,4))