Skip to content

Commit 829dacc

Browse files
hahnleevstinner
authored andcommitted
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
1 parent e6eb48c commit 829dacc

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

Lib/test/test_time.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,10 @@ def test_localtime_failure(self):
485485
self.assertRaises(OSError, time.localtime, invalid_time_t)
486486
self.assertRaises(OSError, time.ctime, invalid_time_t)
487487

488+
# Issue #26669: check for localtime() failure
489+
self.assertRaises(ValueError, time.localtime, float("nan"))
490+
self.assertRaises(ValueError, time.ctime, float("nan"))
491+
488492
def test_get_clock_info(self):
489493
clocks = ['clock', 'perf_counter', 'process_time', 'time']
490494
if hasattr(time, 'monotonic'):
@@ -819,6 +823,11 @@ def c_int_filter(secs):
819823
lambda secs: secs * SEC_TO_NS,
820824
value_filter=c_int_filter)
821825

826+
# test nan
827+
for time_rnd, _ in ROUNDING_MODES:
828+
with self.assertRaises(TypeError):
829+
PyTime_FromSeconds(float('nan'))
830+
822831
def test_FromSecondsObject(self):
823832
from _testcapi import PyTime_FromSecondsObject
824833

@@ -830,6 +839,11 @@ def test_FromSecondsObject(self):
830839
PyTime_FromSecondsObject,
831840
lambda ns: self.decimal_round(ns * SEC_TO_NS))
832841

842+
# test nan
843+
for time_rnd, _ in ROUNDING_MODES:
844+
with self.assertRaises(ValueError):
845+
PyTime_FromSecondsObject(float('nan'), time_rnd)
846+
833847
def test_AsSecondsDouble(self):
834848
from _testcapi import PyTime_AsSecondsDouble
835849

@@ -843,6 +857,11 @@ def float_converter(ns):
843857
float_converter,
844858
NS_TO_SEC)
845859

860+
# test nan
861+
for time_rnd, _ in ROUNDING_MODES:
862+
with self.assertRaises(TypeError):
863+
PyTime_AsSecondsDouble(float('nan'))
864+
846865
def create_decimal_converter(self, denominator):
847866
denom = decimal.Decimal(denominator)
848867

@@ -948,6 +967,11 @@ def test_object_to_timeval(self):
948967
self.create_converter(SEC_TO_US),
949968
value_filter=self.time_t_filter)
950969

970+
# test nan
971+
for time_rnd, _ in ROUNDING_MODES:
972+
with self.assertRaises(ValueError):
973+
pytime_object_to_timeval(float('nan'), time_rnd)
974+
951975
def test_object_to_timespec(self):
952976
from _testcapi import pytime_object_to_timespec
953977

@@ -959,6 +983,11 @@ def test_object_to_timespec(self):
959983
self.create_converter(SEC_TO_NS),
960984
value_filter=self.time_t_filter)
961985

986+
# test nan
987+
for time_rnd, _ in ROUNDING_MODES:
988+
with self.assertRaises(ValueError):
989+
pytime_object_to_timespec(float('nan'), time_rnd)
990+
962991

963992
if __name__ == "__main__":
964993
unittest.main()

Python/pytime.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,
133133

134134
if (PyFloat_Check(obj)) {
135135
double d = PyFloat_AsDouble(obj);
136+
if (Py_IS_NAN(d)) {
137+
*numerator = 0;
138+
PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
139+
return -1;
140+
}
136141
return _PyTime_DoubleToDenominator(d, sec, numerator,
137142
denominator, round);
138143
}
@@ -154,6 +159,11 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
154159
volatile double d;
155160

156161
d = PyFloat_AsDouble(obj);
162+
if (Py_IS_NAN(d)) {
163+
PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
164+
return -1;
165+
}
166+
157167
d = _PyTime_Round(d, round);
158168
(void)modf(d, &intpart);
159169

@@ -301,6 +311,10 @@ _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
301311
if (PyFloat_Check(obj)) {
302312
double d;
303313
d = PyFloat_AsDouble(obj);
314+
if (Py_IS_NAN(d)) {
315+
PyErr_SetString(PyExc_ValueError, "Invalid value NaN (not a number)");
316+
return -1;
317+
}
304318
return _PyTime_FromFloatObject(t, d, round, unit_to_ns);
305319
}
306320
else {

0 commit comments

Comments
 (0)