]> granicus.if.org Git - python/commitdiff
Issue #22117: Fix usage of _PyTime_AsTimeval()
authorVictor Stinner <victor.stinner@gmail.com>
Mon, 30 Mar 2015 00:51:13 +0000 (02:51 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Mon, 30 Mar 2015 00:51:13 +0000 (02:51 +0200)
Add _PyTime_AsTimeval_noraise() function. Call it when it's not possible (or
not useful) to raise a Python exception on overflow.

Include/pytime.h
Modules/_ssl.c
Modules/_testcapimodule.c
Modules/socketmodule.c
Modules/timemodule.c
Python/pytime.c

index b8727748a0f82dffe95c9a226ceba8b16f4b9d0f..f14e1fc6fde5063e0076aad00a7f94547f8a0685 100644 (file)
@@ -94,11 +94,17 @@ PyAPI_FUNC(PyObject *) _PyTime_AsNanosecondsObject(_PyTime_t t);
 
 /* Convert a timestamp to a timeval structure (microsecond resolution).
    tv_usec is always positive.
-   Return -1 if the conversion overflowed, return 0 on success. */
+   Raise an exception and return -1 if the conversion overflowed,
+   return 0 on success. */
 PyAPI_FUNC(int) _PyTime_AsTimeval(_PyTime_t t,
     struct timeval *tv,
     _PyTime_round_t round);
 
+/* Similar to _PyTime_AsTimeval(), but don't raise an exception on error. */
+PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t,
+    struct timeval *tv,
+    _PyTime_round_t round);
+
 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
 /* Convert a timestamp to a timespec structure (nanosecond resolution).
    tv_nsec is always positive.
index 54f5d140ed474b7eb4e2672f13549e99d6887edc..217c77c5933d3f29dc0a36d76452568b6c795c66 100644 (file)
@@ -1651,9 +1651,7 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
     if (!_PyIsSelectable_fd(s->sock_fd))
         return SOCKET_TOO_LARGE_FOR_SELECT;
 
-    /* conversion was already checked for overflow when
-       the timeout was set */
-    (void)_PyTime_AsTimeval(s->sock_timeout, &tv, _PyTime_ROUND_UP);
+    _PyTime_AsTimeval_noraise(s->sock_timeout, &tv, _PyTime_ROUND_UP);
 
     FD_ZERO(&fds);
     FD_SET(s->sock_fd, &fds);
index 9abb7ccd1955d6a3c584d765100478d280959439..128ba094b2ee9aff185958b8ffd95915393209de 100644 (file)
@@ -3427,11 +3427,8 @@ test_PyTime_AsTimeval(PyObject *self, PyObject *args)
     if (check_time_rounding(round) < 0)
         return NULL;
     t = _PyTime_FromNanoseconds(ns);
-    if (_PyTime_AsTimeval(t, &tv, round) < 0) {
-        PyErr_SetString(PyExc_OverflowError,
-                        "timeout doesn't fit into C timeval");
+    if (_PyTime_AsTimeval(t, &tv, round) < 0)
         return NULL;
-    }
 
     seconds = PyLong_FromLong((PY_LONG_LONG)tv.tv_sec);
     if (seconds == NULL)
index 93dcd419481d1688e399612fcee7903000e07df8..513405e507a5d4eb837b6cc9837f96c79f9f21df 100644 (file)
@@ -641,9 +641,7 @@ internal_select_ex(PySocketSockObject *s, int writing, _PyTime_t interval)
     n = poll(&pollfd, 1, timeout_int);
     Py_END_ALLOW_THREADS;
 #else
-    /* conversion was already checked for overflow when
-       the timeout was set */
-    (void)_PyTime_AsTimeval(interval, &tv, _PyTime_ROUND_UP);
+    _PyTime_AsTimeval_noraise(interval, &tv, _PyTime_ROUND_UP);
 
     FD_ZERO(&fds);
     FD_SET(s->sock_fd, &fds);
@@ -2454,9 +2452,7 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
         struct timeval tv;
         int conv;
 
-        /* conversion was already checked for overflow when
-           the timeout was set */
-        (void)_PyTime_AsTimeval(s->sock_timeout, &tv, _PyTime_ROUND_UP);
+        _PyTime_AsTimeval_noraise(s->sock_timeout, &tv, _PyTime_ROUND_UP);
 
         Py_BEGIN_ALLOW_THREADS
         FD_ZERO(&fds);
index 99e83cc6dc055c42d5f8c85b1baf0427b62a87cf..3ed3fb31bdc696b499c1ca717898d057fad75d82 100644 (file)
@@ -1405,11 +1405,8 @@ pysleep(_PyTime_t secs)
 
     do {
 #ifndef MS_WINDOWS
-        if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_UP) < 0) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "delay doesn't fit into C timeval");
+        if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_UP) < 0)
             return -1;
-        }
 
         Py_BEGIN_ALLOW_THREADS
         err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
index 2bf6ba5cf28587b4d9b3fd438db9cdaa87e2ade3..a7eda869a07ec07cd5591a70f17838da3344fdfa 100644 (file)
@@ -311,8 +311,9 @@ _PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
     return _PyTime_Multiply(t, 1000 * 1000, round);
 }
 
-int
-_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
+static int
+_PyTime_AsTimeval_impl(_PyTime_t t, struct timeval *tv, _PyTime_round_t round,
+                       int raise)
 {
     _PyTime_t secs, ns;
     int res = 0;
@@ -357,9 +358,23 @@ _PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
         tv->tv_sec += 1;
     }
 
+    if (res && raise)
+        _PyTime_overflow();
     return res;
 }
 
+int
+_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
+{
+    return _PyTime_AsTimeval_impl(t, tv, round, 1);
+}
+
+int
+_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
+{
+    return _PyTime_AsTimeval_impl(t, tv, round, 0);
+}
+
 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
 int
 _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)