|
3 | 3 | # file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
4 | 4 |
|
5 | 5 | import os
|
| 6 | +import struct |
6 | 7 | import sys
|
7 | 8 | import unittest
|
8 | 9 |
|
@@ -137,6 +138,45 @@ def test_sqlite(self):
|
137 | 138 | cursor.execute(
|
138 | 139 | f"CREATE VIRTUAL TABLE test{extension} USING {extension}(a, b, c);"
|
139 | 140 | )
|
| 141 | + |
| 142 | + # Test various SQLite flags and features requested / expected by users. |
| 143 | + # The DBSTAT virtual table shows some metadata about disk usage. |
| 144 | + # https://www.sqlite.org/dbstat.html |
| 145 | + self.assertNotEqual( |
| 146 | + cursor.execute("SELECT COUNT(*) FROM dbstat;").fetchone()[0], |
| 147 | + 0, |
| 148 | + ) |
| 149 | + |
| 150 | + # The serialize/deserialize API is configurable at compile time. |
| 151 | + if sys.version_info[0:2] >= (3, 11): |
| 152 | + self.assertEqual(conn.serialize()[:15], b"SQLite format 3") |
| 153 | + |
| 154 | + # The "enhanced query syntax" (-DSQLITE_ENABLE_FTS3_PARENTHESIS) allows parenthesizable |
| 155 | + # AND, OR, and NOT operations. The "standard query syntax" only has OR as a keyword, so we |
| 156 | + # can test for the difference with a query using AND. |
| 157 | + # https://www.sqlite.org/fts3.html#_set_operations_using_the_enhanced_query_syntax |
| 158 | + cursor.execute("INSERT INTO testfts3 VALUES('hello world', '', '');") |
| 159 | + self.assertEqual( |
| 160 | + cursor.execute( |
| 161 | + "SELECT COUNT(*) FROM testfts3 WHERE a MATCH 'hello AND world';" |
| 162 | + ).fetchone()[0], |
| 163 | + 1, |
| 164 | + ) |
| 165 | + |
| 166 | + # fts3_tokenizer() takes/returns native pointers. Newer SQLite versions require the use of |
| 167 | + # bound parameters with this function to avoid the risk of a SQL injection esclating into a |
| 168 | + # full RCE. This requirement can be disabled at either compile time or runtime for |
| 169 | + # backwards compatibility. Ensure that the check is enabled (more secure) by default but |
| 170 | + # applications can still use fts3_tokenize with a bound parameter. See discussion at |
| 171 | + # https://github.com/astral-sh/python-build-standalone/pull/562#issuecomment-3254522958 |
| 172 | + wild_pointer = struct.pack("P", 0xDEADBEEF) |
| 173 | + with self.assertRaises(sqlite3.OperationalError) as caught: |
| 174 | + cursor.execute( |
| 175 | + f"SELECT fts3_tokenizer('mytokenizer', x'{wild_pointer.hex()}')" |
| 176 | + ) |
| 177 | + self.assertEqual(str(caught.exception), "fts3tokenize disabled") |
| 178 | + cursor.execute("SELECT fts3_tokenizer('mytokenizer', ?)", (wild_pointer,)) |
| 179 | + |
140 | 180 | conn.close()
|
141 | 181 |
|
142 | 182 | def test_ssl(self):
|
|
0 commit comments