Skip to content

Commit deada95

Browse files
committed
Update function parameter types to always be PyObject *
Standard Python dev practice has been to use the "subclass" C type for the self parameter. The methods are called with PyObject * as the type. This does not cause any problems. Except control flow integrity is now available. It requires that the types and parameters of a called function match exactly, and if not will fail. clangs undefined sanitizer warns about these. CPython fixed their own calls in 3.14 - see python/cpython#111178 This large change corrects the self parameter to PyObject * and then casts to the useful type in the body. It also adds the various unused closure parameters. It won't cause any code generation changes. Refs #498
1 parent e19b6aa commit deada95

11 files changed

Lines changed: 708 additions & 471 deletions

File tree

src/apsw.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ static int allow_missing_dict_bindings = 0;
273273
*/
274274

275275
static PyObject *
276-
get_sqlite_version(void)
276+
get_sqlite_version(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
277277
{
278278
return PyUnicode_FromString(sqlite3_libversion());
279279
}
@@ -287,7 +287,7 @@ get_sqlite_version(void)
287287
*/
288288

289289
static PyObject *
290-
get_sqlite3_sourceid(void)
290+
get_sqlite3_sourceid(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
291291
{
292292
return PyUnicode_FromString(sqlite3_sourceid());
293293
}
@@ -297,7 +297,7 @@ get_sqlite3_sourceid(void)
297297
Returns the APSW version.
298298
*/
299299
static PyObject *
300-
get_apsw_version(void)
300+
get_apsw_version(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
301301
{
302302
return PyUnicode_FromString(APSW_VERSION);
303303
}
@@ -340,7 +340,7 @@ enable_shared_cache(PyObject *Py_UNUSED(self), PyObject *const *fast_args, Py_ss
340340
*/
341341
static PyObject *the_connections;
342342
static PyObject *
343-
apsw_connections(PyObject *Py_UNUSED(self))
343+
apsw_connections(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
344344
{
345345
Py_ssize_t i;
346346
PyObject *res = PyList_New(0), *item = NULL;
@@ -408,7 +408,7 @@ apsw_connection_add(Connection *con)
408408
*/
409409

410410
static PyObject *
411-
initialize(void)
411+
initialize(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
412412
{
413413
int res;
414414

@@ -435,7 +435,7 @@ static void free_fork_checker(void);
435435
#endif
436436

437437
static PyObject *
438-
sqliteshutdown(void)
438+
sqliteshutdown(PyObject *Py_UNUSED(unused1), PyObject *Py_UNUSED(unused2))
439439
{
440440
int res;
441441

@@ -623,7 +623,7 @@ apsw_config(PyObject *Py_UNUSED(self), PyObject *args)
623623
-* sqlite3_memory_used
624624
*/
625625
static PyObject *
626-
memory_used(void)
626+
memory_used(PyObject *Py_UNUSED(unused1), PyObject *Py_UNUSED(unused2))
627627
{
628628
return PyLong_FromLongLong(sqlite3_memory_used());
629629
}
@@ -805,7 +805,7 @@ status(PyObject *Py_UNUSED(self), PyObject *const *fast_args, Py_ssize_t fast_na
805805
-* sqlite3_vfs_find
806806
*/
807807
static PyObject *
808-
vfs_names(PyObject *Py_UNUSED(self))
808+
vfs_names(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
809809
{
810810
PyObject *result = NULL, *str = NULL;
811811
int res;
@@ -866,7 +866,7 @@ Pointers are converted using :c:func:`PyLong_FromVoidPtr`.
866866
-* sqlite3_vfs_find
867867
*/
868868
static PyObject *
869-
vfs_details(PyObject *Py_UNUSED(self))
869+
vfs_details(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
870870
{
871871
PyObject *result, *dict;
872872
sqlite3_vfs *vfs = sqlite3_vfs_find(0);
@@ -1008,7 +1008,7 @@ apswcomplete(PyObject *Py_UNUSED(self), PyObject *const *fast_args, Py_ssize_t f
10081008

10091009
#if defined(APSW_DEBUG) || defined(APSW_FAULT_INJECT)
10101010
static PyObject *
1011-
apsw_fini(PyObject *Py_UNUSED(self))
1011+
apsw_fini(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(unused))
10121012
{
10131013
fini_apsw_strings();
10141014
Py_RETURN_NONE;
@@ -1811,13 +1811,13 @@ apsw_getattr(PyObject *Py_UNUSED(module), PyObject *name)
18111811

18121812
static PyMethodDef module_methods[] = {
18131813
{ "sqlite3_sourceid", (PyCFunction)get_sqlite3_sourceid, METH_NOARGS, Apsw_sqlite3_sourceid_DOC },
1814-
{ "sqlite_lib_version", (PyCFunction)get_sqlite_version, METH_NOARGS, Apsw_sqlite_lib_version_DOC },
1815-
{ "apsw_version", (PyCFunction)get_apsw_version, METH_NOARGS, Apsw_apsw_version_DOC },
1814+
{ "sqlite_lib_version", get_sqlite_version, METH_NOARGS, Apsw_sqlite_lib_version_DOC },
1815+
{ "apsw_version", get_apsw_version, METH_NOARGS, Apsw_apsw_version_DOC },
18161816
{ "vfs_names", (PyCFunction)vfs_names, METH_NOARGS, Apsw_vfs_names_DOC },
18171817
{ "vfs_details", (PyCFunction)vfs_details, METH_NOARGS, Apsw_vfs_details_DOC },
18181818
{ "enable_shared_cache", (PyCFunction)enable_shared_cache, METH_FASTCALL | METH_KEYWORDS,
18191819
Apsw_enable_shared_cache_DOC },
1820-
{ "initialize", (PyCFunction)initialize, METH_NOARGS, Apsw_initialize_DOC },
1820+
{ "initialize", initialize, METH_NOARGS, Apsw_initialize_DOC },
18211821
{ "shutdown", (PyCFunction)sqliteshutdown, METH_NOARGS, Apsw_shutdown_DOC },
18221822
{ "format_sql_value", (PyCFunction)formatsqlvalue, METH_O, Apsw_format_sql_value_DOC },
18231823
{ "config", (PyCFunction)apsw_config, METH_VARARGS, Apsw_config_DOC },
@@ -1900,11 +1900,11 @@ PyInit_apsw(void)
19001900
|| PyType_Ready(&APSWFTS5TokenizerType) < 0 || PyType_Ready(&APSWFTS5ExtensionAPIType) < 0
19011901
|| PyType_Ready(&PyObjectBindType) < 0
19021902
#ifdef SQLITE_ENABLE_SESSION
1903-
|| PyType_Ready(&APSWSessionType) <0 || PyType_Ready(&APSWTableChangeType) <0
1904-
|| PyType_Ready(&APSWChangesetType) <0 || PyType_Ready(&APSWChangesetBuilderType) <0
1905-
|| PyType_Ready(&APSWChangesetIteratorType) <0 || PyType_Ready(&APSWRebaserType) <0
1903+
|| PyType_Ready(&APSWSessionType) < 0 || PyType_Ready(&APSWTableChangeType) < 0
1904+
|| PyType_Ready(&APSWChangesetType) < 0 || PyType_Ready(&APSWChangesetBuilderType) < 0
1905+
|| PyType_Ready(&APSWChangesetIteratorType) < 0 || PyType_Ready(&APSWRebaserType) < 0
19061906
#endif
1907-
)
1907+
)
19081908
goto fail;
19091909

19101910
/* PyStructSequence_NewType is broken in some Pythons

src/apsw.docstrings

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3666,6 +3666,13 @@
36663666
"\n" \
36673667
"Calls: `sqlite3session_changeset <https://sqlite.org/session/sqlite3session_changeset.html>`__\n"
36683668

3669+
#define Session_changeset_KWNAMES NULL
3670+
#define Session_changeset_USAGE "Session.changeset() -> bytes"
3671+
3672+
#define Session_changeset_CHECK do { \
3673+
} while(0)
3674+
3675+
36693676
#define Session_changeset_size_DOC ":type: int\n" \
36703677
"\n" \
36713678
"Returns upper limit on changeset size, but only if :meth:`Session.config`\n" \
@@ -3783,6 +3790,13 @@
37833790
"\n" \
37843791
"Calls: `sqlite3session_patchset <https://sqlite.org/session/sqlite3session_patchset.html>`__\n"
37853792

3793+
#define Session_patchset_KWNAMES NULL
3794+
#define Session_patchset_USAGE "Session.patchset() -> bytes"
3795+
3796+
#define Session_patchset_CHECK do { \
3797+
} while(0)
3798+
3799+
37863800
#define Session_patchset_stream_DOC "patchset_stream($self,output)\n--\n\nSession.patchset_stream(output: SessionStreamOutput) -> None\n\n" \
37873801
"Produces a patchset of the session so far in a stream\n" \
37883802
"\n" \

src/backup.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ APSWBackup_close_internal(APSWBackup *self, int force)
118118
}
119119

120120
static void
121-
APSWBackup_dealloc(APSWBackup *self)
121+
APSWBackup_dealloc(PyObject *self_)
122122
{
123+
APSWBackup *self = (APSWBackup *)self_;
123124
APSW_CLEAR_WEAKREFS;
124125

125126
if (self->backup)
@@ -152,8 +153,9 @@ APSWBackup_dealloc(APSWBackup *self)
152153
-* sqlite3_backup_step
153154
*/
154155
static PyObject *
155-
APSWBackup_step(APSWBackup *self, PyObject *const *fast_args, Py_ssize_t fast_nargs, PyObject *fast_kwnames)
156+
APSWBackup_step(PyObject *self_, PyObject *const *fast_args, Py_ssize_t fast_nargs, PyObject *fast_kwnames)
156157
{
158+
APSWBackup *self = (APSWBackup *)self_;
157159
int npages = -1, res;
158160

159161
CHECK_BACKUP_CLOSED(NULL);
@@ -206,8 +208,9 @@ APSWBackup_step(APSWBackup *self, PyObject *const *fast_args, Py_ssize_t fast_na
206208
-* sqlite3_backup_finish
207209
*/
208210
static PyObject *
209-
APSWBackup_finish(APSWBackup *self)
211+
APSWBackup_finish(PyObject *self_, PyObject *Py_UNUSED(unused))
210212
{
213+
APSWBackup *self = (APSWBackup *)self_;
211214
int setexc;
212215

213216
/* We handle CHECK_BACKUP_CLOSED internally */
@@ -233,8 +236,9 @@ APSWBackup_finish(APSWBackup *self)
233236
:param force: If true then any exceptions are ignored.
234237
*/
235238
static PyObject *
236-
APSWBackup_close(APSWBackup *self, PyObject *const *fast_args, Py_ssize_t fast_nargs, PyObject *fast_kwnames)
239+
APSWBackup_close(PyObject *self_, PyObject *const *fast_args, Py_ssize_t fast_nargs, PyObject *fast_kwnames)
237240
{
241+
APSWBackup *self = (APSWBackup *)self_;
238242
int force = 0, setexc;
239243

240244
/* We handle CHECK_BACKUP_CLOSED internally */
@@ -266,9 +270,9 @@ APSWBackup_close(APSWBackup *self, PyObject *const *fast_args, Py_ssize_t fast_n
266270
-* sqlite3_backup_remaining
267271
*/
268272
static PyObject *
269-
APSWBackup_get_remaining(APSWBackup *self, void *Py_UNUSED(ignored))
273+
APSWBackup_get_remaining(PyObject *self_, void *Py_UNUSED(ignored))
270274
{
271-
275+
APSWBackup *self = (APSWBackup *)self_;
272276
return PyLong_FromLong(self->backup ? sqlite3_backup_remaining(self->backup) : 0);
273277
}
274278

@@ -283,9 +287,9 @@ APSWBackup_get_remaining(APSWBackup *self, void *Py_UNUSED(ignored))
283287
-* sqlite3_backup_pagecount
284288
*/
285289
static PyObject *
286-
APSWBackup_get_page_count(APSWBackup *self, void *Py_UNUSED(ignored))
290+
APSWBackup_get_page_count(PyObject *self_, void *Py_UNUSED(ignored))
287291
{
288-
292+
APSWBackup *self = (APSWBackup *)self_;
289293
return PyLong_FromLong(self->backup ? sqlite3_backup_pagecount(self->backup) : 0);
290294
}
291295

@@ -297,12 +301,12 @@ APSWBackup_get_page_count(APSWBackup *self, void *Py_UNUSED(ignored))
297301
is :meth:`finished <Backup.finish>`.
298302
*/
299303
static PyObject *
300-
APSWBackup_enter(APSWBackup *self)
304+
APSWBackup_enter(PyObject *self_, PyObject *Py_UNUSED(ignored))
301305
{
302-
306+
APSWBackup *self = (APSWBackup *)self_;
303307
CHECK_BACKUP_CLOSED(NULL);
304308

305-
return Py_NewRef((PyObject *)self);
309+
return Py_NewRef(self_);
306310
}
307311

308312
/** .. method:: __exit__(etype: Optional[type[BaseException]], evalue: Optional[BaseException], etraceback: Optional[types.TracebackType]) -> Optional[bool]
@@ -311,8 +315,9 @@ APSWBackup_enter(APSWBackup *self)
311315
that the copy is :meth:`finished <Backup.finish>`.
312316
*/
313317
static PyObject *
314-
APSWBackup_exit(APSWBackup *self, PyObject *const *fast_args, Py_ssize_t fast_nargs, PyObject *fast_kwnames)
318+
APSWBackup_exit(PyObject *self_, PyObject *const *fast_args, Py_ssize_t fast_nargs, PyObject *fast_kwnames)
315319
{
320+
APSWBackup *self = (APSWBackup *)self_;
316321
PyObject *etype, *evalue, *etraceback;
317322
int setexc;
318323

@@ -347,8 +352,9 @@ APSWBackup_exit(APSWBackup *self, PyObject *const *fast_args, Py_ssize_t fast_na
347352
}
348353

349354
static PyObject *
350-
APSWBackup_tp_str(APSWBackup *self)
355+
APSWBackup_tp_str(PyObject *self_)
351356
{
357+
APSWBackup *self = (APSWBackup *)self_;
352358
return PyUnicode_FromFormat("<apsw.Backup object from %S to %S at %p>",
353359
self->source ? (PyObject *)self->source : apst.closed,
354360
self->dest ? (PyObject *)self->dest : apst.closed, self);

0 commit comments

Comments
 (0)