Skip to content

Commit ca40501

Browse files
authored
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).
1 parent 5ff3a16 commit ca40501

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

Modules/_sqlite/connection.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,17 +1461,33 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *
14611461
const char *name = "main";
14621462
int rc;
14631463
int callback_error = 0;
1464-
double sleep_secs = 0.250;
1464+
PyObject *sleep_obj = NULL;
1465+
int sleep_ms = 250;
14651466
sqlite3 *bck_conn;
14661467
sqlite3_backup *bck_handle;
14671468
static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL};
14681469

1469-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsd:backup", keywords,
1470+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords,
14701471
&pysqlite_ConnectionType, &target,
1471-
&pages, &progress, &name, &sleep_secs)) {
1472+
&pages, &progress, &name, &sleep_obj)) {
14721473
return NULL;
14731474
}
14741475

1476+
if (sleep_obj != NULL) {
1477+
_PyTime_t sleep_secs;
1478+
if (_PyTime_FromSecondsObject(&sleep_secs, sleep_obj,
1479+
_PyTime_ROUND_TIMEOUT)) {
1480+
return NULL;
1481+
}
1482+
_PyTime_t ms = _PyTime_AsMilliseconds(sleep_secs,
1483+
_PyTime_ROUND_TIMEOUT);
1484+
if (ms < INT_MIN || ms > INT_MAX) {
1485+
PyErr_SetString(PyExc_OverflowError, "sleep is too large");
1486+
return NULL;
1487+
}
1488+
sleep_ms = (int)ms;
1489+
}
1490+
14751491
if (!pysqlite_check_connection((pysqlite_Connection *)target)) {
14761492
return NULL;
14771493
}
@@ -1531,7 +1547,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject *
15311547
the engine could not make any progress */
15321548
if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
15331549
Py_BEGIN_ALLOW_THREADS
1534-
sqlite3_sleep(sleep_secs * 1000.0);
1550+
sqlite3_sleep(sleep_ms);
15351551
Py_END_ALLOW_THREADS
15361552
}
15371553
} while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);

0 commit comments

Comments
 (0)