diff options
author | 2021-02-11 00:04:02 +0100 | |
---|---|---|
committer | 2021-02-11 01:04:02 +0200 | |
commit | ea46579067fd2d4e164d6605719ffec690c4d621 (patch) | |
tree | 0c47f143e62973981cdb7c8ae46afe5e75bafae9 | |
parent | Fix link to sqlite3 enable_shared_cache documentation (GH-24496) (diff) | |
download | cpython-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.py | 4 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-02-10-23-29-50.bpo-40956.LcAbwG.rst | 3 | ||||
-rw-r--r-- | Modules/_sqlite/clinic/connection.c.h | 29 | ||||
-rw-r--r-- | Modules/_sqlite/connection.c | 4 |
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; |