Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Lib/sqlite3/test/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ def verify_backup(self, bckcx):
self.assertEqual(result[0][0], 3)
self.assertEqual(result[1][0], 4)

def test_bad_target_none(self):
def test_bad_target(self):
with self.assertRaises(TypeError):
self.cx.backup(None)
with self.assertRaises(TypeError):
self.cx.backup()

def test_bad_target_filename(self):
with self.assertRaises(TypeError):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix segfault in ``sqlite3.Connection.backup`` if no argument was provided.
The regression was introduced by GH-23838. Patch by Erlend E. Aasland.
29 changes: 10 additions & 19 deletions Modules/_sqlite/clinic/connection.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,8 @@ pysqlite_connection_iterdump(pysqlite_Connection *self, PyObject *Py_UNUSED(igno
}

PyDoc_STRVAR(pysqlite_connection_backup__doc__,
"backup($self, /, target=<unrepresentable>, *, pages=-1, progress=None,\n"
" name=\'main\', sleep=0.25)\n"
"backup($self, /, target, *, pages=-1, progress=None, name=\'main\',\n"
" sleep=0.25)\n"
"--\n"
"\n"
"Makes a backup of the database. Non-standard.");
Expand All @@ -541,31 +541,22 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_
static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL};
static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0};
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
pysqlite_Connection *target = NULL;
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
pysqlite_Connection *target;
int pages = -1;
PyObject *progress = Py_None;
const char *name = "main";
double sleep = 0.25;

args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
if (!noptargs) {
goto skip_optional_pos;
}
if (args[0]) {
if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) {
_PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]);
goto exit;
}
target = (pysqlite_Connection *)args[0];
if (!--noptargs) {
goto skip_optional_pos;
}
if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) {
_PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]);
goto exit;
}
skip_optional_pos:
target = (pysqlite_Connection *)args[0];
if (!noptargs) {
goto skip_optional_kwonly;
}
Expand Down Expand Up @@ -719,4 +710,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss
#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
#define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
#endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */
/*[clinic end generated code: output=7cb13d491a5970aa input=a9049054013a1b77]*/
/*[clinic end generated code: output=c1bf09db3bcd0105 input=a9049054013a1b77]*/
4 changes: 2 additions & 2 deletions Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1582,7 +1582,7 @@ pysqlite_connection_iterdump_impl(pysqlite_Connection *self)
/*[clinic input]
_sqlite3.Connection.backup as pysqlite_connection_backup

target: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType') = NULL
target: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType')
*
pages: int = -1
progress: object = None
Expand All @@ -1597,7 +1597,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
pysqlite_Connection *target, int pages,
PyObject *progress, const char *name,
double sleep)
/*[clinic end generated code: output=306a3e6a38c36334 input=2f3497ea530144b1]*/
/*[clinic end generated code: output=306a3e6a38c36334 input=30ae45fc420bfd3b]*/
{
int rc;
int callback_error = 0;
Expand Down