Skip to content

Commit 067d6d4

Browse files
miss-islingtonErlend Egeberg Aasland
and
Erlend Egeberg Aasland
authored
bpo-43853: Handle sqlite3_value_text() errors (GH-25422)
(cherry picked from commit 006fd86) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
1 parent 3f4d801 commit 067d6d4

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

Lib/sqlite3/test/userfunctions.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,11 @@ def test_func_exception(self):
236236

237237
def test_param_string(self):
238238
cur = self.con.cursor()
239-
cur.execute("select isstring(?)", ("foo",))
240-
val = cur.fetchone()[0]
241-
self.assertEqual(val, 1)
239+
for text in ["foo", str()]:
240+
with self.subTest(text=text):
241+
cur.execute("select isstring(?)", (text,))
242+
val = cur.fetchone()[0]
243+
self.assertEqual(val, 1)
242244

243245
def test_param_int(self):
244246
cur = self.con.cursor()
@@ -391,9 +393,9 @@ def test_aggr_exception_in_finalize(self):
391393

392394
def test_aggr_check_param_str(self):
393395
cur = self.con.cursor()
394-
cur.execute("select checkType('str', ?)", ("foo",))
396+
cur.execute("select checkTypes('str', ?, ?)", ("foo", str()))
395397
val = cur.fetchone()[0]
396-
self.assertEqual(val, 1)
398+
self.assertEqual(val, 2)
397399

398400
def test_aggr_check_param_int(self):
399401
cur = self.con.cursor()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Improve :mod:`sqlite3` error handling: ``sqlite3_value_text()`` errors that
2+
set ``SQLITE_NOMEM`` now raise :exc:`MemoryError`. Patch by Erlend E.
3+
Aasland.

Modules/_sqlite/connection.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,6 @@ _pysqlite_build_py_params(sqlite3_context *context, int argc,
576576
int i;
577577
sqlite3_value* cur_value;
578578
PyObject* cur_py_value;
579-
const char* val_str;
580579

581580
args = PyTuple_New(argc);
582581
if (!args) {
@@ -592,15 +591,19 @@ _pysqlite_build_py_params(sqlite3_context *context, int argc,
592591
case SQLITE_FLOAT:
593592
cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
594593
break;
595-
case SQLITE_TEXT:
596-
val_str = (const char*)sqlite3_value_text(cur_value);
597-
cur_py_value = PyUnicode_FromString(val_str);
598-
/* TODO: have a way to show errors here */
599-
if (!cur_py_value) {
600-
PyErr_Clear();
601-
cur_py_value = Py_NewRef(Py_None);
594+
case SQLITE_TEXT: {
595+
sqlite3 *db = sqlite3_context_db_handle(context);
596+
const char *text = (const char *)sqlite3_value_text(cur_value);
597+
598+
if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) {
599+
PyErr_NoMemory();
600+
goto error;
602601
}
602+
603+
Py_ssize_t size = sqlite3_value_bytes(cur_value);
604+
cur_py_value = PyUnicode_FromStringAndSize(text, size);
603605
break;
606+
}
604607
case SQLITE_BLOB: {
605608
sqlite3 *db = sqlite3_context_db_handle(context);
606609
const void *blob = sqlite3_value_blob(cur_value);

0 commit comments

Comments
 (0)