From 52f4139674ed8156d6956e6fca507f5aea64f627 Mon Sep 17 00:00:00 2001 From: Peter Thomassen <4242683+peterthomassen@users.noreply.github.com> Date: Thu, 24 Nov 2022 12:27:45 +0100 Subject: [PATCH] Properly handle OverflowError in DurationField deserialization (#8042) Related: https://github.com/django/django/pull/8870/files --- rest_framework/fields.py | 6 +++++- tests/test_fields.py | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 4bea5c419..4eae004dc 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1329,6 +1329,7 @@ class DurationField(Field): 'invalid': _('Duration has wrong format. Use one of these formats instead: {format}.'), 'max_value': _('Ensure this value is less than or equal to {max_value}.'), 'min_value': _('Ensure this value is greater than or equal to {min_value}.'), + 'overflow': _('The number of days must be between {min_days} and {max_days}.'), } def __init__(self, **kwargs): @@ -1347,7 +1348,10 @@ class DurationField(Field): def to_internal_value(self, value): if isinstance(value, datetime.timedelta): return value - parsed = parse_duration(str(value)) + try: + parsed = parse_duration(str(value)) + except OverflowError: + self.fail('overflow', min_days=datetime.timedelta.min.days, max_days=datetime.timedelta.max.days) if parsed is not None: return parsed self.fail('invalid', format='[DD] [HH:[MM:]]ss[.uuuuuu]') diff --git a/tests/test_fields.py b/tests/test_fields.py index bcdcf15d8..648c2a9c9 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1642,10 +1642,14 @@ class TestDurationField(FieldValues): '08:01': datetime.timedelta(minutes=8, seconds=1), datetime.timedelta(days=3, hours=8, minutes=32, seconds=1, microseconds=123): datetime.timedelta(days=3, hours=8, minutes=32, seconds=1, microseconds=123), 3600: datetime.timedelta(hours=1), + '-999999999 00': datetime.timedelta(days=-999999999), + '999999999 00': datetime.timedelta(days=999999999), } invalid_inputs = { 'abc': ['Duration has wrong format. Use one of these formats instead: [DD] [HH:[MM:]]ss[.uuuuuu].'], '3 08:32 01.123': ['Duration has wrong format. Use one of these formats instead: [DD] [HH:[MM:]]ss[.uuuuuu].'], + '-1000000000 00': ['The number of days must be between -999999999 and 999999999.'], + '1000000000 00': ['The number of days must be between -999999999 and 999999999.'], } outputs = { datetime.timedelta(days=3, hours=8, minutes=32, seconds=1, microseconds=123): '3 08:32:01.000123',