mirror of
https://github.com/python/cpython.git
synced 2025-12-04 00:30:19 +00:00
bpo-40956: Fix segfault when Connection.backup is called without target (GH-24503)
This commit is contained in:
parent
749d40a53f
commit
ea46579067
4 changed files with 18 additions and 22 deletions
|
|
@ -17,9 +17,11 @@ class BackupTests(unittest.TestCase):
|
||||||
self.assertEqual(result[0][0], 3)
|
self.assertEqual(result[0][0], 3)
|
||||||
self.assertEqual(result[1][0], 4)
|
self.assertEqual(result[1][0], 4)
|
||||||
|
|
||||||
def test_bad_target_none(self):
|
def test_bad_target(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
self.cx.backup(None)
|
self.cx.backup(None)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
self.cx.backup()
|
||||||
|
|
||||||
def test_bad_target_filename(self):
|
def test_bad_target_filename(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -519,8 +519,8 @@ pysqlite_connection_iterdump(pysqlite_Connection *self, PyObject *Py_UNUSED(igno
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(pysqlite_connection_backup__doc__,
|
PyDoc_STRVAR(pysqlite_connection_backup__doc__,
|
||||||
"backup($self, /, target=<unrepresentable>, *, pages=-1, progress=None,\n"
|
"backup($self, /, target, *, pages=-1, progress=None, name=\'main\',\n"
|
||||||
" name=\'main\', sleep=0.25)\n"
|
" sleep=0.25)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Makes a backup of the database. Non-standard.");
|
"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 const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL};
|
||||||
static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0};
|
static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0};
|
||||||
PyObject *argsbuf[5];
|
PyObject *argsbuf[5];
|
||||||
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
|
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
|
||||||
pysqlite_Connection *target = NULL;
|
pysqlite_Connection *target;
|
||||||
int pages = -1;
|
int pages = -1;
|
||||||
PyObject *progress = Py_None;
|
PyObject *progress = Py_None;
|
||||||
const char *name = "main";
|
const char *name = "main";
|
||||||
double sleep = 0.25;
|
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) {
|
if (!args) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (!noptargs) {
|
if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) {
|
||||||
goto skip_optional_pos;
|
_PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]);
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
if (args[0]) {
|
target = (pysqlite_Connection *)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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
skip_optional_pos:
|
|
||||||
if (!noptargs) {
|
if (!noptargs) {
|
||||||
goto skip_optional_kwonly;
|
goto skip_optional_kwonly;
|
||||||
}
|
}
|
||||||
|
|
@ -719,4 +710,4 @@ exit:
|
||||||
#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
|
#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
|
||||||
#define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
|
#define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
|
||||||
#endif /* !defined(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]*/
|
||||||
|
|
|
||||||
|
|
@ -1582,7 +1582,7 @@ finally:
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_sqlite3.Connection.backup as pysqlite_connection_backup
|
_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
|
pages: int = -1
|
||||||
progress: object = None
|
progress: object = None
|
||||||
|
|
@ -1597,7 +1597,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
|
||||||
pysqlite_Connection *target, int pages,
|
pysqlite_Connection *target, int pages,
|
||||||
PyObject *progress, const char *name,
|
PyObject *progress, const char *name,
|
||||||
double sleep)
|
double sleep)
|
||||||
/*[clinic end generated code: output=306a3e6a38c36334 input=2f3497ea530144b1]*/
|
/*[clinic end generated code: output=306a3e6a38c36334 input=30ae45fc420bfd3b]*/
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int callback_error = 0;
|
int callback_error = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue