我正在尝试使用不受信任的用户输入执行 SQLite FTS 查询。我不想让用户访问查询语法,即他们将无法执行匹配查询,例如foo OR bar AND cats
. 如果他们尝试使用该字符串进行查询,我希望将其解释为更像foo \OR bar \AND cats
.
SQLite 似乎没有为此内置任何东西,所以我可能最终会构建自己的转义函数,但这似乎很危险且容易出错。有没有首选的方法来做到这一点?
我正在尝试使用不受信任的用户输入执行 SQLite FTS 查询。我不想让用户访问查询语法,即他们将无法执行匹配查询,例如foo OR bar AND cats
. 如果他们尝试使用该字符串进行查询,我希望将其解释为更像foo \OR bar \AND cats
.
SQLite 似乎没有为此内置任何东西,所以我可能最终会构建自己的转义函数,但这似乎很危险且容易出错。有没有首选的方法来做到这一点?
FTS MATCH 语法是它自己的小语言。对于 FTS5,逐字字符串文字定义明确:
在 FTS 表达式中,可以通过以下两种方式之一指定字符串:
通过将其括在双引号 (") 中。在字符串中,任何嵌入的双引号字符都可以通过 SQL 样式进行转义 - 通过添加第二个双引号字符。
(编辑特殊情况)
事实证明,为 FTS 查询正确转义字符串非常简单,可以完全可靠地实现:在两端"
替换""
并包含结果。"
就我而言,当我将其放入准备好的语句(例如SELECT stuff FROM fts_table WHERE fts_table MATCH ?
. 然后我想我上面描述的功能.bind(fts_escape(user_input))
在哪里。fts_escape
好的,我已经进行了进一步调查,并且通过一些强大的魔法,您可以访问 SQLite 的 FTS 使用的实际标记器。“简单”标记器获取您的字符串,将其分隔为不在 [A-Za-z0-0] 中的任何字符,并将其余字符小写。如果您执行相同的操作,您将得到一个适合 FTS 的很好的“转义”字符串。
您可以自己编写,但您也可以访问 SQLite 的内部代码。有关详细信息,请参阅此问题:Automatic OR queries using SQLite FTS4