QtPass 2.0.0
Developer documentation
Loading...
Searching...
No Matches
NativeGrep Class Reference

Full-text search over a password store without pass grep: every .gpg file is decrypted with gpg on a worker thread and its lines matched against a QRegularExpression. Only the newest search may report; a search started while another runs asks that one to stop and supersedes it. More...

#include <nativegrep.h>

Inheritance diagram for NativeGrep:
Collaboration diagram for NativeGrep:

Classes

struct  Worker

Signals

void finished (const QList< QPair< QString, QStringList > > &results)
 The newest search is over.

Public Member Functions

 NativeGrep (QObject *parent=nullptr)
 Create a searcher.
 ~NativeGrep () override
 Interrupt running searches and wait up to five seconds for them.
void search (const QString &pattern, bool caseInsensitive, const QString &gpgExe, const QString &storeDir, const QProcessEnvironment &env)
 Start a search; finished() follows asynchronously, also for an empty or invalid pattern (with no results).
void cancel ()
 Ask running searches to stop without waiting for them: the walk ends at the next file and a gpg that is decrypting is terminated by its own worker thread.

Static Public Member Functions

static auto isMoreMarker (const QString &line) -> bool
 Whether a line in a result is the marker for "more matches in this entry" rather than a match.
static auto isStoppedMarker (const QPair< QString, QStringList > &result) -> bool
 Whether a result is the marker for "the search stopped at kMaxMatches, more entries were not searched".
static auto matchFile (const QProcessEnvironment &env, const QString &gpgExe, const QString &filePath, const QRegularExpression &rx, const std::atomic_bool *cancel=nullptr) -> QStringList
 Decrypt one .gpg file and return its trimmed lines matching rx.
static auto scanStore (const QProcessEnvironment &env, const QString &gpgExe, const QString &storeDir, const QRegularExpression &rx, const std::atomic_bool *cancel=nullptr) -> QList< QPair< QString, QStringList > >
 Walk storeDir, decrypt every .gpg file and collect the matches.

Static Public Attributes

static constexpr int kMaxMatchesPerEntry = 100
 Most matching lines taken from one entry.
static constexpr int kMaxMatches = 10000
 Most matching lines a search collects over the whole store.
static constexpr qsizetype kMaxPreviewLength = 200
 Longest preview of a matching line, in UTF-16 code units.

Private Attributes

int m_seq = 0
 Number of the newest search. A worker reports through finished() only when its own number still equals this.
QList< Worker > m_workers
 Searches still running, superseded ones included.

Detailed Description

Full-text search over a password store without pass grep: every .gpg file is decrypted with gpg on a worker thread and its lines matched against a QRegularExpression. Only the newest search may report; a search started while another runs asks that one to stop and supersedes it.

Definition at line 31 of file nativegrep.h.

Constructor & Destructor Documentation

◆ NativeGrep()

NativeGrep::NativeGrep ( QObject * parent = nullptr)
explicit

Create a searcher.

Parameters
parentOwner; results are delivered on its thread.

Definition at line 21 of file nativegrep.cpp.

◆ ~NativeGrep()

NativeGrep::~NativeGrep ( )
override

Interrupt running searches and wait up to five seconds for them.

Definition at line 23 of file nativegrep.cpp.

Here is the call graph for this function:

Member Function Documentation

◆ cancel()

void NativeGrep::cancel ( )

Ask running searches to stop without waiting for them: the walk ends at the next file and a gpg that is decrypting is terminated by its own worker thread.

Definition at line 230 of file nativegrep.cpp.

Here is the caller graph for this function:

◆ finished

void NativeGrep::finished ( const QList< QPair< QString, QStringList > > & results)
signal

The newest search is over.

Parameters
results(entry, matching lines) pairs.
Here is the caller graph for this function:

◆ isMoreMarker()

auto NativeGrep::isMoreMarker ( const QString & line) -> bool
inlinestaticnodiscard

Whether a line in a result is the marker for "more matches in this entry" rather than a match.

A match is a trimmed, non-empty line, so an empty one can only be the marker, which matchFile() and scanStore() put last. Not a match: not counted, not content to hide.

Parameters
lineA line of a result.
Returns
Whether it is the marker.

Definition at line 80 of file nativegrep.h.

Here is the caller graph for this function:

◆ isStoppedMarker()

auto NativeGrep::isStoppedMarker ( const QPair< QString, QStringList > & result) -> bool
inlinestaticnodiscard

Whether a result is the marker for "the search stopped at kMaxMatches, more entries were not searched".

No entry has an empty name, so a result without one can only be the marker, which scanStore() puts last.

Parameters
resultA result.
Returns
Whether it is the marker.

Definition at line 94 of file nativegrep.h.

Here is the caller graph for this function:

◆ matchFile()

auto NativeGrep::matchFile ( const QProcessEnvironment & env,
const QString & gpgExe,
const QString & filePath,
const QRegularExpression & rx,
const std::atomic_bool * cancel = nullptr ) -> QStringList
static

Decrypt one .gpg file and return its trimmed lines matching rx.

Decrypt one .gpg file and return lines matching rx.

Parameters
envEnvironment for gpg.
gpgExeThe gpg executable.
filePathThe encrypted file.
rxThe pattern.
cancelWhen set, gpg is not started, or is terminated while it runs; nullptr to run to completion.
Returns
Matching lines, at most kMaxMatchesPerEntry and then a marker (isMoreMarker()) when there are more; empty when gpg fails, is cancelled or nothing matches.

Definition at line 41 of file nativegrep.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scanStore()

auto NativeGrep::scanStore ( const QProcessEnvironment & env,
const QString & gpgExe,
const QString & storeDir,
const QRegularExpression & rx,
const std::atomic_bool * cancel = nullptr ) -> QList< QPair< QString, QStringList > >
static

Walk storeDir, decrypt every .gpg file and collect the matches.

Walk the store, decrypt every .gpg file, collect matches.

Parameters
envEnvironment for gpg.
gpgExeThe gpg executable.
storeDirThe store.
rxThe pattern.
cancelStops the walk and the running gpg when set; nullptr to rely on QThread::isInterruptionRequested() alone.
Returns
(entry name without .gpg, matching lines) per file with matches, at most kMaxMatches lines in all, an entry cut short ending in a marker (isMoreMarker()); when the walk stopped at that budget with entries left, a last result that is a marker (isStoppedMarker()). Empty when the search is stopped.

Definition at line 107 of file nativegrep.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ search()

void NativeGrep::search ( const QString & pattern,
bool caseInsensitive,
const QString & gpgExe,
const QString & storeDir,
const QProcessEnvironment & env )

Start a search; finished() follows asynchronously, also for an empty or invalid pattern (with no results).

Start a search on a worker thread.

Parameters
patternPCRE pattern.
caseInsensitiveMatch regardless of case.
gpgExeThe gpg executable (a wsl prefix routes paths through wslpath).
storeDirThe store to walk.
envEnvironment for gpg (GNUPGHOME and friends).

Results are emitted on the owner's thread via QMetaObject::invokeMethod. A sequence counter discards results from superseded searches; the previous search is asked to stop but not waited for, since blocking the UI thread while gpg decrypts would freeze the interface.

Definition at line 160 of file nativegrep.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ kMaxMatches

int NativeGrep::kMaxMatches = 10000
staticconstexpr

Most matching lines a search collects over the whole store.

The search stops once it has this many; the window says so.

Definition at line 55 of file nativegrep.h.

◆ kMaxMatchesPerEntry

int NativeGrep::kMaxMatchesPerEntry = 100
staticconstexpr

Most matching lines taken from one entry.

A compressed entry can expand into millions of lines within the plaintext limit, each a result and a row in the results list; past this many, the entry gets one line saying there are more.

Definition at line 48 of file nativegrep.h.

◆ kMaxPreviewLength

qsizetype NativeGrep::kMaxPreviewLength = 200
staticconstexpr

Longest preview of a matching line, in UTF-16 code units.

A result shows where the pattern matched, not the line; a single line can be most of an entry's 64 MiB plaintext, and 10000 such copies would not fit in memory. A longer line is shown as a window of this many code units around the match (up to two more, one per edge, to keep a surrogate pair whole), "…" where the line goes on. A sequence of several code points (a ZWJ emoji, a flag) can still be cut between them.

Definition at line 68 of file nativegrep.h.

◆ m_seq

int NativeGrep::m_seq = 0
private

Number of the newest search. A worker reports through finished() only when its own number still equals this.

Definition at line 179 of file nativegrep.h.

◆ m_workers

QList<Worker> NativeGrep::m_workers
private

Searches still running, superseded ones included.

Definition at line 181 of file nativegrep.h.


The documentation for this class was generated from the following files: