[Python-checkins] [3.9] bpo-43853: Handle sqlite3_value_text() errors (GH-25422). (GH-27627)
serhiy-storchaka
webhook-mailer at python.org
Fri Aug 6 13:57:47 EDT 2021
https://github.com/python/cpython/commit/8c07fef867707694c9f2fcee4d7a9563ad78ed14
commit: 8c07fef867707694c9f2fcee4d7a9563ad78ed14
branch: 3.9
author: Erlend Egeberg Aasland <erlend.aasland at innova.no>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2021-08-06T20:57:39+03:00
summary:
[3.9] bpo-43853: Handle sqlite3_value_text() errors (GH-25422). (GH-27627)
(cherry picked from commit 006fd869e4798b68e266f5de89c83ddb531a756b)
files:
A Misc/NEWS.d/next/Library/2021-04-15-12-02-17.bpo-43853.XXCVAp.rst
M Lib/sqlite3/test/userfunctions.py
M Modules/_sqlite/connection.c
diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py
index c11c82e1275778..a1c29d482366e4 100644
--- a/Lib/sqlite3/test/userfunctions.py
+++ b/Lib/sqlite3/test/userfunctions.py
@@ -236,9 +236,11 @@ def CheckFuncException(self):
def CheckParamString(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 CheckParamInt(self):
cur = self.con.cursor()
@@ -387,9 +389,9 @@ def CheckAggrExceptionInFinalize(self):
def CheckAggrCheckParamStr(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 CheckAggrCheckParamInt(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 00000000000000..c5c3a0ae83c7f4
--- /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 1cf31489d07f9f..986a82918b5fe8 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -546,7 +546,6 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
int i;
sqlite3_value* cur_value;
PyObject* cur_py_value;
- const char* val_str;
Py_ssize_t buflen;
args = PyTuple_New(argc);
@@ -563,16 +562,19 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
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();
- Py_INCREF(Py_None);
- cur_py_value = 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:
buflen = sqlite3_value_bytes(cur_value);
cur_py_value = PyBytes_FromStringAndSize(
@@ -585,8 +587,7 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
}
if (!cur_py_value) {
- Py_DECREF(args);
- return NULL;
+ goto error;
}
PyTuple_SetItem(args, i, cur_py_value);
@@ -594,6 +595,10 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
}
return args;
+
+error:
+ Py_DECREF(args);
+ return NULL;
}
void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
More information about the Python-checkins
mailing list