Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-40956: [regression] first argument in sqlite3.Connection.backup is mandatory #24503

Merged
merged 4 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from all 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,3 @@
Fix segfault in :meth:`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