diff options
author | Victor Stinner <vstinner@redhat.com> | 2018-04-30 10:22:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-30 10:22:17 (GMT) |
commit | ca405017d5e776a2e3d9291236e62d2e09489dd2 (patch) | |
tree | 54f7f13f52fde86c9ec8d89dd9a13c18a6ca3e72 /Modules/_sqlite/connection.c | |
parent | 5ff3a161c8a6b525c5e5b3e36e9c43f5a95bda60 (diff) | |
download | cpython-ca405017d5e776a2e3d9291236e62d2e09489dd2.zip cpython-ca405017d5e776a2e3d9291236e62d2e09489dd2.tar.gz cpython-ca405017d5e776a2e3d9291236e62d2e09489dd2.tar.bz2 |
bpo-27645, sqlite: Fix integer overflow on sleep (#6594)
Use the _PyTime_t type and round away from zero (ROUND_UP,
_PyTime_ROUND_TIMEOUT) the sleep duration, when converting a Python
object to seconds and then to milliseconds. Raise an OverflowError in
case of overflow.
Previously the (int)double conversion rounded towards zero
(ROUND_DOWN).
Diffstat (limited to 'Modules/_sqlite/connection.c')
-rw-r--r-- | Modules/_sqlite/connection.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 6e05761..ef2daeb 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1461,17 +1461,33 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * const char *name = "main"; int rc; int callback_error = 0; - double sleep_secs = 0.250; + PyObject *sleep_obj = NULL; + int sleep_ms = 250; sqlite3 *bck_conn; sqlite3_backup *bck_handle; static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsd:backup", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, &pysqlite_ConnectionType, &target, - &pages, &progress, &name, &sleep_secs)) { + &pages, &progress, &name, &sleep_obj)) { return NULL; } + if (sleep_obj != NULL) { + _PyTime_t sleep_secs; + if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj, + _PyTime_ROUND_TIMEOUT)) { + return NULL; + } + _PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs, + _PyTime_ROUND_TIMEOUT); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "sleep is too large"); + return NULL; + } + sleep_ms = (int)ms; + } + if (!pysqlite_check_connection((pysqlite_Connection *)target)) { return NULL; } @@ -1531,7 +1547,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * the engine could not make any progress */ if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { Py_BEGIN_ALLOW_THREADS - sqlite3_sleep(sleep_secs * 1000.0); + sqlite3_sleep(sleep_ms); Py_END_ALLOW_THREADS } } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); |