diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index 938c538535..c678b58bae 100644 --- a/django/views/generic/dates.py +++ b/django/views/generic/dates.py @@ -66,7 +66,10 @@ class YearMixin(object): The interval is defined by start date <= item date < next start date. """ - return date.replace(year=date.year + 1, month=1, day=1) + try: + return date.replace(year=date.year + 1, month=1, day=1) + except ValueError: + raise Http404(_("Date out of range")) def _get_current_year(self, date): """ @@ -123,7 +126,10 @@ class MonthMixin(object): The interval is defined by start date <= item date < next start date. """ if date.month == 12: - return date.replace(year=date.year + 1, month=1, day=1) + try: + return date.replace(year=date.year + 1, month=1, day=1) + except ValueError: + raise Http404(_("Date out of range")) else: return date.replace(month=date.month + 1, day=1) @@ -237,7 +243,10 @@ class WeekMixin(object): The interval is defined by start date <= item date < next start date. """ - return date + datetime.timedelta(days=7 - self._get_weekday(date)) + try: + return date + datetime.timedelta(days=7 - self._get_weekday(date)) + except OverflowError: + raise Http404(_("Date out of range")) def _get_current_week(self, date): """ diff --git a/docs/releases/1.11.2.txt b/docs/releases/1.11.2.txt index 99e82f75a0..ab7d04959f 100644 --- a/docs/releases/1.11.2.txt +++ b/docs/releases/1.11.2.txt @@ -44,3 +44,6 @@ Bugfixes invalid SQL (:ticket:`28199`). * Corrected detection of GDAL 2.1 on Windows (:ticket:`28181`). + +* Made date-based generic views return a 404 rather than crash when given an + out of range date (:ticket:`28209`). diff --git a/tests/generic_views/test_dates.py b/tests/generic_views/test_dates.py index 9b7c20ec73..5e52bb48e2 100644 --- a/tests/generic_views/test_dates.py +++ b/tests/generic_views/test_dates.py @@ -664,6 +664,17 @@ class DateDetailViewTests(TestDataMixin, TestCase): self.assertEqual(res.context['book'], b) self.assertTemplateUsed(res, 'generic_views/book_detail.html') + def test_year_out_of_range(self): + urls = [ + '/dates/books/9999/', + '/dates/books/9999/12/', + '/dates/books/9999/week/52/', + ] + for url in urls: + res = self.client.get(url) + self.assertEqual(res.status_code, 404) + self.assertEqual(res.context['exception'], 'Date out of range') + def test_invalid_url(self): with self.assertRaises(AttributeError): self.client.get("/dates/books/2008/oct/01/nopk/")