mirror of
https://github.com/simonw/datasette.git
synced 2026-06-24 01:34:41 +02:00
escape_sqlite() favors double quotes, closes #2795
This commit is contained in:
parent
39f1df5997
commit
22ccd8a087
2 changed files with 24 additions and 11 deletions
|
|
@ -410,12 +410,7 @@ def escape_css_string(s):
|
|||
def escape_sqlite(s):
|
||||
if _boring_keyword_re.match(s) and (s.lower() not in reserved_words):
|
||||
return s
|
||||
elif "]" in s:
|
||||
# SQLite does not support escaping ] inside [bracket] quoting, so fall
|
||||
# back to double-quote quoting (doubling any embedded ") - #2677
|
||||
return '"{}"'.format(s.replace('"', '""'))
|
||||
else:
|
||||
return f"[{s}]"
|
||||
return '"{}"'.format(s.replace('"', '""'))
|
||||
|
||||
|
||||
def make_dockerfile(
|
||||
|
|
|
|||
|
|
@ -221,11 +221,10 @@ def test_detect_fts(open_quote, close_quote):
|
|||
"identifier,expected",
|
||||
(
|
||||
("plain", "plain"),
|
||||
("select", "[select]"),
|
||||
("has space", "[has space]"),
|
||||
("has'quote", "[has'quote]"),
|
||||
# Identifiers containing ] must fall back to double-quote quoting
|
||||
# (SQLite does not support escaping ] inside [brackets]) - #2677
|
||||
("select", '"select"'),
|
||||
("has space", '"has space"'),
|
||||
("has'quote", '"has\'quote"'),
|
||||
('has"dquote', '"has""dquote"'),
|
||||
("has]bracket", '"has]bracket"'),
|
||||
('has"dquote]', '"has""dquote]"'),
|
||||
),
|
||||
|
|
@ -234,6 +233,25 @@ def test_escape_sqlite(identifier, expected):
|
|||
assert utils.escape_sqlite(identifier) == expected
|
||||
|
||||
|
||||
def test_escape_sqlite_double_quotes_work_in_query():
|
||||
conn = utils.sqlite3.connect(":memory:")
|
||||
table = 'table with "double quotes"'
|
||||
column = "select"
|
||||
escaped_table = utils.escape_sqlite(table)
|
||||
escaped_column = utils.escape_sqlite(column)
|
||||
conn.execute(f"CREATE TABLE {escaped_table} ({escaped_column} TEXT)")
|
||||
create_sql = conn.execute(
|
||||
"SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?", (table,)
|
||||
).fetchone()[0]
|
||||
assert create_sql == 'CREATE TABLE "table with ""double quotes""" ("select" TEXT)'
|
||||
conn.execute(
|
||||
f"INSERT INTO {escaped_table} ({escaped_column}) VALUES (?)", ("hello",)
|
||||
)
|
||||
results = conn.execute(f"SELECT {escaped_column} FROM {escaped_table}").fetchall()
|
||||
conn.close()
|
||||
assert results == [("hello",)]
|
||||
|
||||
|
||||
def test_escape_sqlite_prevents_injection():
|
||||
# https://github.com/simonw/datasette/issues/2677
|
||||
conn = utils.sqlite3.connect(":memory:")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue