Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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)
  • Loading branch information
miss-islington authored and Mariatta committed Sep 9, 2017
1 parent 3892799 commit a4baf1c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
29 changes: 29 additions & 0 deletions Lib/test/test_time.py
Expand Up @@ -489,6 +489,10 @@ def test_localtime_failure(self):
self.assertRaises(OSError, time.localtime, 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):
clocks = ['clock', 'perf_counter', 'process_time', 'time']
if hasattr(time, 'monotonic'):
Expand Down Expand Up @@ -823,6 +827,11 @@ def c_int_filter(secs):
lambda secs: secs * SEC_TO_NS,
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):
from _testcapi import PyTime_FromSecondsObject

Expand All @@ -834,6 +843,11 @@ def test_FromSecondsObject(self):
PyTime_FromSecondsObject,
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):
from _testcapi import PyTime_AsSecondsDouble

Expand All @@ -847,6 +861,11 @@ def float_converter(ns):
float_converter,
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):
denom = decimal.Decimal(denominator)

Expand Down Expand Up @@ -952,6 +971,11 @@ def test_object_to_timeval(self):
self.create_converter(SEC_TO_US),
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):
from _testcapi import pytime_object_to_timespec

Expand All @@ -963,6 +987,11 @@ def test_object_to_timespec(self):
self.create_converter(SEC_TO_NS),
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__":
unittest.main()
14 changes: 14 additions & 0 deletions Python/pytime.c
Expand Up @@ -133,6 +133,11 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator,

if (PyFloat_Check(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,
denominator, round);
}
Expand All @@ -154,6 +159,11 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
volatile double d;

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);
(void)modf(d, &intpart);

Expand Down Expand Up @@ -301,6 +311,10 @@ _PyTime_FromObject(_PyTime_t *t, PyObject *obj, _PyTime_round_t round,
if (PyFloat_Check(obj)) {
double d;
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);
}
else {
Expand Down

0 comments on commit a4baf1c

Please sign in to comment.