Skip to content

Commit d20458c

Browse files
authored
Merge pull request #384 from python/master
bpo-40956: Fix segfault when Connection.backup is called without targ…
2 parents b823218 + ea46579 commit d20458c

File tree

4 files changed

+18
-22
lines changed

4 files changed

+18
-22
lines changed

Diff for: Lib/sqlite3/test/backup.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ def verify_backup(self, bckcx):
1717
self.assertEqual(result[0][0], 3)
1818
self.assertEqual(result[1][0], 4)
1919

20-
def test_bad_target_none(self):
20+
def test_bad_target(self):
2121
with self.assertRaises(TypeError):
2222
self.cx.backup(None)
23+
with self.assertRaises(TypeError):
24+
self.cx.backup()
2325

2426
def test_bad_target_filename(self):
2527
with self.assertRaises(TypeError):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix segfault in :meth:`sqlite3.Connection.backup` if no argument was
2+
provided. The regression was introduced by GH-23838. Patch by
3+
Erlend E. Aasland.

Diff for: Modules/_sqlite/clinic/connection.c.h

+10-19
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,8 @@ pysqlite_connection_iterdump(pysqlite_Connection *self, PyObject *Py_UNUSED(igno
519519
}
520520

521521
PyDoc_STRVAR(pysqlite_connection_backup__doc__,
522-
"backup($self, /, target=<unrepresentable>, *, pages=-1, progress=None,\n"
523-
" name=\'main\', sleep=0.25)\n"
522+
"backup($self, /, target, *, pages=-1, progress=None, name=\'main\',\n"
523+
" sleep=0.25)\n"
524524
"--\n"
525525
"\n"
526526
"Makes a backup of the database. Non-standard.");
@@ -541,31 +541,22 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_
541541
static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL};
542542
static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0};
543543
PyObject *argsbuf[5];
544-
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
545-
pysqlite_Connection *target = NULL;
544+
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
545+
pysqlite_Connection *target;
546546
int pages = -1;
547547
PyObject *progress = Py_None;
548548
const char *name = "main";
549549
double sleep = 0.25;
550550

551-
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
551+
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
552552
if (!args) {
553553
goto exit;
554554
}
555-
if (!noptargs) {
556-
goto skip_optional_pos;
557-
}
558-
if (args[0]) {
559-
if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) {
560-
_PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]);
561-
goto exit;
562-
}
563-
target = (pysqlite_Connection *)args[0];
564-
if (!--noptargs) {
565-
goto skip_optional_pos;
566-
}
555+
if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) {
556+
_PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]);
557+
goto exit;
567558
}
568-
skip_optional_pos:
559+
target = (pysqlite_Connection *)args[0];
569560
if (!noptargs) {
570561
goto skip_optional_kwonly;
571562
}
@@ -719,4 +710,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss
719710
#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
720711
#define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
721712
#endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */
722-
/*[clinic end generated code: output=7cb13d491a5970aa input=a9049054013a1b77]*/
713+
/*[clinic end generated code: output=c1bf09db3bcd0105 input=a9049054013a1b77]*/

Diff for: Modules/_sqlite/connection.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1582,7 +1582,7 @@ pysqlite_connection_iterdump_impl(pysqlite_Connection *self)
15821582
/*[clinic input]
15831583
_sqlite3.Connection.backup as pysqlite_connection_backup
15841584
1585-
target: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType') = NULL
1585+
target: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType')
15861586
*
15871587
pages: int = -1
15881588
progress: object = None
@@ -1597,7 +1597,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
15971597
pysqlite_Connection *target, int pages,
15981598
PyObject *progress, const char *name,
15991599
double sleep)
1600-
/*[clinic end generated code: output=306a3e6a38c36334 input=2f3497ea530144b1]*/
1600+
/*[clinic end generated code: output=306a3e6a38c36334 input=30ae45fc420bfd3b]*/
16011601
{
16021602
int rc;
16031603
int callback_error = 0;

0 commit comments

Comments
 (0)