From 5cb601f956886b32641f818b5da347cc86a43db2 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 14 Apr 2021 23:09:11 +0200 Subject: bpo-43296: Handle sqlite3_value_blob() errors (GH-24674) --- Lib/sqlite3/test/userfunctions.py | 4 ++++ .../2021-03-01-13-01-33.bpo-43296.p_gU6T.rst | 3 +++ Modules/_sqlite/connection.c | 24 +++++++++++++++------- 3 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-03-01-13-01-33.bpo-43296.p_gU6T.rst diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 749ea049c8..148d9f596a 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -276,6 +276,10 @@ class FunctionTests(unittest.TestCase): val = cur.fetchone()[0] self.assertEqual(val, 2) + def test_empty_blob(self): + cur = self.con.execute("select isblob(x'')") + self.assertTrue(cur.fetchone()[0]) + # Regarding deterministic functions: # # Between 3.8.3 and 3.15.0, deterministic functions were only used to diff --git a/Misc/NEWS.d/next/Library/2021-03-01-13-01-33.bpo-43296.p_gU6T.rst b/Misc/NEWS.d/next/Library/2021-03-01-13-01-33.bpo-43296.p_gU6T.rst new file mode 100644 index 0000000000..741dfcd705 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-03-01-13-01-33.bpo-43296.p_gU6T.rst @@ -0,0 +1,3 @@ +Improve :mod:`sqlite3` error handling: ``sqlite3_value_blob()`` errors that +set ``SQLITE_NOMEM`` now raise :exc:`MemoryError`. Patch by Erlend E. +Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 6d3ccb9b94..93365495f5 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -546,7 +546,6 @@ _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_value* cur_value; PyObject* cur_py_value; const char* val_str; - Py_ssize_t buflen; args = PyTuple_New(argc); if (!args) { @@ -571,19 +570,26 @@ _pysqlite_build_py_params(sqlite3_context *context, int argc, cur_py_value = Py_NewRef(Py_None); } break; - case SQLITE_BLOB: - buflen = sqlite3_value_bytes(cur_value); - cur_py_value = PyBytes_FromStringAndSize( - sqlite3_value_blob(cur_value), buflen); + case SQLITE_BLOB: { + sqlite3 *db = sqlite3_context_db_handle(context); + const void *blob = sqlite3_value_blob(cur_value); + + if (blob == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { + PyErr_NoMemory(); + goto error; + } + + Py_ssize_t size = sqlite3_value_bytes(cur_value); + cur_py_value = PyBytes_FromStringAndSize(blob, size); break; + } case SQLITE_NULL: default: cur_py_value = Py_NewRef(Py_None); } if (!cur_py_value) { - Py_DECREF(args); - return NULL; + goto error; } PyTuple_SetItem(args, i, cur_py_value); @@ -591,6 +597,10 @@ _pysqlite_build_py_params(sqlite3_context *context, int argc, } return args; + +error: + Py_DECREF(args); + return NULL; } static void -- cgit v1.2.1