mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-43762: Add audit events for loading of sqlite3 extensions (GH-25246)
This commit is contained in:
parent
52cd6d5e1b
commit
7244c0060d
7 changed files with 86 additions and 0 deletions
|
@ -225,6 +225,7 @@ Module functions and constants
|
||||||
be found in the `SQLite URI documentation <https://www.sqlite.org/uri.html>`_.
|
be found in the `SQLite URI documentation <https://www.sqlite.org/uri.html>`_.
|
||||||
|
|
||||||
.. audit-event:: sqlite3.connect database sqlite3.connect
|
.. audit-event:: sqlite3.connect database sqlite3.connect
|
||||||
|
.. audit-event:: sqlite3.connect/handle connection_handle sqlite3.connect
|
||||||
|
|
||||||
.. versionchanged:: 3.4
|
.. versionchanged:: 3.4
|
||||||
Added the *uri* parameter.
|
Added the *uri* parameter.
|
||||||
|
@ -232,6 +233,9 @@ Module functions and constants
|
||||||
.. versionchanged:: 3.7
|
.. versionchanged:: 3.7
|
||||||
*database* can now also be a :term:`path-like object`, not only a string.
|
*database* can now also be a :term:`path-like object`, not only a string.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.10
|
||||||
|
Added the ``sqlite3.connect/handle`` auditing event.
|
||||||
|
|
||||||
|
|
||||||
.. function:: register_converter(typename, callable)
|
.. function:: register_converter(typename, callable)
|
||||||
|
|
||||||
|
@ -467,8 +471,13 @@ Connection Objects
|
||||||
|
|
||||||
Loadable extensions are disabled by default. See [#f1]_.
|
Loadable extensions are disabled by default. See [#f1]_.
|
||||||
|
|
||||||
|
.. audit-event:: sqlite3.enable_load_extension connection,enabled sqlite3.enable_load_extension
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. versionchanged:: 3.10
|
||||||
|
Added the ``sqlite3.enable_load_extension`` auditing event.
|
||||||
|
|
||||||
.. literalinclude:: ../includes/sqlite3/load_extension.py
|
.. literalinclude:: ../includes/sqlite3/load_extension.py
|
||||||
|
|
||||||
.. method:: load_extension(path)
|
.. method:: load_extension(path)
|
||||||
|
@ -479,8 +488,13 @@ Connection Objects
|
||||||
|
|
||||||
Loadable extensions are disabled by default. See [#f1]_.
|
Loadable extensions are disabled by default. See [#f1]_.
|
||||||
|
|
||||||
|
.. audit-event:: sqlite3.load_extension connection,path sqlite3.load_extension
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
.. versionchanged:: 3.10
|
||||||
|
Added the ``sqlite3.load_extension`` auditing event.
|
||||||
|
|
||||||
.. attribute:: row_factory
|
.. attribute:: row_factory
|
||||||
|
|
||||||
You can change this attribute to a callable that accepts the cursor and the
|
You can change this attribute to a callable that accepts the cursor and the
|
||||||
|
|
|
@ -1080,6 +1080,14 @@ ssl
|
||||||
Add a *timeout* parameter to the :func:`ssl.get_server_certificate` function.
|
Add a *timeout* parameter to the :func:`ssl.get_server_certificate` function.
|
||||||
(Contributed by Zackery Spytz in :issue:`31870`.)
|
(Contributed by Zackery Spytz in :issue:`31870`.)
|
||||||
|
|
||||||
|
sqlite3
|
||||||
|
-------
|
||||||
|
|
||||||
|
Add audit events for :func:`~sqlite3.connect/handle`,
|
||||||
|
:meth:`~sqlite3.Connection.enable_load_extension`, and
|
||||||
|
:meth:`~sqlite3.Connection.load_extension`.
|
||||||
|
(Contributed by Erlend E. Aasland in :issue:`43762`.)
|
||||||
|
|
||||||
sys
|
sys
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -359,6 +359,27 @@ def test_http_client():
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
def test_sqlite3():
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
def hook(event, *args):
|
||||||
|
if event.startswith("sqlite3."):
|
||||||
|
print(event, *args)
|
||||||
|
|
||||||
|
sys.addaudithook(hook)
|
||||||
|
cx = sqlite3.connect(":memory:")
|
||||||
|
|
||||||
|
# Configured without --enable-loadable-sqlite-extensions
|
||||||
|
if hasattr(sqlite3.Connection, "enable_load_extension"):
|
||||||
|
cx.enable_load_extension(False)
|
||||||
|
try:
|
||||||
|
cx.load_extension("test")
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Expected sqlite3.load_extension to fail")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from test.support import suppress_msvcrt_asserts
|
from test.support import suppress_msvcrt_asserts
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,7 @@ class AuditTest(unittest.TestCase):
|
||||||
["gc.get_objects", "gc.get_referrers", "gc.get_referents"]
|
["gc.get_objects", "gc.get_referrers", "gc.get_referents"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_http(self):
|
def test_http(self):
|
||||||
import_helper.import_module("http.client")
|
import_helper.import_module("http.client")
|
||||||
returncode, events, stderr = self.run_python("test_http_client")
|
returncode, events, stderr = self.run_python("test_http_client")
|
||||||
|
@ -145,5 +146,27 @@ class AuditTest(unittest.TestCase):
|
||||||
self.assertIn('HTTP', events[1][2])
|
self.assertIn('HTTP', events[1][2])
|
||||||
|
|
||||||
|
|
||||||
|
def test_sqlite3(self):
|
||||||
|
try:
|
||||||
|
import sqlite3
|
||||||
|
except ImportError:
|
||||||
|
return
|
||||||
|
returncode, events, stderr = self.run_python("test_sqlite3")
|
||||||
|
if returncode:
|
||||||
|
self.fail(stderr)
|
||||||
|
|
||||||
|
if support.verbose:
|
||||||
|
print(*events, sep='\n')
|
||||||
|
actual = [ev[0] for ev in events]
|
||||||
|
expected = ["sqlite3.connect", "sqlite3.connect/handle"]
|
||||||
|
|
||||||
|
if hasattr(sqlite3.Connection, "enable_load_extension"):
|
||||||
|
expected += [
|
||||||
|
"sqlite3.enable_load_extension",
|
||||||
|
"sqlite3.load_extension",
|
||||||
|
]
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Add audit events for :func:`sqlite3.connect/handle`,
|
||||||
|
:meth:`sqlite3.Connection.enable_load_extension`, and
|
||||||
|
:meth:`sqlite3.Connection.load_extension`. Patch by Erlend E. Aasland.
|
|
@ -1154,6 +1154,11 @@ pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self,
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (PySys_Audit("sqlite3.enable_load_extension",
|
||||||
|
"OO", self, onoff ? Py_True : Py_False) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1185,6 +1190,10 @@ pysqlite_connection_load_extension_impl(pysqlite_Connection *self,
|
||||||
int rc;
|
int rc;
|
||||||
char* errmsg;
|
char* errmsg;
|
||||||
|
|
||||||
|
if (PySys_Audit("sqlite3.load_extension", "Os", self, extension_name) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,14 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
|
||||||
}
|
}
|
||||||
|
|
||||||
result = PyObject_Call(factory, args, kwargs);
|
result = PyObject_Call(factory, args, kwargs);
|
||||||
|
if (result == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PySys_Audit("sqlite3.connect/handle", "O", self) < 0) {
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue