22 Commits
docs ... v0.2

Auteur SHA1 Bericht Datum
fc92b963d4 Release: v0.2 2022-06-07 00:01:35 +02:00
9acbd5dccf Add .gitignore 2022-06-07 00:00:54 +02:00
87ebc137d5 shared/gui: Add LOOQS_DISABLE_SANDBOX env to allow disabling sandboxing
Mainly for devs to check whether a problem is caused by sandboxing.
2022-06-06 23:23:07 +02:00
67189f34c6 gui: main: Make sandboxing work on kernels without landlock
Those are still around of course, so deal with that
2022-06-06 22:16:36 +02:00
fac6ed1853 Release: v0.1 2022-06-06 17:44:51 +02:00
ae2097fe6a HACKING.md: Fix broken link 2022-06-06 17:44:51 +02:00
9e3d3b1dd4 Begin CHANGELOG.md 2022-06-06 17:26:14 +02:00
4f3abb3f67 README.md: Mention packages 2022-06-06 17:11:20 +02:00
3ca6e4df3c looqs.desktop: Remove absolute path to binary 2022-06-06 15:55:21 +02:00
0d81452a67 rename icon to looqs.svg 2022-06-06 15:55:21 +02:00
3e14498437 README.md: General updates, more screenshots 2022-06-06 14:52:58 +02:00
3102a952df Begin CONTRIBUTING.md 2022-06-06 14:49:34 +02:00
3903f18854 Begin HACKING.md 2022-06-06 14:49:24 +02:00
60a91967bb Begin USAGE.md 2022-06-06 14:49:17 +02:00
c6550e81bb submodules: exile.h: Update 2022-06-06 14:19:17 +02:00
744fa2ec7a cli: CommandAdd: Set keepGoing, Remove verbose for now 2022-06-06 09:34:37 +02:00
f8542dc96a shared: Indexer: Handle keepGoing, set verbose 2022-06-06 09:34:37 +02:00
fdae7fd065 shared: LooqsQuery: Use unicode category class in regex 2022-06-06 09:34:37 +02:00
f8d6a1a586 gui: mainwindow: Use Unicode category class to extract highlight words 2022-06-06 09:34:37 +02:00
61fa7ca16d shared: IndexSyncer: Check whether file is located in a mountpath 2022-06-06 09:34:37 +02:00
61a446ec2d shared: common: Add mountPaths()
Mountpaths indicate mount points of external devices. Files
located under such paths should not be removed on sync, because
they may have not been deleted, but are just inaccessible right now.
2022-06-06 09:34:37 +02:00
0e5abf96c8 shared: indexer: Don't dispatch DirScanner if no dirs given
This makes sense in general, however it also avoids a race condition.

The dirscanner may finish before the filescanworkers for the files
run, this then signals the whole indexer has finished.
2022-06-05 20:35:21 +02:00
20 gewijzigde bestanden met toevoegingen van 256 en 48 verwijderingen

11
.gitignore vendored Normal file
Bestand weergeven

@ -0,0 +1,11 @@
.user
.o
*.user
*.o
*.a
moc_*.cpp
moc_*.h
Makefile
cli/looqs
gui/looqs-gui
qrc_*

Bestand weergeven

@ -1,22 +1,34 @@
# looqs: Release notes
## 2022-06-XX - v0.1
## 2022-06-07 - v0.2
CHANGES:
- Sandboxing: Add environment variable `LOOQS_DISABLE_SANDBOXING` to disable sandboxing. This is intended for troubleshooting
- Sandboxing: Fix issue where activation failed on kernels without landlock
## 2022-06-06 - v0.1
The first release comes with basic functionality. It's a start that can be considered useful to some degree.
looqs is still at an early stage and may exhibit some weirdness and contain bugs.
Tested architectures: amd64.
CHANGES:
- CLI command "looqs" to add/update/delete and search
- GUI: "looqs-gui" to search, render previews, and add files to index
CHANGES:
- CLI command "looqs" to add/update/delete and search
- GUI: "looqs-gui" to search, render previews, and add files to index
- General: Add multi-threaded indexing of all files (paths, mtime)
- General: Generate sqlite based full-text search index for: .pdf,.odt,.ods, text files
- General: Sandboxed content processing
- GUI: Sandboxed IPC sub-process to render previews.
- GUI: Add previews for pdf: Render the page the search keywords were found. Highlight the keywords when rendering the page.
- GUI: Add previews for plaintext files: Extract snippets. Highlight the keywords when rendering the page.
- GUI: Add previews for pdf: Render the page the search keywords were found. Highlight the keywords when rendering the page.
- GUI: Add previews for plaintext files: Extract snippets. Highlight the keywords when rendering the page.
- General: Add basic filters for query.
- Add packages: Ubuntu 22.04
- GUI: Add icon. Special thanks to the following sources:
https://www.svgrepo.com/svg/151751/magnifier-with-small-handle
https://www.svgrepo.com/svg/52764/open-book
Thanks!
- General: Documentation.
- Add packages: Ubuntu 21.10, 22.04
Thanks to all those who provided feedback (and endured bugs) at various stages. You know who you are, thx!

26
CONTRIBUTING.md Normal file
Bestand weergeven

@ -0,0 +1,26 @@
# looqs - Contributing
Contributions are welcome, please use the following guidelines.
## Repository
The github repository https://github.com/quitesimpleorg/looqs is the primary one. Pull-Requests and Issues go there, but you can also submit your feedback there.
Those who prefer a more classical approach can mail their patches etc. to looqs at quitesimple org. Ideally git-format patch and git send-email.
The repository at https://gitea.quitesimple.org/crtxcr/looqs was supposed to be the main one, but these
plans are on hold for the time being. Just ignore it.
## Pull-Requests & Rebasing
Your merge requests should be submitted against the dev branch. master branch won't be rebased. I'll try to avoid in the dev branch. I definitly rebase WIP/feature branches.
## Commit messages
Commit messages begin with the component your change affects, e. g. "gui:", "cli:", "shared:", followed by the class.
Then choose an appropriate verb in present tense. Wrong: Fixed, Fixes. Correct: Fix. Make sure lines are not too long,
I personally go by gut feeling in this matter.
If your change has an issue, link it at the end: Closes: https://github.com/quitesimpleorg/looqs/issues/1
Example: "shared: Indexer: Use WildcardMatcher to ignore paths"
## License
You license your changes under the GPLv3 by contributing.

33
HACKING.md Normal file
Bestand weergeven

@ -0,0 +1,33 @@
# looqs - Hacking
## Introduction
Without elaborating here, I hacked looqs because I was not satisfied with the state of desktop search on Linux.
Originally a set of CLI python scripts, it is now written in C++ and offers a GUI made using Qt. While a "web app" would have been an option, I prefer a desktop application for something like looqs. I chose Qt because I am more familiar with it than with any other GUI framework. To my knowledge, potential alternatives like GTK do not include as many "batteries" as Qt anyway, so the job presumably would have been harder there.
[CONTRIBUTING.md](CONTRIBUTING.md) contains the instructions on how to submit patches etc.
## Security
The architecture ensures that the parsing of documents and the preview generation is sandboxed by [exile.h](https://github.com/quitesimpleorg/exile.h). looqs uses a multi-process architecture to achieve this.
Qt code is considered trusted in this model. While one may critize this, it was the only practical solution. looqs uses its serialization mechanism and other classes to communicate between the non-sandboxed GUI process and the sandboxed processes.
Set the enviornment variable `LOOQS_DISABLE_SANDBOX=1` to disable sandboxing. It's intended for troublehshooting.
## Database
The heart is sqlite, with the FTS5 extensions behind the full-text search. I definitly did not
want to run some heavy Java based solutions. I explored other options like Postgresql, I've discard them due to some limitations back then.
Down the road, alternatives will be explored of course if sqlite should not suffice anymore.
## File format support
The pdf library is libpoppler. Files such as .odt or .docx documents are opened with libquazip. The XML files in there are not parsed,
looqs simply strips the tags and that seems to work fine so far. Naturally, this is not the "proper way", so there is room for improvement maybehere. However, those file formats are not a huge priortiy for me personally. libuchardet does encoding detection and conversion.
Naturally looqs won't be able to index and render previews for everything. Such approach would create a huge bloated binary. In the future, there will be some plugin system of some sorts, either we will load .so objects or use subprocesses.
## Name
looqs looks for files. You as the user can also look inside them. The 'k' was replaced by a 'q'. Originally wanted my projects to have "qs" (for quitesimple) in their name. While abandoned now, this got us to looqs.

Bestand weergeven

@ -2,20 +2,35 @@
looqs is a tool that creates a full-text search index for your files. It allows you to look at previews where your
search terms have been found, as shown in the screenshots below.
## Screenshots
The screenshots in this section may occasionally be slightly outdated, but they are usually recent enough to get an overall impression of the current state.
### List
![Screenshot looqs results](https://garage.quitesimple.org/assets/looqs/opearting_systems_looqs.png)
The screenshots in this section may occasionally be slightly outdated, but they are usually recent enough to get an overall impression of the current state of the GUI.
### Preview
looqs allow you to look inside files. It marks what you have searched for.
![Screenshot looqs](https://garage.quitesimple.org/assets/looqs/orwell.png)
![Screenshot looqs search fstream](https://garage.quitesimple.org/assets/looqs/fstream_write.png)
### Results list
#### Classic results list
Just enter what you want to find, it will search paths and file content.
![Screenshot looqs results](https://garage.quitesimple.org/assets/looqs/looqs_diary.png)
#### Searching with filters
You can be more specific to get what you want with filters
**Filters (long form)**
![Screenshot looqs results](https://garage.quitesimple.org/assets/looqs/opearting_systems_looqs.png)
**Filters (short form)**
There is no need to write the long form of filters. There are also booleans available
![Screenshot looqs results](https://garage.quitesimple.org/assets/looqs/looqs_beatles_marley.png)
## Current status
Last version: 2022-0X-XX, v0.1
Last version: 2022-06-07, v0.2
Please see [Changelog](CHANGELOG.md) for a human readable list of changes.
@ -23,10 +38,20 @@ Please see [Changelog](CHANGELOG.md) for a human readable list of changes.
## Goals and principles
* **Find & Preview**. Instead of merely telling you where your search phrase has been found, it should also render the corresponding portion/pages of the documents and highlight the searched words.
* **No daemons**. As some other desktop search projects are prone to have annoying daemons running that eat system resources away, this solution should make do without daemons where possible.
* **Easy setup**. Similiarly, there should be no need for heavy-weight databases. Instead, this solution tries to squeeze out the most from simple approaches. In particular, it relies on sqlite.
* **Easy setup**. Similarly, there should be no need for heavy-weight databases. Instead, looqs tries to squeeze out the most from simple approaches. In particular, it relies on sqlite.
* **GUI & CLI**. Provide CLI interfaces and GUI interfaces
* **Sandboxing**. As reading and rendering lots of formats naturally opens the door for security bugs, those tasks are offloaded to small, sandboxed sub-processes to mitigate the effect of exploited vulnerabilities.
## Features
- GUI, CLI interface
- Indexing of file path and some metadata.
- Indexing of file file content for FTS search. Currently: .pdf, odt, docx, plaintext.
- Preview of file formats: Currently: .pdf, plaintext
- Highlight searched terms.
- Quickly open PDF viewer or text editor at location of preview
- Search filters
## Supported platforms
Linux (on amd64) is currently the main focus. Currently, I don't plan on supporting anything else and the sandboxing architecture does not make it likely. I suppose a version without sandboxing might be conceivable for other platforms, but I have no plans or resources to actively target anything but Linux at this point.
@ -34,15 +59,17 @@ Linux (on amd64) is currently the main focus. Currently, I don't plan on support
GPLv3.
### Contributing
For now, github issues and pull-requests are preferred, but you can also just email
your patches or issues to: looqs at quitesimple.org
Please see the [Contribution guidelines](CONTRIBUTING.md) file.
Please target the 'dev' branch in your pull request.
## Documentation
Please see [USAGE.md](USAGE.md) for the user manual. There is also [HACKING.md](HACKING.md) with more technical information.
## Build
### Ubuntu 21.10/22.04
To build on Ubuntu and Debian, clone the repo and then run:
```
git submodule init
git submodule update
@ -53,9 +80,22 @@ make
The GUI is located in `gui/looqs-gui`, the binary for the CLI is in `cli/looqs`
## Documentation
Please see [USAGE.md](USAGE.md) for the user manual.
## Packages
Coming soon™
At this point, looqs is not in any official distro package repo, but I maintain some packages.
### Ubuntu 21.10/22.04
Latest release can be installed using apt from the repo.
```
# First, obtain key, assume it's trusted.
wget -O- https://repo.quitesimple.org/repo.quitesimple.org.asc | gpg --dearmor > repo.quitesimple.org-keyring.gpg
cat repo.quitesimple.org-keyring.gpg | sudo tee -a /usr/share/keyrings/repo.quitesimple.org.gpg > /dev/null
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/repo.quitesimple.org.gpg] https://repo.quitesimple.org/debian/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/quitesimple.list
sudo apt-get update
sudo apt-get install looqs
```
### Other distros
I'll probably add a package for voidlinux at some point and maybe will provide a Gentoo ebuild. However, I would appreciate help for others distros. If you create a package, let me know!
As for distro-agnostic packages, I will also take a look into appimage / flatpak etc. and/or maybe just provide a self-contained archive.

Bestand weergeven

@ -29,8 +29,12 @@ void CommandAdd::indexerFinished()
}
}
/* TODO maybe not 0 if keepGoing not given */
emit finishedCmd(0);
int ret = 0;
if(!keepGoing && failedPathsCount > 0)
{
ret = 1;
}
emit finishedCmd(ret);
}
int CommandAdd::handle(QStringList arguments)
@ -40,15 +44,13 @@ int CommandAdd::handle(QStringList arguments)
"Continue adding files, don't exit on first error. If this option is not given, looqs will "
"exit asap, but it's possible that a few files will still be processed. "
"Set -t 1 to avoid this behavior, but processing will be slower. "},
{{"v", "verbose"}, "Print skipped and added files"},
{{"t", "threads"}, "Number of threads to use.", "threads"}});
parser.addHelpOption();
parser.addPositionalArgument("add", "Add paths to the index", "add [paths...]");
parser.process(arguments);
bool keepGoing = parser.isSet("continue");
bool verbose = parser.isSet("verbose");
this->keepGoing = parser.isSet("continue");
if(parser.isSet("threads"))
{
QString threadsCount = parser.value("threads");
@ -70,17 +72,15 @@ int CommandAdd::handle(QStringList arguments)
indexer = new Indexer(*this->dbService);
indexer->setTargetPaths(files.toVector());
indexer->setKeepGoing(keepGoing);
connect(indexer, &Indexer::pathsCountChanged, this,
[](int pathsCount) { Logger::info() << "Found paths: " << pathsCount << Qt::endl; });
connect(indexer, &Indexer::indexProgress, this,
[](int pathsCount, unsigned int added, unsigned int skipped, unsigned int failed, unsigned int totalCount)
{ Logger::info() << "Processed files: " << pathsCount << Qt::endl; });
connect(indexer, &Indexer::finished, this, &CommandAdd::indexerFinished);
/* TODO: keepGoing, verbose */
this->autoFinish = false;
indexer->beginIndexing();

Bestand weergeven

@ -10,6 +10,7 @@ class CommandAdd : public Command
private:
SaveFileResult addFile(QString path);
Indexer *indexer;
bool keepGoing = true;
protected:
public:

Bestand weergeven

@ -78,4 +78,4 @@ else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PW
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../shared/debug/shared.lib
else:unix: PRE_TARGETDEPS += $$OUT_PWD/../shared/libshared.a
RESOURCES = ../icon.svg
RESOURCES = ../looqs.svg

Bestand weergeven

@ -23,19 +23,23 @@ void enableIpcSandbox()
qCritical() << "Failed to init policy for sandbox";
exit(EXIT_FAILURE);
}
policy->namespace_options = EXILE_UNSHARE_NETWORK | EXILE_UNSHARE_USER;
policy->namespace_options = EXILE_UNSHARE_USER | EXILE_UNSHARE_MOUNT | EXILE_UNSHARE_NETWORK;
policy->no_new_privs = 1;
policy->drop_caps = 1;
policy->vow_promises =
exile_vows_from_str("thread cpath wpath rpath unix stdio prot_exec proc shm fsnotify ioctl error");
policy->mount_path_policies_to_chroot = 1;
QString ipcSocketPath = Common::ipcSocketPath();
QFileInfo info{ipcSocketPath};
QString ipcSocketPathDir = info.absolutePath();
std::string stdIpcSocketPath = ipcSocketPathDir.toStdString();
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ, "/");
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_ALL_WRITE, stdIpcSocketPath.c_str());
/* ALLOW_EXEC is needed for fallback, not in landlock mode. It does not allow executing anything though here
* due to the vows */
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_EXEC, "/");
exile_append_path_policies(policy, EXILE_FS_ALLOW_ALL_READ | EXILE_FS_ALLOW_ALL_WRITE | EXILE_FS_ALLOW_EXEC,
stdIpcSocketPath.c_str());
int ret = exile_enable_policy(policy);
if(ret != 0)
{
@ -54,14 +58,21 @@ int main(int argc, char *argv[])
if(arg == "ipc")
{
Common::setupAppInfo();
enableIpcSandbox();
if(Common::noSandboxModeRequested())
{
qInfo() << "Launching with no sandbox!" << Qt::endl;
}
else
{
enableIpcSandbox();
}
QApplication a(argc, argv);
IpcServer *ipcserver = new IpcServer();
qDebug() << "Launching IPC Server";
if(!ipcserver->startSpawner(socketPath))
{
qCritical() << "Error failed to spawn";
qCritical() << "Error failed to spawn" << Qt::endl;
return 1;
}
qDebug() << "Launched IPC Server";
@ -128,7 +139,7 @@ int main(int argc, char *argv[])
return 1;
}
QApplication a(argc, argv);
a.setWindowIcon(QIcon(":/icon.svg"));
a.setWindowIcon(QIcon(":/looqs.svg"));
QObject::connect(&a, &QApplication::aboutToQuit, &process, &QProcess::kill);
qRegisterMetaType<QVector<SearchResult>>("QVector<SearchResult>");

Bestand weergeven

@ -502,7 +502,7 @@ void MainWindow::makePreviews(int page)
scaleText.chop(1);
QVector<QString> wordsToHighlight;
QRegularExpression extractor(R"#("([^"]*)"|(\w+))#");
QRegularExpression extractor(R"#("([^"]*)"|(\p{L}+))#");
for(const Token &token : this->contentSearchQuery.getTokens())
{
if(token.type == FILTER_CONTENT_CONTAINS)

Bestand weergeven

@ -1,6 +1,6 @@
[Desktop Entry]
Name=looqs
Exec=/usr/bin/looqs-gui
Exec=looqs-gui
Terminal=false
Type=Application
Icon=looqs

Bestand weergeven

Voor

Breedte:  |  Hoogte:  |  Grootte: 13 KiB

Na

Breedte:  |  Hoogte:  |  Grootte: 13 KiB

Bestand weergeven

@ -19,6 +19,7 @@
#define SETTINGS_KEY_IPCSOCKETPATH "ipcsocketpath"
#define SETTINGS_KEY_PDFVIEWER "pdfviewer"
#define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths"
#define SETTINGS_KEY_MOUNTPATHS "mountpaths"
inline void initResources()
{
@ -156,6 +157,16 @@ QString Common::databasePath()
return env;
}
bool Common::noSandboxModeRequested()
{
QString env = getenv("LOOQS_DISABLE_SANDBOX");
if(env == "1")
{
return true;
}
return false;
}
QString Common::ipcSocketPath()
{
return "/tmp/.looqs/looqs-ipc-socket";
@ -180,6 +191,32 @@ QStringList Common::excludedPaths()
return ::excludedPaths;
}
QStringList Common::mountPaths()
{
static int ran = false;
static QStringList mountPaths;
if(!ran)
{
QSettings settings;
mountPaths = settings.value(SETTINGS_KEY_MOUNTPATHS, QStringList{"/media", "/mnt"}).toStringList();
ran = true;
}
return mountPaths;
}
bool Common::isMountPath(QString path)
{
QStringList mountPaths = Common::mountPaths();
for(QString &mountPath : mountPaths)
{
if(path.startsWith(mountPath))
{
return true;
}
}
return false;
}
bool Common::isTextFile(QFileInfo fileInfo)
{
/* TODO: This is not sandboxed yet ... */

Bestand weergeven

@ -12,7 +12,10 @@ QString findInPath(QString needle);
bool initSqliteDatabase(QString path);
void ensureConfigured();
QStringList excludedPaths();
QStringList mountPaths();
bool isTextFile(QFileInfo fileInfo);
bool isMountPath(QString path);
bool noSandboxModeRequested();
QString versionText();
} // namespace Common
#endif

Bestand weergeven

@ -36,10 +36,14 @@ void Indexer::beginIndexing()
this->filePathTargetsQueue.enqueue(path);
}
}
this->dirScanner->setPaths(dirs);
this->dirScanner->setIgnorePatterns(this->ignorePattern);
this->dirScanner->scan();
if(!dirs.empty())
{
this->dirScanner->setPaths(dirs);
this->dirScanner->setIgnorePatterns(this->ignorePattern);
this->dirScanner->scan();
}
this->workerCancellationToken.store(false, std::memory_order_seq_cst);
launchWorker(this->filePathTargetsQueue, this->filePathTargetsQueue.remaining());
@ -55,6 +59,16 @@ void Indexer::setTargetPaths(QVector<QString> pathsToScan)
this->pathsToScan = pathsToScan;
}
void Indexer::setVerbose(bool verbose)
{
this->verbose = verbose;
}
void Indexer::setKeepGoing(bool keepGoing)
{
this->keepGoing = keepGoing;
}
void Indexer::requestCancellation()
{
this->dirScanner->cancel();
@ -68,7 +82,7 @@ IndexResult Indexer::getResult()
void Indexer::dirScanFinished()
{
Logger::info() << "Dir scan finished";
Logger::info() << "Dir scan finished" << Qt::endl;
if(!isRunning())
{
emit finished();
@ -92,17 +106,24 @@ void Indexer::dirScanProgress(int current, int total)
void Indexer::processFileScanResult(FileScanResult result)
{
if(verbose)
if(result.second == DBFAIL || result.second == PROCESSFAIL || result.second == NOTFOUND)
{
this->currentIndexResult.results.append(result);
if(!keepGoing)
{
this->requestCancellation();
emit finished();
return;
}
}
else
{
if(result.second == DBFAIL || result.second == PROCESSFAIL || result.second == NOTFOUND)
if(verbose)
{
this->currentIndexResult.results.append(result);
}
}
if(result.second == OK)
{
++this->currentIndexResult.addedPaths;

Bestand weergeven

@ -67,6 +67,8 @@ class Indexer : public QObject
void beginIndexing();
void setIgnorePattern(QStringList ignorePattern);
void setTargetPaths(QVector<QString> pathsToScan);
void setVerbose(bool verbose);
void setKeepGoing(bool keepGoing);
void requestCancellation();

Bestand weergeven

@ -55,6 +55,11 @@ void IndexSyncer::sync()
emit finished(totalUpdatesFilesCount, totalDeletedFilesCount, totalErroredFilesCount);
return;
}
if(Common::isMountPath(fileData.absPath))
{
continue;
}
QFileInfo fileInfo(fileData.absPath);
if(fileInfo.exists())
{

Bestand weergeven

@ -180,8 +180,9 @@ LooqsQuery LooqsQuery::build(QString expression, TokenType loneWordsTokenType, b
QStringList loneWords;
LooqsQuery result;
QRegularExpression rx("((?<filtername>(\\.|\\w)+):(?<args>\\((?<innerargs>[^\\)]+)\\)|([\\w,])+)|(?<boolean>AND|OR)"
"|(?<negation>!)|(?<bracket>\\(|\\))|(?<loneword>[\"\\w]+))");
QRegularExpression rx(
"((?<filtername>(\\.|\\w)+):(?<args>\\((?<innerargs>[^\\)]+)\\)|([\\p{L},])+)|(?<boolean>AND|OR)"
"|(?<negation>!)|(?<bracket>\\(|\\))|(?<loneword>[\"\\p{L}]+))");
QRegularExpressionMatchIterator i = rx.globalMatch(expression);
auto previousWasBool = [&result] { return !result.tokens.empty() && ((result.tokens.last().type & BOOL) == BOOL); };
auto previousWas = [&result](TokenType t) { return !result.tokens.empty() && (result.tokens.last().type == t); };

Bestand weergeven

@ -27,6 +27,11 @@ static QMap<QString, Processor *> processors{
void SandboxedProcessor::enableSandbox(QString readablePath)
{
if(Common::noSandboxModeRequested())
{
qInfo() << "Sandbox is disabled!" << Qt::endl;
return;
}
struct exile_policy *policy = exile_init_policy();
if(policy == NULL)
{