]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-43853: Handle sqlite3_value_text() errors (GH-25422)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 4 Jun 2021 18:54:39 +0000 (11:54 -0700)
committerGitHub <noreply@github.com>
Fri, 4 Jun 2021 18:54:39 +0000 (11:54 -0700)
(cherry picked from commit 006fd869e4798b68e266f5de89c83ddb531a756b)

Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
Lib/sqlite3/test/userfunctions.py
Misc/NEWS.d/next/Library/2021-04-15-12-02-17.bpo-43853.XXCVAp.rst [new file with mode: 0644]
Modules/_sqlite/connection.c

index 148d9f596a91c8a0af12e5a1c09e7d773b7c00e1..6f57d1911b24d8cceeefe7d77b3f754f857bc0b8 100644 (file)
@@ -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 (file)
index 0000000..c5c3a0a
--- /dev/null
@@ -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.
index e124b17782dfe5f8817aee85cb84db1e7d09c090..fccffabc4b2a0b20015c4c27c8328598c312a992 100644 (file)
@@ -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);