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

Static helpers that have no better home: setting up the process and the Git environment the way pass does, finding binaries and the default store, path and URL handling, and file operations that refuse to follow links. More...

#include <util.h>

Public Types

using Filler = std::function<QString(QFileDevice &)>
 Fills the temporary of stageFileReplacing() through its open handle; returns why it could not (translated, for the user), or an empty string.

Static Public Member Functions

static void applyPassProcessDefaults ()
 Set up the process the way pass sets up its own, before anything runs git or gpg or writes into the store.
static auto gitCeiling (const QString &store) -> QString
 GIT_CEILING_DIRECTORIES for a store, as pass sets it.
static auto repositoryPassClimbsTo (const QString &store) -> QString
 The repository above store that pass itself would commit to, if any.
static auto gitStoreVariables (const QString &store, const QString &git={}, std::optional< uint > asUser=std::nullopt) -> QList< std::pair< QString, QString > >
 The variables that keep git in store's own repository, never one above it: GIT_CEILING_DIRECTORIES (gitCeiling()), and, when that ceiling holds git's list separator (":", ";" on Windows) and so cannot be one entry of the list, GIT_DIR and GIT_WORK_TREE naming the store's own .git and the store. A store without a .git then has no repository to git, rather than the one above it.
static void setGitOwnerForTests (std::optional< uint > user)
 For tests: the user gitStoreVariables() compares owners with when no asUser is given, in place of the effective user. A file owned by another user cannot be made without root.
static auto mkpathForStore (const QString &path) -> bool
 Create path and any missing parents as pass would.
static auto passUmask (const QString &value) -> int
 The umask pass would use for value of PASSWORD_STORE_UMASK.
static auto findBinaryInPath (const QString &binary) -> QString
 Locate an executable by searching the process PATH and (on Windows) falling back to WSL.
static auto findBinaryInPath (const QString &binary, const QStringList &searchPaths) -> QString
 Locate an executable in an explicit list of directories.
static auto findPasswordStore () -> QString
 Locate the password store directory.
static auto expandTilde (const QString &path) -> QString
 Expand a leading current-user tilde in a path.
static auto normalizeFolderPath (const QString &path) -> QString
 Ensure a folder path always ends with '/'.
static auto configIsValid (const AppSettings &s) -> bool
 Verify that the required configuration is complete.
static auto endsWithGpg () -> const QRegularExpression &
 Returns a regex to match .gpg file extensions.
static auto protocolRegex () -> const QRegularExpression &
 Returns a regex to match URL protocols.
static auto isLaunchableWebUrl (const QString &value) -> bool
 Check whether a value is a safe, launchable web URL.
static auto linkifyUrls (const QString &text, bool *linked=nullptr) -> QString
 Turn plain text into HTML with clickable links for safe web URLs.
static auto newLinesRegex () -> const QRegularExpression &
 Returns a regex to match newline characters.
static auto isValidKeyId (const QString &keyId) -> bool
 Check whether a .gpg-id token may be passed to gpg as a key selector. Accepts any non-empty token that does not start with -, exactly as pass does: key IDs and fingerprints of every version, emails, =Exact User ID, plain name substrings and the @, /, #, & routing prefixes.
static auto regularFilesUnder (const QString &dir, const QStringList &nameFilters, QStringList *skipped=nullptr, bool hiddenFiles=false) -> QStringList
 Regular files under dir whose name matches one of nameFilters, found by walking only real directories.
static auto directoriesUnder (const QString &dir) -> QStringList
 Every real, visible directory under dir, walked by the same rules as regularFilesUnder(): links, junctions and hidden directories are neither listed nor entered.
static auto isLinkedFolder (const QString &path) -> bool
 Whether path names a symbolic link or NTFS junction, with or without a trailing separator (which would otherwise make the check look at the target instead). Folder or file: a linked .gpg, .gpg-id or .gpg-id.sig is judged the same way.
static auto isUnderLink (const QString &path, const QString &storeRoot, bool includeSelf=true) -> bool
 Whether the way from storeRoot down to path passes through a symbolic link or NTFS junction: path itself or any folder between.
static auto removeTree (const QString &dir) -> bool
 Remove dir and everything in it, the way rm -rf does: a symbolic link or NTFS junction, dir itself or anything inside, is removed as an entry and what it points to is never entered. A trailing separator on dir does not change that.
static auto replaceFile (const QString &from, const QString &to, bool replace) -> bool
 Give the file at from the name to, atomically and without following anything: the operating system's rename (rename(2), MoveFileEx), never QFile::rename(), whose fallback when the plain rename fails is to copy by opening to for writing, through whatever link sits under that name by then. With replace, whatever entry is at to (a file, a link) is replaced as an entry; without it, the call fails when anything is there (linkat(2) without AT_SYMLINK_FOLLOW and unlink on POSIX, where a no-replace rename is not portable; plain link(2) follows a symlink at from on macOS and the BSDs).
static auto openRegularFile (const QString &path, QFile &file) -> bool
 Open path for reading as the regular file it is, not as what a link under that name points to: the object opened is the object judged. A check of the name before an open by name leaves a window in which a co-writer of the store makes the name a link; opening without following (O_NOFOLLOW; on Windows the reparse point itself) and judging the open handle closes it. A directory, a link, a FIFO or a device is refused.
static auto readRegularFile (const QString &path, qint64 maxBytes) -> std::optional< QByteArray >
 Read path whole, as the regular file it is (openRegularFile()), when it holds at most maxBytes.
static auto stageFileReplacing (const QString &path, bool replace, const Filler &fill, QString *error=nullptr) -> bool
 The staged write every file QtPass puts into a store goes through: a temporary created next to path (an opaque name, exclusive, owner-only), filled by fill through its open handle, synced, then replaceFile()d under the name, and the object under the name afterwards checked to be the very file that was filled (opened without following, compared by device and inode). The name is never opened for writing, so a link a co-writer plants under it between the caller's check and the write is replaced as an entry rather than written through (QSaveFile resolves such a link at open); a file swapped under the temporary's name before the rename (a hard link to something of the user's, say) is caught by the comparison and reported, and what is under the name is left (removing it by name could take another writer's file that landed there since). Where the system cannot give both identities the write stands: on FAT and exFAT a rename moves the file ID, and those filesystems have no hard links to swap in either.
static auto writeFileReplacing (const QString &path, const QByteArray &bytes, bool replace, QString *error=nullptr) -> bool
 Write bytes as the file path through stageFileReplacing().
static auto copyFileReplacing (const QString &src, const QString &dst, bool replace, QString *error=nullptr) -> bool
 Copy the regular file src to the name dst through stageFileReplacing(): src is read through a handle opened without following (openRegularFile()). The copy is owner-only whatever src's mode, as pass's cp under its umask 077 makes it.
static auto syncToDisk (QFileDevice &file) -> bool
 Flush file's bytes to the device (fsync, FlushFileBuffers) before it is renamed into place, so that a crash right after the rename does not leave the name pointing at an empty file. QSaveFile did this on commit; the staged writes here do it themselves.

Static Public Attributes

static constexpr qint64 kMaxGpgIdBytes = 1024 * 1024
 Most bytes of a .gpg-id QtPass reads.

Static Private Member Functions

static void initialiseEnvironment ()
 Fill _env once: the process environment with the usual GPG install directories appended to PATH (MacGPG2 and /usr/local/bin on macOS, WinGPG and GnuPG on Windows) when they exist.

Static Private Attributes

static QProcessEnvironment _env
static bool _envInitialised = false
 Whether initialiseEnvironment() has run.

Detailed Description

Static helpers that have no better home: setting up the process and the Git environment the way pass does, finding binaries and the default store, path and URL handling, and file operations that refuse to follow links.

Nothing here keeps state apart from the cached process environment, and nothing depends on a widget or a model. Store-boundary checks live in PathValidator, SSH agent discovery in SshAuthSock and template files in TemplateIO.

Definition at line 40 of file util.h.

Member Typedef Documentation

◆ Filler

using Util::Filler = std::function<QString(QFileDevice &)>

Fills the temporary of stageFileReplacing() through its open handle; returns why it could not (translated, for the user), or an empty string.

Definition at line 405 of file util.h.

Member Function Documentation

◆ applyPassProcessDefaults()

void Util::applyPassProcessDefaults ( )
static

Set up the process the way pass sets up its own, before anything runs git or gpg or writes into the store.

Clears the variables that point git at another repository (GIT_DIR, GIT_WORK_TREE and the rest pass clears), and on Unix gives the processes QtPass starts (git, gpg, pass) the umask from PASSWORD_STORE_UMASK, 077 by default (Executor::setChildUmask()): what they create in the store is then the user's alone, as with pass. QtPass's own umask stays the session's, so a browser or file manager it opens is not affected. Call it first thing in main().

Definition at line 106 of file util.cpp.

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

◆ configIsValid()

auto Util::configIsValid ( const AppSettings & s) -> bool
static

Verify that the required configuration is complete.

Parameters
sApplication settings snapshot (passStore, usePass, executables).
Returns
bool true if the password store's .gpg-id exists AND the configured executable (pass or gpg, depending on settings) exists or is a WSL wrapper; false otherwise.

Definition at line 556 of file util.cpp.

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

◆ copyFileReplacing()

auto Util::copyFileReplacing ( const QString & src,
const QString & dst,
bool replace,
QString * error = nullptr ) -> bool
static

Copy the regular file src to the name dst through stageFileReplacing(): src is read through a handle opened without following (openRegularFile()). The copy is owner-only whatever src's mode, as pass's cp under its umask 077 makes it.

Parameters
srcThe file to copy; a link, a directory or a special file under that name is refused.
dstThe name to give the copy.
replaceWhether an existing entry under dst may go.
errorReceives why not, if not null.
Returns
Whether dst now holds a copy of src.

Definition at line 1179 of file util.cpp.

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

◆ directoriesUnder()

auto Util::directoriesUnder ( const QString & dir) -> QStringList
static

Every real, visible directory under dir, walked by the same rules as regularFilesUnder(): links, junctions and hidden directories are neither listed nor entered.

Parameters
dirDirectory to walk.
Returns
Absolute paths, parents before children.

Definition at line 749 of file util.cpp.

Here is the caller graph for this function:

◆ endsWithGpg()

auto Util::endsWithGpg ( ) -> const QRegularExpression &
static

Returns a regex to match .gpg file extensions.

Returns
Reference to static regex

Definition at line 582 of file util.cpp.

Here is the caller graph for this function:

◆ expandTilde()

auto Util::expandTilde ( const QString & path) -> QString
static

Expand a leading current-user tilde in a path.

Environment variables set outside a shell (systemd units, .desktop entries, quoted assignments) keep a literal "~", which no filesystem call resolves. "~" and "~/..." become the home directory; "~user" forms and everything else are returned unchanged.

Parameters
pathPath that may start with a tilde.
Returns
QString Path with a leading current-user tilde expanded.

Definition at line 88 of file util.cpp.

Here is the caller graph for this function:

◆ findBinaryInPath() [1/2]

auto Util::findBinaryInPath ( const QString & binary) -> QString
static

Locate an executable by searching the process PATH and (on Windows) falling back to WSL.

Parameters
binaryExecutable name or relative path to locate (e.g., "gpg" or "pass").
Returns
QString Absolute path to the executable if found, empty QString otherwise.

Definition at line 474 of file util.cpp.

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

◆ findBinaryInPath() [2/2]

auto Util::findBinaryInPath ( const QString & binary,
const QStringList & searchPaths ) -> QString
static

Locate an executable in an explicit list of directories.

Only regular, executable files match; a directory named like the binary is skipped. Empty entries are ignored (they never resolve to the current working directory) and an empty list finds nothing. Only bare names are searched: an absolute path, or a name containing a directory separator, finds nothing rather than escaping searchPaths.

Parameters
binaryExecutable name to locate (no directory separators).
searchPathsDirectories to search, in order.
Returns
QString Absolute path to the executable if found, empty QString otherwise.

Definition at line 537 of file util.cpp.

◆ findPasswordStore()

auto Util::findPasswordStore ( ) -> QString
static

Locate the password store directory.

Returns
QString Path to the password store, always ends with '/'.

Definition at line 73 of file util.cpp.

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

◆ gitCeiling()

auto Util::gitCeiling ( const QString & store) -> QString
static

GIT_CEILING_DIRECTORIES for a store, as pass sets it.

The store's parent, so git never takes a repository above the store for the store's own. git compares ceilings with its real working directory, so this is the real parent when the store path is a link; a store that does not exist yet gets the parent of its absolute path.

Parameters
storeThe store's path.
Returns
The ceiling, empty for an empty store.

Definition at line 135 of file util.cpp.

Here is the caller graph for this function:

◆ gitStoreVariables()

auto Util::gitStoreVariables ( const QString & store,
const QString & git = {},
std::optional< uint > asUser = std::nullopt ) -> QList< std::pair< QString, QString > >
static

The variables that keep git in store's own repository, never one above it: GIT_CEILING_DIRECTORIES (gitCeiling()), and, when that ceiling holds git's list separator (":", ";" on Windows) and so cannot be one entry of the list, GIT_DIR and GIT_WORK_TREE naming the store's own .git and the store. A store without a .git then has no repository to git, rather than the one above it.

An explicit GIT_DIR skips git's ownership check, which runs only when git discovers a repository. On Unix the store is therefore pinned only when git's check would pass: it, its .git and a gitfile's target are the user's own, or git's safe.directory names the store (as git reads it: only from system, global and command-line configuration, never a repository's own; *, an exact path, or a path ending in a slash and * for what lies below it, an empty value clearing the entries before it). Otherwise GIT_DIR names a path that cannot exist, and git refuses rather than run another user's repository and hooks.

Parameters
storeThe store's path.
gitThe git executable that reads safe.directory; "git" from PATH when empty. Run only for a store that is not the user's own.
asUserThe user to compare owners with; the effective user when not given (a test passes another).
Returns
Name and value pairs to set; empty for an empty store.

Definition at line 376 of file util.cpp.

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

◆ initialiseEnvironment()

void Util::initialiseEnvironment ( )
staticprivate

Fill _env once: the process environment with the usual GPG install directories appended to PATH (MacGPG2 and /usr/local/bin on macOS, WinGPG and GnuPG on Windows) when they exist.

Definition at line 46 of file util.cpp.

Here is the caller graph for this function:

◆ isLaunchableWebUrl()

auto Util::isLaunchableWebUrl ( const QString & value) -> bool
static

Check whether a value is a safe, launchable web URL.

Stricter than protocolRegex(): intended to gate an "open in browser" action, where launching a non-web scheme would be a security risk. Returns true only when the trimmed value:

  • contains no control characters (CR, LF, NUL),
  • parses to a valid QUrl,
  • has scheme exactly "http" or "https" (case-insensitive),
  • has a non-empty host,
  • carries no embedded userinfo (user:password@host).

Deliberately rejects file://, javascript:, data:, ftp/ssh/webdav and scheme-less inputs (e.g. "www.example.com").

Parameters
valueCandidate URL string (typically a password-file field).
Returns
true if the value is a launchable http(s) URL, false otherwise.

Definition at line 596 of file util.cpp.

Here is the caller graph for this function:

◆ isLinkedFolder()

auto Util::isLinkedFolder ( const QString & path) -> bool
static

Whether path names a symbolic link or NTFS junction, with or without a trailing separator (which would otherwise make the check look at the target instead). Folder or file: a linked .gpg, .gpg-id or .gpg-id.sig is judged the same way.

The store tree shows linked entries like any other; an operation on one (show, edit, re-encrypt, recipients, delete) must not reach through it.

Parameters
pathPath as the tree or a caller names it.
Returns
true for a link or junction.

Definition at line 761 of file util.cpp.

Here is the caller graph for this function:

◆ isUnderLink()

auto Util::isUnderLink ( const QString & path,
const QString & storeRoot,
bool includeSelf = true ) -> bool
static

Whether the way from storeRoot down to path passes through a symbolic link or NTFS junction: path itself or any folder between.

The tree shows a linked folder's children too, and a pick of one of them names a place outside the store as much as the link does. The root itself is not checked: a linked store root is the user's setup.

Parameters
pathFile or folder under the store, as the tree names it.
storeRootThe configured store.
includeSelfWhether path itself counts; false for a removal, which unlinks a link and touches nothing behind it.
Returns
true when something on the way is a link.

Definition at line 765 of file util.cpp.

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

◆ isValidKeyId()

auto Util::isValidKeyId ( const QString & keyId) -> bool
static

Check whether a .gpg-id token may be passed to gpg as a key selector. Accepts any non-empty token that does not start with -, exactly as pass does: key IDs and fingerprints of every version, emails, =Exact User ID, plain name substrings and the @, /, #, & routing prefixes.

Parameters
keyIdThe string to validate.
Returns
true if gpg may be given the token, false otherwise.

Definition at line 664 of file util.cpp.

Here is the caller graph for this function:

◆ linkifyUrls()

auto Util::linkifyUrls ( const QString & text,
bool * linked = nullptr ) -> QString
static

Turn plain text into HTML with clickable links for safe web URLs.

The single rule for every place a value is rendered into an <a href>: the text is HTML-escaped, and only the protocolRegex() matches that also pass isLaunchableWebUrl() become anchors. Everything else (ssh://, ftp://, URLs carrying user:pass@ credentials, ...) stays escaped plain text, so a click can never hand a non-web scheme or a secret to the OS URL handler via QTextBrowser::setOpenExternalLinks().

Parameters
textPlain (unescaped) text, possibly containing URLs.
linkedOptional out parameter, set to true when at least one anchor was produced.
Returns
HTML-escaped text with anchors for launchable http(s) URLs.

Definition at line 627 of file util.cpp.

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

◆ mkpathForStore()

auto Util::mkpathForStore ( const QString & path) -> bool
static

Create path and any missing parents as pass would.

What pass's mkdir -p does under its umask, for the folders QtPass makes in the store itself: on Unix the mode is 0777 less the store umask (Executor::childUmask(), from PASSWORD_STORE_UMASK, 077 by default and when none is set), whatever QtPass's own umask. Existing folders are left as they are.

Parameters
pathThe folder to create.
Returns
True when path is a folder afterwards.

Definition at line 438 of file util.cpp.

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

◆ newLinesRegex()

auto Util::newLinesRegex ( ) -> const QRegularExpression &
static

Returns a regex to match newline characters.

Returns
Reference to static regex

Definition at line 656 of file util.cpp.

Here is the caller graph for this function:

◆ normalizeFolderPath()

auto Util::normalizeFolderPath ( const QString & path) -> QString
static

Ensure a folder path always ends with '/'.

Qt normalises paths to forward slashes internally, so this function appends '/' unconditionally rather than the platform-native separator. Callers that need native separators can call QDir::toNativeSeparators() themselves.

Parameters
pathThe folder path to normalize.
Returns
QString Path with a trailing '/' added if it was missing.

Definition at line 98 of file util.cpp.

Here is the caller graph for this function:

◆ openRegularFile()

auto Util::openRegularFile ( const QString & path,
QFile & file ) -> bool
static

Open path for reading as the regular file it is, not as what a link under that name points to: the object opened is the object judged. A check of the name before an open by name leaves a window in which a co-writer of the store makes the name a link; opening without following (O_NOFOLLOW; on Windows the reparse point itself) and judging the open handle closes it. A directory, a link, a FIFO or a device is refused.

Parameters
pathThe file, as the caller names it.
fileReceives the open file on success; untouched otherwise.
Returns
Whether file is open on a regular file.

Definition at line 913 of file util.cpp.

Here is the caller graph for this function:

◆ passUmask()

auto Util::passUmask ( const QString & value) -> int
static

The umask pass would use for value of PASSWORD_STORE_UMASK.

Parameters
valueThe variable's value; empty when unset.
Returns
The octal value when it is one (up to four octal digits), else 077, pass's default.

Definition at line 122 of file util.cpp.

Here is the caller graph for this function:

◆ protocolRegex()

auto Util::protocolRegex ( ) -> const QRegularExpression &
static

Returns a regex to match URL protocols.

Returns
Reference to static regex

Definition at line 590 of file util.cpp.

Here is the caller graph for this function:

◆ readRegularFile()

auto Util::readRegularFile ( const QString & path,
qint64 maxBytes ) -> std::optional< QByteArray >
static

Read path whole, as the regular file it is (openRegularFile()), when it holds at most maxBytes.

Parameters
pathThe file.
maxBytesThe most bytes accepted.
Returns
The contents; nothing when the file is missing, not a regular file (a link, FIFO or device included), unreadable or larger.

Definition at line 973 of file util.cpp.

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

◆ regularFilesUnder()

auto Util::regularFilesUnder ( const QString & dir,
const QStringList & nameFilters,
QStringList * skipped = nullptr,
bool hiddenFiles = false ) -> QStringList
static

Regular files under dir whose name matches one of nameFilters, found by walking only real directories.

Symbolic links and NTFS junctions are never entered and never listed: either can point outside the tree, and QDirIterator's own recursion treats a junction as an ordinary directory (Qt marks it JunctionType, not LinkType, so QDir::NoSymLinks does not see it). Hidden directories (.git, a sync tool's version folder) are not entered either, as with QDirIterator without QDir::Hidden.

dir itself is followed whatever it is: the configured store root is commonly a symlink (~/.password-store to a synced folder), and it is the user's choice, not something found inside the store. A caller that gets its folder from the store tree decides with isLinkedFolder() first.

The walk is a listing, not a lock: what is a regular file when listed can be replaced before it is opened. That is the store's trust boundary (SECURITY.md), not something a walk can close.

Parameters
dirDirectory to walk.
nameFiltersWildcards, as for QDir::setNameFilters().
skippedReceives what was left out although it is in the way: every linked directory, and every link or special file (FIFO, socket, device) whose name matches nameFilters. Null to not care.
hiddenFilesList hidden files too (.gpg-id); hidden directories stay closed regardless.
Returns
Absolute paths, sorted by name within each directory, a directory's files before its subdirectories.

Definition at line 721 of file util.cpp.

Here is the caller graph for this function:

◆ removeTree()

auto Util::removeTree ( const QString & dir) -> bool
static

Remove dir and everything in it, the way rm -rf does: a symbolic link or NTFS junction, dir itself or anything inside, is removed as an entry and what it points to is never entered. A trailing separator on dir does not change that.

QDir::removeRecursively() descends into junctions (it stops only at what Qt calls a symlink) and would empty the junction's target.

Parameters
dirDirectory to remove.
Returns
true when dir is gone.

Definition at line 1239 of file util.cpp.

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

◆ replaceFile()

auto Util::replaceFile ( const QString & from,
const QString & to,
bool replace ) -> bool
static

Give the file at from the name to, atomically and without following anything: the operating system's rename (rename(2), MoveFileEx), never QFile::rename(), whose fallback when the plain rename fails is to copy by opening to for writing, through whatever link sits under that name by then. With replace, whatever entry is at to (a file, a link) is replaced as an entry; without it, the call fails when anything is there (linkat(2) without AT_SYMLINK_FOLLOW and unlink on POSIX, where a no-replace rename is not portable; plain link(2) follows a symlink at from on macOS and the BSDs).

Parameters
fromAn existing regular file, on the same filesystem as to.
toThe name to give it.
replaceWhether an existing entry at to may go.
Returns
Whether to is now that file.

Definition at line 873 of file util.cpp.

Here is the caller graph for this function:

◆ repositoryPassClimbsTo()

auto Util::repositoryPassClimbsTo ( const QString & store) -> QString
static

The repository above store that pass itself would commit to, if any.

pass fences git in with GIT_CEILING_DIRECTORIES="$PREFIX/..", spelled as the store path is given, and unsets GIT_DIR and GIT_WORK_TREE. git splits that list on ":", so a colon anywhere in the path (above the store or in its own name) leaves no ceiling at the parent; a piece can still be a ceiling further up, which git keeps to, and so does this. A store without its own .git then finds a repository above it, and pass adds and commits there on every change, whether or not QtPass uses Git. QtPass cannot fence pass in from outside, so this is for a warning. Always empty on Windows, where pass runs in WSL.

Parameters
storeThe store's path, as PASSWORD_STORE_DIR gets it.
Returns
The folder holding that repository's .git; empty when pass keeps to the store.

Definition at line 146 of file util.cpp.

Here is the caller graph for this function:

◆ setGitOwnerForTests()

void Util::setGitOwnerForTests ( std::optional< uint > user)
static

For tests: the user gitStoreVariables() compares owners with when no asUser is given, in place of the effective user. A file owned by another user cannot be made without root.

Parameters
userThe user, or nothing to go back to the effective user.

Definition at line 284 of file util.cpp.

◆ stageFileReplacing()

auto Util::stageFileReplacing ( const QString & path,
bool replace,
const Filler & fill,
QString * error = nullptr ) -> bool
static

The staged write every file QtPass puts into a store goes through: a temporary created next to path (an opaque name, exclusive, owner-only), filled by fill through its open handle, synced, then replaceFile()d under the name, and the object under the name afterwards checked to be the very file that was filled (opened without following, compared by device and inode). The name is never opened for writing, so a link a co-writer plants under it between the caller's check and the write is replaced as an entry rather than written through (QSaveFile resolves such a link at open); a file swapped under the temporary's name before the rename (a hard link to something of the user's, say) is caught by the comparison and reported, and what is under the name is left (removing it by name could take another writer's file that landed there since). Where the system cannot give both identities the write stands: on FAT and exFAT a rename moves the file ID, and those filesystems have no hard links to swap in either.

Parameters
pathThe file to write.
replaceWhether an existing entry under the name may go.
fillWrites the contents.
errorReceives why not, if not null.
Returns
Whether path now holds what fill wrote.

Definition at line 1142 of file util.cpp.

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

◆ syncToDisk()

auto Util::syncToDisk ( QFileDevice & file) -> bool
static

Flush file's bytes to the device (fsync, FlushFileBuffers) before it is renamed into place, so that a crash right after the rename does not leave the name pointing at an empty file. QSaveFile did this on commit; the staged writes here do it themselves.

Parameters
fileAn open file.
Returns
Whether the data is on the device.

Definition at line 992 of file util.cpp.

◆ writeFileReplacing()

auto Util::writeFileReplacing ( const QString & path,
const QByteArray & bytes,
bool replace,
QString * error = nullptr ) -> bool
static

Write bytes as the file path through stageFileReplacing().

Parameters
pathThe file to write.
bytesIts contents.
replaceWhether an existing entry under the name may go.
errorReceives why not, if not null.
Returns
Whether path now holds bytes.

Definition at line 1165 of file util.cpp.

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

Member Data Documentation

◆ _env

QProcessEnvironment Util::_env
staticprivate

The environment findBinaryInPath() and findPasswordStore() read, as initialiseEnvironment() built it.

Definition at line 479 of file util.h.

◆ _envInitialised

bool Util::_envInitialised = false
staticprivate

Whether initialiseEnvironment() has run.

Definition at line 481 of file util.h.

◆ kMaxGpgIdBytes

qint64 Util::kMaxGpgIdBytes = 1024 * 1024
staticconstexpr

Most bytes of a .gpg-id QtPass reads.

A recipient list is a few lines; a shared store's other writers could otherwise hand it a sparse file of gigabytes to read before the signature is even checked. Far beyond any real list.

Definition at line 387 of file util.h.


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