bpo-13312: Avoid int underflow in time year. (GH-8912) · python/cpython@d5f017b

3 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -19,7 +19,7 @@

1919

# Max year is only limited by the size of C int.

2020

SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4

2121

TIME_MAXYEAR = (1 << 8 * SIZEOF_INT - 1) - 1

22-

TIME_MINYEAR = -TIME_MAXYEAR - 1

22+

TIME_MINYEAR = -TIME_MAXYEAR - 1 + 1900

2323
2424

SEC_TO_US = 10 ** 6

2525

US_TO_NS = 10 ** 3

@@ -714,12 +714,11 @@ def test_negative(self):

714714

self.assertEqual(self.yearstr(-123456), '-123456')

715715

self.assertEqual(self.yearstr(-123456789), str(-123456789))

716716

self.assertEqual(self.yearstr(-1234567890), str(-1234567890))

717-

self.assertEqual(self.yearstr(TIME_MINYEAR + 1900), str(TIME_MINYEAR + 1900))

718-

# Issue #13312: it may return wrong value for year < TIME_MINYEAR + 1900

719-

# Skip the value test, but check that no error is raised

720-

self.yearstr(TIME_MINYEAR)

721-

# self.assertEqual(self.yearstr(TIME_MINYEAR), str(TIME_MINYEAR))

717+

self.assertEqual(self.yearstr(TIME_MINYEAR), str(TIME_MINYEAR))

718+

# Modules/timemodule.c checks for underflow

722719

self.assertRaises(OverflowError, self.yearstr, TIME_MINYEAR - 1)

720+

with self.assertRaises(OverflowError):

721+

self.yearstr(-TIME_MAXYEAR - 1)

723722
724723
725724

class TestAsctime4dyear(_TestAsctimeYear, _Test4dYear, unittest.TestCase):

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,2 @@

1+

Avoids a possible integer underflow (undefined behavior) in the time

2+

module's year handling code when passed a very low negative year value.

Original file line numberDiff line numberDiff line change

@@ -551,6 +551,12 @@ gettmarg(PyObject *args, struct tm *p, const char *format)

551551

&p->tm_hour, &p->tm_min, &p->tm_sec,

552552

&p->tm_wday, &p->tm_yday, &p->tm_isdst))

553553

return 0;

554+
555+

if (y < INT_MIN + 1900) {

556+

PyErr_SetString(PyExc_OverflowError, "year out of range");

557+

return 0;

558+

}

559+
554560

p->tm_year = y - 1900;

555561

p->tm_mon--;

556562

p->tm_wday = (p->tm_wday + 1) % 7;