bpo-45754: Use correct SQLite limit when checking statement length (GH-29489)

This commit is contained in:
Erlend Egeberg Aasland 2021-11-10 19:46:11 +01:00 committed by GitHub
parent 4cdeee5978
commit c1323d4b8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 11 deletions

View file

@ -55,7 +55,7 @@ def memory_database():
# Temporarily limit a database connection parameter # Temporarily limit a database connection parameter
@contextlib.contextmanager @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: try:
_prev = cx.setlimit(category, limit) _prev = cx.setlimit(category, limit)
yield limit yield limit
@ -495,7 +495,7 @@ class ConnectionTests(unittest.TestCase):
prev_limit = self.cx.setlimit(category, new_limit) prev_limit = self.cx.setlimit(category, new_limit)
self.assertEqual(saved_limit, prev_limit) self.assertEqual(saved_limit, prev_limit)
self.assertEqual(self.cx.getlimit(category), new_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.assertRaisesRegex(sqlite.DataError, msg,
self.cx.execute, "select 1 as '16'") self.cx.execute, "select 1 as '16'")
finally: # restore saved limit finally: # restore saved limit
@ -1063,9 +1063,9 @@ class ExtensionTests(unittest.TestCase):
def test_cursor_executescript_too_large_script(self): def test_cursor_executescript_too_large_script(self):
msg = "query string is too large" msg = "query string is too large"
with memory_database() as cx, cx_limit(cx) as lim: 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): 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): def test_cursor_executescript_tx_control(self):
con = sqlite.connect(":memory:") con = sqlite.connect(":memory:")

View file

@ -362,11 +362,11 @@ class RegressionTests(unittest.TestCase):
with memory_database() as cx, cx_limit(cx) as lim: with memory_database() as cx, cx_limit(cx) as lim:
cu = cx.cursor() 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 # 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, cx, sql)
self.assertRaisesRegex(sqlite.DataError, msg, cu.execute, sql) self.assertRaisesRegex(sqlite.DataError, msg, cu.execute, sql)

View file

@ -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.

View file

@ -729,8 +729,8 @@ pysqlite_cursor_executescript_impl(pysqlite_Cursor *self,
size_t sql_len = strlen(sql_script); size_t sql_len = strlen(sql_script);
int max_length = sqlite3_limit(self->connection->db, int max_length = sqlite3_limit(self->connection->db,
SQLITE_LIMIT_LENGTH, -1); SQLITE_LIMIT_SQL_LENGTH, -1);
if (sql_len >= (unsigned)max_length) { if (sql_len > (unsigned)max_length) {
PyErr_SetString(self->connection->DataError, PyErr_SetString(self->connection->DataError,
"query string is too large"); "query string is too large");
return NULL; return NULL;

View file

@ -60,8 +60,8 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
} }
sqlite3 *db = connection->db; sqlite3 *db = connection->db;
int max_length = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1); int max_length = sqlite3_limit(db, SQLITE_LIMIT_SQL_LENGTH, -1);
if (size >= max_length) { if (size > max_length) {
PyErr_SetString(connection->DataError, PyErr_SetString(connection->DataError,
"query string is too large"); "query string is too large");
return NULL; return NULL;