diff options
author | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2010-05-27 22:03:53 (GMT) |
---|---|---|
committer | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2010-05-27 22:03:53 (GMT) |
commit | 3efc2fd479f024b70d9532cd4249ad6aaf8aba77 (patch) | |
tree | 844993b1a8a4fe39009f7c07065c9a8eff0502a2 | |
parent | dfe715e13612c32a531ea9c0e8869da929481b25 (diff) | |
download | cpython-3efc2fd479f024b70d9532cd4249ad6aaf8aba77.zip cpython-3efc2fd479f024b70d9532cd4249ad6aaf8aba77.tar.gz cpython-3efc2fd479f024b70d9532cd4249ad6aaf8aba77.tar.bz2 |
Merged revisions 81568 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
................
r81568 | alexander.belopolsky | 2010-05-27 17:42:58 -0400 (Thu, 27 May 2010) | 10 lines
Merged revisions 81566 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r81566 | alexander.belopolsky | 2010-05-27 16:55:27 -0400 (Thu, 27 May 2010) | 3 lines
Issue #7150: Raise OverflowError if the result of adding or subtracting
timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range.
........
................
-rw-r--r-- | Lib/test/test_datetime.py | 19 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/datetimemodule.c | 29 |
3 files changed, 29 insertions, 22 deletions
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index 8bf8420..ead8d70 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -700,15 +700,16 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): def test_overflow(self): tiny = self.theclass.resolution - dt = self.theclass.min + tiny - dt -= tiny # no problem - self.assertRaises(OverflowError, dt.__sub__, tiny) - self.assertRaises(OverflowError, dt.__add__, -tiny) - - dt = self.theclass.max - tiny - dt += tiny # no problem - self.assertRaises(OverflowError, dt.__add__, tiny) - self.assertRaises(OverflowError, dt.__sub__, -tiny) + for delta in [tiny, timedelta(1), timedelta(2)]: + dt = self.theclass.min + delta + dt -= delta # no problem + self.assertRaises(OverflowError, dt.__sub__, delta) + self.assertRaises(OverflowError, dt.__add__, -delta) + + dt = self.theclass.max - delta + dt += delta # no problem + self.assertRaises(OverflowError, dt.__add__, delta) + self.assertRaises(OverflowError, dt.__sub__, -delta) def test_fromtimestamp(self): import time @@ -54,6 +54,9 @@ C-API Library ------- +- Issue #7150: Raise OverflowError if the result of adding or subtracting + timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range. + - Issue #4769: Fix main() function of the base64 module, use sys.stdin.buffer and sys.stdout.buffer (instead of sys.stdin and sys.stdout) to use the bytes API diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c index 6235d6e..419eb7b 100644 --- a/Modules/datetimemodule.c +++ b/Modules/datetimemodule.c @@ -30,6 +30,7 @@ #define MINYEAR 1 #define MAXYEAR 9999 +#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */ /* Nine decimal digits is easy to communicate, and leaves enough room * so that two delta days can be added w/o fear of overflowing a signed @@ -480,7 +481,7 @@ normalize_d_s_us(int *d, int *s, int *us) * The input values must be such that the internals don't overflow. * The way this routine is used, we don't get close. */ -static void +static int normalize_y_m_d(int *y, int *m, int *d) { int dim; /* # of days in month */ @@ -534,11 +535,23 @@ normalize_y_m_d(int *y, int *m, int *d) else { int ordinal = ymd_to_ord(*y, *m, 1) + *d - 1; - ord_to_ymd(ordinal, y, m, d); + if (ordinal < 1 || ordinal > MAXORDINAL) { + goto error; + } else { + ord_to_ymd(ordinal, y, m, d); + return 0; + } } } assert(*m > 0); assert(*d > 0); + if (MINYEAR <= *y && *y <= MAXYEAR) + return 0; + error: + PyErr_SetString(PyExc_OverflowError, + "date value out of range"); + return -1; + } /* Fiddle out-of-bounds months and days so that the result makes some kind @@ -548,17 +561,7 @@ normalize_y_m_d(int *y, int *m, int *d) static int normalize_date(int *year, int *month, int *day) { - int result; - - normalize_y_m_d(year, month, day); - if (MINYEAR <= *year && *year <= MAXYEAR) - result = 0; - else { - PyErr_SetString(PyExc_OverflowError, - "date value out of range"); - result = -1; - } - return result; + return normalize_y_m_d(year, month, day); } /* Force all the datetime fields into range. The parameters are both |