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 "sqlitequeryoption.h"
#include "../logger.h"
#include "../utils.h"
/* 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;
}
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)
{
@ -162,11 +179,10 @@ std::vector<SearchResult> PageDaoSqlite::search(std::string name, QueryOption op
try
{
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 =
*db << "SELECT page.name FROM search INNER JOIN page ON search.page = page.id WHERE search MATCH ? "
<< name;
<< ftsEscape(name);
query >> [&](std::string pagename) {
SearchResult sresult;
sresult.pagename = pagename;

View File

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

View File

@ -28,15 +28,6 @@ Response HandlerSearch::handleRequest(const Request &r)
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();
QueryOption qo = queryOption(r);
try