From c1323d4b8cb010a06c11bace6e681bea7f895851 Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 10 Nov 2021 19:46:11 +0100 Subject: bpo-45754: Use correct SQLite limit when checking statement length (GH-29489) --- Lib/test/test_sqlite3/test_dbapi.py | 8 ++++---- Lib/test/test_sqlite3/test_regression.py | 6 +++--- Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst | 3 +++ Modules/_sqlite/cursor.c | 4 ++-- Modules/_sqlite/statement.c | 4 ++-- 5 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 6628eee..a5ec66f 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -55,7 +55,7 @@ def memory_database(): # Temporarily limit a database connection parameter @contextlib.contextmanager -def cx_limit(cx, category=sqlite.SQLITE_LIMIT_LENGTH, limit=128): +def cx_limit(cx, category=sqlite.SQLITE_LIMIT_SQL_LENGTH, limit=128): try: _prev = cx.setlimit(category, limit) yield limit @@ -495,7 +495,7 @@ class ConnectionTests(unittest.TestCase): prev_limit = self.cx.setlimit(category, new_limit) self.assertEqual(saved_limit, prev_limit) self.assertEqual(self.cx.getlimit(category), new_limit) - msg = "string or blob too big" + msg = "query string is too large" self.assertRaisesRegex(sqlite.DataError, msg, self.cx.execute, "select 1 as '16'") finally: # restore saved limit @@ -1063,9 +1063,9 @@ class ExtensionTests(unittest.TestCase): def test_cursor_executescript_too_large_script(self): msg = "query string is too large" with memory_database() as cx, cx_limit(cx) as lim: - cx.executescript("select 'almost too large'".ljust(lim-1)) + cx.executescript("select 'almost too large'".ljust(lim)) with self.assertRaisesRegex(sqlite.DataError, msg): - cx.executescript("select 'too large'".ljust(lim)) + cx.executescript("select 'too large'".ljust(lim+1)) def test_cursor_executescript_tx_control(self): con = sqlite.connect(":memory:") diff --git a/Lib/test/test_sqlite3/test_regression.py b/Lib/test/test_sqlite3/test_regression.py index 158f4cf..eb34069 100644 --- a/Lib/test/test_sqlite3/test_regression.py +++ b/Lib/test/test_sqlite3/test_regression.py @@ -362,11 +362,11 @@ class RegressionTests(unittest.TestCase): with memory_database() as cx, cx_limit(cx) as lim: cu = cx.cursor() - cx("select 1".ljust(lim-1)) + cx("select 1".ljust(lim)) # use a different SQL statement; don't reuse from the LRU cache - cu.execute("select 2".ljust(lim-1)) + cu.execute("select 2".ljust(lim)) - sql = "select 3".ljust(lim) + sql = "select 3".ljust(lim+1) self.assertRaisesRegex(sqlite.DataError, msg, cx, sql) self.assertRaisesRegex(sqlite.DataError, msg, cu.execute, sql) diff --git a/Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst b/Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst new file mode 100644 index 0000000..196bfc9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-11-09-15-48-38.bpo-45754.c-JDto.rst @@ -0,0 +1,3 @@ +Fix a regression in Python 3.11a1 and 3.11a2 where :mod:`sqlite3` +incorrectly would use ``SQLITE_LIMIT_LENGTH`` when checking SQL statement +lengths. Now, ``SQLITE_LIMIT_SQL_LENGTH`` is used. Patch by Erlend E. Aasland. diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 1d7c0b4..3ee1c5d 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -729,8 +729,8 @@ pysqlite_cursor_executescript_impl(pysqlite_Cursor *self, size_t sql_len = strlen(sql_script); int max_length = sqlite3_limit(self->connection->db, - SQLITE_LIMIT_LENGTH, -1); - if (sql_len >= (unsigned)max_length) { + SQLITE_LIMIT_SQL_LENGTH, -1); + if (sql_len > (unsigned)max_length) { PyErr_SetString(self->connection->DataError, "query string is too large"); return NULL; diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index b20c91d..66fadb6 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -60,8 +60,8 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) } sqlite3 *db = connection->db; - int max_length = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1); - if (size >= max_length) { + int max_length = sqlite3_limit(db, SQLITE_LIMIT_SQL_LENGTH, -1); + if (size > max_length) { PyErr_SetString(connection->DataError, "query string is too large"); return NULL; -- cgit v0.12