From 067d6d46575b5cf30bbf7c812defee1517106a34 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 4 Jun 2021 11:54:39 -0700 Subject: bpo-43853: Handle sqlite3_value_text() errors (GH-25422) (cherry picked from commit 006fd869e4798b68e266f5de89c83ddb531a756b) Co-authored-by: Erlend Egeberg Aasland --- Lib/sqlite3/test/userfunctions.py | 12 +++++++----- .../Library/2021-04-15-12-02-17.bpo-43853.XXCVAp.rst | 3 +++ Modules/_sqlite/connection.c | 19 +++++++++++-------- 3 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-04-15-12-02-17.bpo-43853.XXCVAp.rst diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 148d9f5..6f57d19 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -236,9 +236,11 @@ class FunctionTests(unittest.TestCase): def test_param_string(self): cur = self.con.cursor() - cur.execute("select isstring(?)", ("foo",)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) + for text in ["foo", str()]: + with self.subTest(text=text): + cur.execute("select isstring(?)", (text,)) + val = cur.fetchone()[0] + self.assertEqual(val, 1) def test_param_int(self): cur = self.con.cursor() @@ -391,9 +393,9 @@ class AggregateTests(unittest.TestCase): def test_aggr_check_param_str(self): cur = self.con.cursor() - cur.execute("select checkType('str', ?)", ("foo",)) + cur.execute("select checkTypes('str', ?, ?)", ("foo", str())) val = cur.fetchone()[0] - self.assertEqual(val, 1) + self.assertEqual(val, 2) def test_aggr_check_param_int(self): cur = self.con.cursor() diff --git a/Misc/NEWS.d/next/Library/2021-04-15-12-02-17.bpo-43853.XXCVAp.rst b/Misc/NEWS.d/next/Library/2021-04-15-12-02-17.bpo-43853.XXCVAp.rst new file mode 100644 index 0000000..c5c3a0a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-04-15-12-02-17.bpo-43853.XXCVAp.rst @@ -0,0 +1,3 @@ +Improve :mod:`sqlite3` error handling: ``sqlite3_value_text()`` 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 e124b17..fccffab 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -576,7 +576,6 @@ _pysqlite_build_py_params(sqlite3_context *context, int argc, int i; sqlite3_value* cur_value; PyObject* cur_py_value; - const char* val_str; args = PyTuple_New(argc); if (!args) { @@ -592,15 +591,19 @@ _pysqlite_build_py_params(sqlite3_context *context, int argc, case SQLITE_FLOAT: cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value)); break; - case SQLITE_TEXT: - val_str = (const char*)sqlite3_value_text(cur_value); - cur_py_value = PyUnicode_FromString(val_str); - /* TODO: have a way to show errors here */ - if (!cur_py_value) { - PyErr_Clear(); - cur_py_value = Py_NewRef(Py_None); + case SQLITE_TEXT: { + sqlite3 *db = sqlite3_context_db_handle(context); + const char *text = (const char *)sqlite3_value_text(cur_value); + + if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) { + PyErr_NoMemory(); + goto error; } + + Py_ssize_t size = sqlite3_value_bytes(cur_value); + cur_py_value = PyUnicode_FromStringAndSize(text, size); break; + } case SQLITE_BLOB: { sqlite3 *db = sqlite3_context_db_handle(context); const void *blob = sqlite3_value_blob(cur_value); -- cgit v0.12