From f6d0f9bd38207ded24ab3ee41e3e0d85be31b338 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Thu, 3 Sep 2026 14:36:41 -0700 Subject: [PATCH] detect_fts() now uses parameterized SQL Refs GHSA-jcvx-2fh3-pjfp Co-authored-by: Alex Garcia <15178711+asg017@users.noreply.github.com> --- datasette/utils/__init__.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/datasette/utils/__init__.py b/datasette/utils/__init__.py index eb46d549..47e3be27 100644 --- a/datasette/utils/__init__.py +++ b/datasette/utils/__init__.py @@ -820,7 +820,8 @@ def detect_spatialite(conn): def detect_fts(conn, table): """Detect if table has a corresponding FTS virtual table and return it""" - rows = conn.execute(detect_fts_sql(table)).fetchall() + sql, params = detect_fts_sql(table) + rows = conn.execute(sql, params).fetchall() if len(rows) == 0: return None else: @@ -828,18 +829,25 @@ def detect_fts(conn, table): def detect_fts_sql(table): - return r""" - select name from sqlite_master - where rootpage = 0 - and ( - sql like '%VIRTUAL TABLE%USING FTS%content="{table}"%' - or sql like '%VIRTUAL TABLE%USING FTS%content=[{table}]%' - or ( - tbl_name = "{table}" - and sql like '%VIRTUAL TABLE%USING FTS%' + return ( + r""" + select name from sqlite_master + where rootpage = 0 + and ( + sql like :fts_double_quoted + or sql like :fts_bracket_quoted + or ( + tbl_name = :table + and sql like '%VIRTUAL TABLE%USING FTS%' + ) ) - ) - """.format(table=table.replace("'", "''")) + """, + { + "fts_double_quoted": f'%VIRTUAL TABLE%USING FTS%content="{table}"%', + "fts_bracket_quoted": f"%VIRTUAL TABLE%USING FTS%content=[{table}]%", + "table": table, + }, + ) def detect_json1(conn=None):