aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-02-11 00:04:02 +0100
committerGitHub <noreply@github.com>2021-02-11 01:04:02 +0200
commitea46579067fd2d4e164d6605719ffec690c4d621 (patch)
tree0c47f143e62973981cdb7c8ae46afe5e75bafae9
parentFix link to sqlite3 enable_shared_cache documentation (GH-24496) (diff)
downloadcpython-ea46579067fd2d4e164d6605719ffec690c4d621.tar.gz
cpython-ea46579067fd2d4e164d6605719ffec690c4d621.tar.bz2
cpython-ea46579067fd2d4e164d6605719ffec690c4d621.zip
bpo-40956: Fix segfault when Connection.backup is called without target (GH-24503)
-rw-r--r--Lib/sqlite3/test/backup.py4
-rw-r--r--Misc/NEWS.d/next/Library/2021-02-10-23-29-50.bpo-40956.LcAbwG.rst3
-rw-r--r--Modules/_sqlite/clinic/connection.c.h29
-rw-r--r--Modules/_sqlite/connection.c4
4 files changed, 18 insertions, 22 deletions
diff --git a/Lib/sqlite3/test/backup.py b/Lib/sqlite3/test/backup.py
index ddff78c760..cbe24df2e9 100644
--- a/Lib/sqlite3/test/backup.py
+++ b/Lib/sqlite3/test/backup.py
@@ -17,9 +17,11 @@ class BackupTests(unittest.TestCase):
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):
diff --git a/Misc/NEWS.d/next/Library/2021-02-10-23-29-50.bpo-40956.LcAbwG.rst b/Misc/NEWS.d/next/Library/2021-02-10-23-29-50.bpo-40956.LcAbwG.rst
new file mode 100644
index 0000000000..e81922c031
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-02-10-23-29-50.bpo-40956.LcAbwG.rst
@@ -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.
diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h
index 01b8e37a95..f231ecc2ae 100644
--- a/Modules/_sqlite/clinic/connection.c.h
+++ b/Modules/_sqlite/clinic/connection.c.h
@@ -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.");
@@ -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;
}
@@ -719,4 +710,4 @@ exit:
#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]*/
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 370dc1a30e..63fcb0055d 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -1582,7 +1582,7 @@ finally:
/*[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
@@ -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;