diff options
author | Erlend Egeberg Aasland <erlend.aasland@protonmail.com> | 2022-05-02 14:14:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-02 14:14:35 (GMT) |
commit | 721aa96540bb96700f8c4bab0b4095b43491dca1 (patch) | |
tree | e57e4f90905ab72a7387273d2adffd27d6356757 /Modules | |
parent | 6811bdef63d4f3af6ff901d324556cf8954575a7 (diff) | |
download | cpython-721aa96540bb96700f8c4bab0b4095b43491dca1.zip cpython-721aa96540bb96700f8c4bab0b4095b43491dca1.tar.gz cpython-721aa96540bb96700f8c4bab0b4095b43491dca1.tar.bz2 |
gh-89301: Fix regression with bound values in traced SQLite statements (#92053)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_sqlite/connection.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 0028cf7..fe244c8 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1332,11 +1332,10 @@ progress_callback(void *ctx) * to ensure future compatibility. */ static int -trace_callback(unsigned int type, void *ctx, void *prepared_statement, - void *statement_string) +trace_callback(unsigned int type, void *ctx, void *stmt, void *sql) #else static void -trace_callback(void *ctx, const char *statement_string) +trace_callback(void *ctx, const char *sql) #endif { #ifdef HAVE_TRACE_V2 @@ -1347,24 +1346,51 @@ trace_callback(void *ctx, const char *statement_string) PyGILState_STATE gilstate = PyGILState_Ensure(); - PyObject *py_statement = NULL; - PyObject *ret = NULL; - py_statement = PyUnicode_DecodeUTF8(statement_string, - strlen(statement_string), "replace"); assert(ctx != NULL); + pysqlite_state *state = ((callback_context *)ctx)->state; + assert(state != NULL); + + PyObject *py_statement = NULL; +#ifdef HAVE_TRACE_V2 + const char *expanded_sql = sqlite3_expanded_sql((sqlite3_stmt *)stmt); + if (expanded_sql == NULL) { + sqlite3 *db = sqlite3_db_handle((sqlite3_stmt *)stmt); + if (sqlite3_errcode(db) == SQLITE_NOMEM) { + (void)PyErr_NoMemory(); + goto exit; + } + + PyErr_SetString(state->DataError, + "Expanded SQL string exceeds the maximum string length"); + print_or_clear_traceback((callback_context *)ctx); + + // Fall back to unexpanded sql + py_statement = PyUnicode_FromString((const char *)sql); + } + else { + py_statement = PyUnicode_FromString(expanded_sql); + sqlite3_free((void *)expanded_sql); + } +#else + if (sql == NULL) { + PyErr_SetString(state->DataError, + "Expanded SQL string exceeds the maximum string length"); + print_or_clear_traceback((callback_context *)ctx); + goto exit; + } + py_statement = PyUnicode_FromString(sql); +#endif if (py_statement) { PyObject *callable = ((callback_context *)ctx)->callable; - ret = PyObject_CallOneArg(callable, py_statement); + PyObject *ret = PyObject_CallOneArg(callable, py_statement); Py_DECREF(py_statement); + Py_XDECREF(ret); } - - if (ret) { - Py_DECREF(ret); - } - else { - print_or_clear_traceback(ctx); + if (PyErr_Occurred()) { + print_or_clear_traceback((callback_context *)ctx); } +exit: PyGILState_Release(gilstate); #ifdef HAVE_TRACE_V2 return 0; |