Skip to content

Commit a4baf1c

Browse files
miss-islingtonMariatta
authored andcommitted
[3.6] bpo-26669: Fix nan arg value error in pytime.c (GH-3085) (GH-3467)
* Modify NaN check function and error message * Fix pytime.c when arg is nan * fix whitespace (cherry picked from commit 829dacc)
1 parent 3892799 commit a4baf1c

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
@@ -489,6 +489,10 @@ def test_localtime_failure(self):
489489
self.assertRaises(OSError, time.localtime, invalid_time_t)
490490
self.assertRaises(OSError, time.ctime, invalid_time_t)
491491

492+
# Issue #26669: check for localtime() failure
493+
self.assertRaises(ValueError, time.localtime, float("nan"))
494+
self.assertRaises(ValueError, time.ctime, float("nan"))
495+
492496
def test_get_clock_info(self):
493497
clocks = ['clock', 'perf_counter', 'process_time', 'time']
494498
if hasattr(time, 'monotonic'):
@@ -823,6 +827,11 @@ def c_int_filter(secs):
823827
lambda secs: secs * SEC_TO_NS,
824828
value_filter=c_int_filter)
825829

830+
# test nan
831+
for time_rnd, _ in ROUNDING_MODES:
832+
with self.assertRaises(TypeError):
833+
PyTime_FromSeconds(float('nan'))
834+
826835
def test_FromSecondsObject(self):
827836
from _testcapi import PyTime_FromSecondsObject
828837

@@ -834,6 +843,11 @@ def test_FromSecondsObject(self):
834843
PyTime_FromSecondsObject,
835844
lambda ns: self.decimal_round(ns * SEC_TO_NS))
836845

846+
# test nan
847+
for time_rnd, _ in ROUNDING_MODES:
848+
with self.assertRaises(ValueError):
849+
PyTime_FromSecondsObject(float('nan'), time_rnd)
850+
837851
def test_AsSecondsDouble(self):
838852
from _testcapi import PyTime_AsSecondsDouble
839853

@@ -847,6 +861,11 @@ def float_converter(ns):
847861
float_converter,
848862
NS_TO_SEC)
849863

864+
# test nan
865+
for time_rnd, _ in ROUNDING_MODES:
866+
with self.assertRaises(TypeError):
867+
PyTime_AsSecondsDouble(float('nan'))
868+
850869
def create_decimal_converter(self, denominator):
851870
denom = decimal.Decimal(denominator)
852871

@@ -952,6 +971,11 @@ def test_object_to_timeval(self):
952971
self.create_converter(SEC_TO_US),
953972
value_filter=self.time_t_filter)
954973

974+
# test nan
975+
for time_rnd, _ in ROUNDING_MODES:
976+
with self.assertRaises(ValueError):
977+
pytime_object_to_timeval(float('nan'), time_rnd)
978+
955979
def test_object_to_timespec(self):
956980
from _testcapi import pytime_object_to_timespec
957981

@@ -963,6 +987,11 @@ def test_object_to_timespec(self):
963987
self.create_converter(SEC_TO_NS),
964988
value_filter=self.time_t_filter)
965989

990+
# test nan
991+
for time_rnd, _ in ROUNDING_MODES:
992+
with self.assertRaises(ValueError):
993+
pytime_object_to_timespec(float('nan'), time_rnd)
994+
966995

967996
if __name__ == "__main__":
968997
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)