如何为SQLite FTS查询转义字符串

11
我正在尝试对不受信任的用户输入执行SQLite FTS查询。我不想让用户访问查询语法,也就是说他们将无法执行像foo OR bar AND cats这样的匹配查询。如果他们尝试使用该字符串进行查询,我希望将其解释为更像foo \OR bar \AND cats的内容。
SQLite内部似乎没有为此构建任何内容,因此我可能最终会自己构建转义函数,但这似乎很危险并且容易出错。有没有更好的方法来做到这一点?
2个回答

10
FTS MATCH语法是一种独立的小语言。对于FTS5,原样字符串文字已经被很好地定义: 在FTS表达式中,可以通过以下两种方式之一指定字符串:
- 用双引号("")括起来。在字符串中,可以通过添加第二个双引号字符来转义任何嵌入的双引号字符。 - (已编辑特殊情况)
事实证明,为FTS查询正确转义字符串足够简单,完全可靠:将“”替换为“”并在两端加上“”即可。
在我的情况下,当我将它放入准备好的语句中时,它能完美地工作,例如“SELECT stuff FROM fts_table WHERE fts_table MATCH ?”。然后我会使用“fts_escape(user_input).bind”其中“fts_escape”是我上面描述的函数。

1
当我从FTS4迁移到FTS5时,我注意到一个有趣的事情,我不得不将形式为“hyphenated-wor”的某些内容更改为“hyphenated-wor”。然而,做类似于MATCH ? || '*'这样的操作会更好吗? - Mark
这是一个更好的 fts_escape 函数,它可以处理连字符单词:" ".join(f'"{x}"' for x in query.replace("-", " ").split(" ")) - Polor Beer

4

好的,我进一步调查了一下,通过一些高级技巧,您可以访问SQLite FTS使用的实际分词器。 "简单"分词器接受您的字符串,将其分隔为不在[A-Za-z0-0]中的任何字符,并将剩余部分转换为小写字母。 如果您执行相同的操作,则会获得一个适用于FTS的漂亮的“转义”字符串。

您可以编写自己的分词器,但也可以访问SQLite的内部分词器。 有关详细信息,请参见此问题:Automatic OR queries using SQLite FTS4


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接