handlersearch: Allow all characters by escaping FTS

Escape FTS queries by simply treating everything as string.
Though this way a user cannot use operators, it's an improvement
over how it was done before.

Closes: #7
This commit is contained in:
Albert S. 2021-03-25 21:40:05 +01:00
parent 2aa11fc2b2
commit d507c507e4
3 changed files with 22 additions and 12 deletions

View File

@ -23,6 +23,7 @@ SOFTWARE.
#include "exceptions.h" #include "exceptions.h"
#include "sqlitequeryoption.h" #include "sqlitequeryoption.h"
#include "../logger.h" #include "../logger.h"
#include "../utils.h"
/* TODO: copied from C version mostly, review whether access to table other than page is ok */ /* TODO: copied from C version mostly, review whether access to table other than page is ok */
@ -155,6 +156,22 @@ std::vector<std::string> PageDaoSqlite::fetchCategories(std::string pagename, Qu
return result; return result;
} }
std::string PageDaoSqlite::ftsEscape(std::string input)
{
std::string result = "";
for(auto &str : utils::splitByChar(input, ' '))
{
std::string tmp = utils::strreplace(str, "\"", "\"\"");
tmp = "\"" + tmp + "\"" + " ";
result += tmp;
}
if(!result.empty())
{
result.pop_back();
}
return result;
}
std::vector<SearchResult> PageDaoSqlite::search(std::string name, QueryOption option) std::vector<SearchResult> PageDaoSqlite::search(std::string name, QueryOption option)
{ {
@ -162,11 +179,10 @@ std::vector<SearchResult> PageDaoSqlite::search(std::string name, QueryOption op
try try
{ {
std::string qo = SqliteQueryOption(option).setPrependWhere(false).setOrderByColumn("rank").build(); std::string qo = SqliteQueryOption(option).setPrependWhere(false).setOrderByColumn("rank").build();
// TODO: what is passed here, simple gets thrown to the MATCH operator without escaping or anything and this is
// suboptimal
auto query = auto query =
*db << "SELECT page.name FROM search INNER JOIN page ON search.page = page.id WHERE search MATCH ? " *db << "SELECT page.name FROM search INNER JOIN page ON search.page = page.id WHERE search MATCH ? "
<< name; << ftsEscape(name);
query >> [&](std::string pagename) { query >> [&](std::string pagename) {
SearchResult sresult; SearchResult sresult;
sresult.pagename = pagename; sresult.pagename = pagename;

View File

@ -8,6 +8,9 @@
#include "sqlitedao.h" #include "sqlitedao.h"
class PageDaoSqlite : public PageDao, protected SqliteDao class PageDaoSqlite : public PageDao, protected SqliteDao
{ {
private:
std::string ftsEscape(std::string input);
public: public:
PageDaoSqlite() PageDaoSqlite()
{ {

View File

@ -28,15 +28,6 @@ Response HandlerSearch::handleRequest(const Request &r)
return errorResponse("Missing search term", "No search term supplied"); return errorResponse("Missing search term", "No search term supplied");
} }
for(int x : q)
{
if(!isalnum(x) && !isspace(x))
{
return errorResponse(
"Invalid char",
"Currently, the search is limited and so only supports alpha numeric characters and spaces");
}
}
auto pageDao = this->database->createPageDao(); auto pageDao = this->database->createPageDao();
QueryOption qo = queryOption(r); QueryOption qo = queryOption(r);
try try