Skip to content

Commit 8c07fef

Browse files
author
Erlend Egeberg Aasland
authored
[3.9] bpo-43853: Handle sqlite3_value_text() errors (GH-25422). (GH-27627)
(cherry picked from commit 006fd86)
1 parent 8c17db6 commit 8c07fef

File tree

3 files changed

+26
-16
lines changed

3 files changed

+26
-16
lines changed

Lib/sqlite3/test/userfunctions.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,11 @@ def CheckFuncException(self):
236236

237237
def CheckParamString(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 CheckParamInt(self):
244246
cur = self.con.cursor()
@@ -387,9 +389,9 @@ def CheckAggrExceptionInFinalize(self):
387389

388390
def CheckAggrCheckParamStr(self):
389391
cur = self.con.cursor()
390-
cur.execute("select checkType('str', ?)", ("foo",))
392+
cur.execute("select checkTypes('str', ?, ?)", ("foo", str()))
391393
val = cur.fetchone()[0]
392-
self.assertEqual(val, 1)
394+
self.assertEqual(val, 2)
393395

394396
def CheckAggrCheckParamInt(self):
395397
cur = self.con.cursor()
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

+16-11
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,6 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
546546
int i;
547547
sqlite3_value* cur_value;
548548
PyObject* cur_py_value;
549-
const char* val_str;
550549
Py_ssize_t buflen;
551550

552551
args = PyTuple_New(argc);
@@ -563,16 +562,19 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
563562
case SQLITE_FLOAT:
564563
cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
565564
break;
566-
case SQLITE_TEXT:
567-
val_str = (const char*)sqlite3_value_text(cur_value);
568-
cur_py_value = PyUnicode_FromString(val_str);
569-
/* TODO: have a way to show errors here */
570-
if (!cur_py_value) {
571-
PyErr_Clear();
572-
Py_INCREF(Py_None);
573-
cur_py_value = Py_None;
565+
case SQLITE_TEXT: {
566+
sqlite3 *db = sqlite3_context_db_handle(context);
567+
const char *text = (const char *)sqlite3_value_text(cur_value);
568+
569+
if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) {
570+
PyErr_NoMemory();
571+
goto error;
574572
}
573+
574+
Py_ssize_t size = sqlite3_value_bytes(cur_value);
575+
cur_py_value = PyUnicode_FromStringAndSize(text, size);
575576
break;
577+
}
576578
case SQLITE_BLOB:
577579
buflen = sqlite3_value_bytes(cur_value);
578580
cur_py_value = PyBytes_FromStringAndSize(
@@ -585,15 +587,18 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
585587
}
586588

587589
if (!cur_py_value) {
588-
Py_DECREF(args);
589-
return NULL;
590+
goto error;
590591
}
591592

592593
PyTuple_SetItem(args, i, cur_py_value);
593594

594595
}
595596

596597
return args;
598+
599+
error:
600+
Py_DECREF(args);
601+
return NULL;
597602
}
598603

599604
void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)

0 commit comments

Comments
 (0)