From 1849eba190b834a2c4eeaaf7e70f0987f0f1224f Mon Sep 17 00:00:00 2001 From: Albert S Date: Thu, 28 Jul 2022 15:10:03 +0200 Subject: [PATCH] shared: sqlitesearch: Escape FTS arguments Most users are not to be expected to be familiar with sqlite's FTS syntax. It also leads to unnnecessary arrows in some instances. So wrap every space separated word in quotes, unless it's already in quotes. Then we just escape those with double-quotes. --- shared/sqlitesearch.cpp | 26 ++++++++++++++++++++++++-- shared/sqlitesearch.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/shared/sqlitesearch.cpp b/shared/sqlitesearch.cpp index a779f2e..dbd59fc 100644 --- a/shared/sqlitesearch.cpp +++ b/shared/sqlitesearch.cpp @@ -66,6 +66,28 @@ QString SqliteSearch::createSortSql(const QVector sortConditions) return ""; } +QString SqliteSearch::escapeFtsArgument(QString ftsArg) +{ + QString result; + QRegularExpression extractor(R"#("([^"]*)"|([^\s]+))#"); + QRegularExpressionMatchIterator i = extractor.globalMatch(ftsArg); + while(i.hasNext()) + { + QRegularExpressionMatch m = i.next(); + QString value = m.captured(1); + if(value.isEmpty()) + { + value = m.captured(2); + } + else + { + value = "\"\"" + value + "\"\""; + } + result += "\"" + value + "\" "; + } + return result; +} + QPair> createNonArgPair(QString key) { return {" " + key + " ", QVector()}; @@ -117,7 +139,7 @@ QPair> SqliteSearch::createSql(const Token &token) { return {" content.id IN (SELECT fts.ROWID FROM fts WHERE fts.content MATCH ? ORDER BY " "rank) ", - {value}}; + {escapeFtsArgument(value)}}; } throw LooqsGeneralException("Unknown token passed (should not happen)"); } @@ -145,7 +167,7 @@ QSqlQuery SqliteSearch::makeSqlQuery(const LooqsQuery &query) ftsAlreadyJoined = true; } whereSql += " fts.content MATCH ? "; - bindValues.append(token.value); + bindValues.append(escapeFtsArgument(token.value)); } else { diff --git a/shared/sqlitesearch.h b/shared/sqlitesearch.h index ea2f70c..3acdd09 100644 --- a/shared/sqlitesearch.h +++ b/shared/sqlitesearch.h @@ -18,6 +18,7 @@ class SqliteSearch QString fieldToColumn(QueryField field); QPair> createSql(const Token &token); QString createSortSql(const QVector sortConditions); + QString escapeFtsArgument(QString ftsArg); }; #endif // SQLITESEARCH_H