Kaydet (Commit) 829dacce authored tarafından Han Lee's avatar Han Lee Kaydeden (comit) Victor Stinner

bpo-26669: Fix nan arg value error in pytime.c (#3085)

* Fix #26669

* Modify NaN check function and error message

* Fix pytime.c when arg is nan

* fix whitespace
üst e6eb48c1
...@@ -485,6 +485,10 @@ class TimeTestCase(unittest.TestCase): ...@@ -485,6 +485,10 @@ class TimeTestCase(unittest.TestCase):
self.assertRaises(OSError, time.localtime, invalid_time_t) self.assertRaises(OSError, time.localtime, invalid_time_t)
self.assertRaises(OSError, time.ctime, invalid_time_t) self.assertRaises(OSError, time.ctime, invalid_time_t)
# Issue #26669: check for localtime() failure
self.assertRaises(ValueError, time.localtime, float("nan"))
self.assertRaises(ValueError, time.ctime, float("nan"))
def test_get_clock_info(self): def test_get_clock_info(self):
clocks = ['clock', 'perf_counter', 'process_time', 'time'] clocks = ['clock', 'perf_counter', 'process_time', 'time']
if hasattr(time, 'monotonic'): if hasattr(time, 'monotonic'):
...@@ -819,6 +823,11 @@ class TestCPyTime(CPyTimeTestCase, unittest.TestCase): ...@@ -819,6 +823,11 @@ class TestCPyTime(CPyTimeTestCase, unittest.TestCase):
lambda secs: secs * SEC_TO_NS, lambda secs: secs * SEC_TO_NS,
value_filter=c_int_filter) value_filter=c_int_filter)
# test nan
for time_rnd, _ in ROUNDING_MODES:
with self.assertRaises(TypeError):
PyTime_FromSeconds(float('nan'))
def test_FromSecondsObject(self): def test_FromSecondsObject(self):
from _testcapi import PyTime_FromSecondsObject from _testcapi import PyTime_FromSecondsObject
...@@ -830,6 +839,11 @@ class TestCPyTime(CPyTimeTestCase, unittest.TestCase): ...@@ -830,6 +839,11 @@ class TestCPyTime(CPyTimeTestCase, unittest.TestCase):
PyTime_FromSecondsObject, PyTime_FromSecondsObject,
lambda ns: self.decimal_round(ns * SEC_TO_NS)) lambda ns: self.decimal_round(ns * SEC_TO_NS))
# test nan
for time_rnd, _ in ROUNDING_MODES:
with self.assertRaises(ValueError):
PyTime_FromSecondsObject(float('nan'), time_rnd)
def test_AsSecondsDouble(self): def test_AsSecondsDouble(self):
from _testcapi import PyTime_AsSecondsDouble from _testcapi import PyTime_AsSecondsDouble
...@@ -843,6 +857,11 @@ class TestCPyTime(CPyTimeTestCase, unittest.TestCase): ...@@ -843,6 +857,11 @@ class TestCPyTime(CPyTimeTestCase, unittest.TestCase):
float_converter, float_converter,
NS_TO_SEC) NS_TO_SEC)
# test nan
for time_rnd, _ in ROUNDING_MODES:
with self.assertRaises(TypeError):
PyTime_AsSecondsDouble(float('nan'))
def create_decimal_converter(self, denominator): def create_decimal_converter(self, denominator):
denom = decimal.Decimal(denominator) denom = decimal.Decimal(denominator)
...@@ -948,6 +967,11 @@ class TestOldPyTime(CPyTimeTestCase, unittest.TestCase): ...@@ -948,6 +967,11 @@ class TestOldPyTime(CPyTimeTestCase, unittest.TestCase):
self.create_converter(SEC_TO_US), self.create_converter(SEC_TO_US),
value_filter=self.time_t_filter) value_filter=self.time_t_filter)
# test nan
for time_rnd, _ in ROUNDING_MODES:
with self.assertRaises(ValueError):
pytime_object_to_timeval(float('nan'), time_rnd)
def test_object_to_timespec(self): def test_object_to_timespec(self):
from _testcapi import pytime_object_to_timespec from _testcapi import pytime_object_to_timespec
...@@ -959,6 +983,11 @@ class TestOldPyTime(CPyTimeTestCase, unittest.TestCase): ...@@ -959,6 +983,11 @@ class TestOldPyTime(CPyTimeTestCase, unittest.TestCase):
self.create_converter(SEC_TO_NS), self.create_converter(SEC_TO_NS),
value_filter=self.time_t_filter) value_filter=self.time_t_filter)
# test nan
for time_rnd, _ in ROUNDING_MODES:
with self.assertRaises(ValueError):
pytime_object_to_timespec(float('nan'), time_rnd)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
...@@ -133,6 +133,11 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, ...@@ -133,6 +133,11 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
if (PyFloat_Check(obj)) { if (PyFloat_Check(obj)) {
double d = PyFloat_AsDouble(obj); double d = PyFloat_AsDouble(obj);
if (Py_IS_NAN(d)) {
*numerator = 0;
PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
return -1;
}
return _PyTime_DoubleToDenominator(d, sec, numerator, return _PyTime_DoubleToDenominator(d, sec, numerator,
denominator, round); denominator, round);
} }
...@@ -154,6 +159,11 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round) ...@@ -154,6 +159,11 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
volatile double d; volatile double d;
d = PyFloat_AsDouble(obj); d = PyFloat_AsDouble(obj);
if (Py_IS_NAN(d)) {
PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
return -1;
}
d = _PyTime_Round(d, round); d = _PyTime_Round(d, round);
(void)modf(d, &intpart); (void)modf(d, &intpart);
...@@ -301,6 +311,10 @@ _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round, ...@@ -301,6 +311,10 @@ _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
if (PyFloat_Check(obj)) { if (PyFloat_Check(obj)) {
double d; double d;
d = PyFloat_AsDouble(obj); d = PyFloat_AsDouble(obj);
if (Py_IS_NAN(d)) {
PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
return -1;
}
return _PyTime_FromFloatObject(t, d, round, unit_to_ns); return _PyTime_FromFloatObject(t, d, round, unit_to_ns);
} }
else { else {
......
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