Commit f03a6164 authored by Alexander Belopolsky's avatar Alexander Belopolsky

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.
........
parent 1ed21db0
...@@ -761,15 +761,16 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): ...@@ -761,15 +761,16 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
def test_overflow(self): def test_overflow(self):
tiny = self.theclass.resolution tiny = self.theclass.resolution
dt = self.theclass.min + tiny for delta in [tiny, timedelta(1), timedelta(2)]:
dt -= tiny # no problem dt = self.theclass.min + delta
self.assertRaises(OverflowError, dt.__sub__, tiny) dt -= delta # no problem
self.assertRaises(OverflowError, dt.__add__, -tiny) self.assertRaises(OverflowError, dt.__sub__, delta)
self.assertRaises(OverflowError, dt.__add__, -delta)
dt = self.theclass.max - tiny
dt += tiny # no problem dt = self.theclass.max - delta
self.assertRaises(OverflowError, dt.__add__, tiny) dt += delta # no problem
self.assertRaises(OverflowError, dt.__sub__, -tiny) self.assertRaises(OverflowError, dt.__add__, delta)
self.assertRaises(OverflowError, dt.__sub__, -delta)
def test_fromtimestamp(self): def test_fromtimestamp(self):
import time import time
......
...@@ -395,6 +395,9 @@ C-API ...@@ -395,6 +395,9 @@ C-API
Library 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 #8806: add SSL contexts support to ftplib. - Issue #8806: add SSL contexts support to ftplib.
- Issue #4769: Fix main() function of the base64 module, use sys.stdin.buffer - Issue #4769: Fix main() function of the base64 module, use sys.stdin.buffer
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#define MINYEAR 1 #define MINYEAR 1
#define MAXYEAR 9999 #define MAXYEAR 9999
#define MAXORDINAL 3652059 /* date(9999,12,31).toordinal() */
/* Nine decimal digits is easy to communicate, and leaves enough room /* 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 * 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) ...@@ -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 input values must be such that the internals don't overflow.
* The way this routine is used, we don't get close. * 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) normalize_y_m_d(int *y, int *m, int *d)
{ {
int dim; /* # of days in month */ int dim; /* # of days in month */
...@@ -534,11 +535,23 @@ normalize_y_m_d(int *y, int *m, int *d) ...@@ -534,11 +535,23 @@ normalize_y_m_d(int *y, int *m, int *d)
else { else {
int ordinal = ymd_to_ord(*y, *m, 1) + int ordinal = ymd_to_ord(*y, *m, 1) +
*d - 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(*m > 0);
assert(*d > 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 /* 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) ...@@ -548,17 +561,7 @@ normalize_y_m_d(int *y, int *m, int *d)
static int static int
normalize_date(int *year, int *month, int *day) normalize_date(int *year, int *month, int *day)
{ {
int result; return normalize_y_m_d(year, month, day);
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;
} }
/* Force all the datetime fields into range. The parameters are both /* Force all the datetime fields into range. The parameters are both
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment