• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IJHack / QtPass / 23819309729

31 Mar 2026 09:03PM UTC coverage: 19.833% (+0.02%) from 19.817%
23819309729

Pull #870

github

web-flow
Merge a34388252 into 3a62426af
Pull Request #870: fix: modernize util.cpp - use range-based for loop

1000 of 5042 relevant lines covered (19.83%)

7.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.83
/src/util.cpp
1
// SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2
// SPDX-License-Identifier: GPL-3.0-or-later
3
#include "util.h"
4
#include <QDir>
5
#include <QFileInfo>
6
#ifdef Q_OS_WIN
7
#include <windows.h>
8
#else
9
#include <sys/time.h>
10
#endif
11
#include "qtpasssettings.h"
12

13
#ifdef QT_DEBUG
14
#include "debughelper.h"
15
#endif
16

17
QProcessEnvironment Util::_env;
18
bool Util::_envInitialised = false;
19

20
/**
21
 * @brief Util::initialiseEnvironment set the correct PATH for use with gpg, git
22
 * etc.
23
 */
24
void Util::initialiseEnvironment() {
5✔
25
  if (!_envInitialised) {
5✔
26
    _env = QProcessEnvironment::systemEnvironment();
1✔
27
#ifdef __APPLE__
28
    QString path = _env.value("PATH");
29
    if (!path.contains("/usr/local/MacGPG2/bin") &&
30
        QFile("/usr/local/MacGPG2/bin").exists())
31
      path += ":/usr/local/MacGPG2/bin";
32
    if (!path.contains("/usr/local/bin"))
33
      path += ":/usr/local/bin";
34
    _env.insert("PATH", path);
35
#endif
36
#ifdef Q_OS_WIN
37
    QString path = _env.value("PATH");
38
    if (!path.contains("C:\\Program Files\\WinGPG\\x86") &&
39
        QFile("C:\\Program Files\\WinGPG\\x86").exists())
40
      path += ";C:\\Program Files\\WinGPG\\x86";
41
    if (!path.contains("C:\\Program Files\\GnuPG\\bin") &&
42
        QFile("C:\\Program Files\\GnuPG\\bin").exists())
43
      path += ";C:\\Program Files\\GnuPG\\bin";
44
    _env.insert("PATH", path);
45
#endif
46
#ifdef QT_DEBUG
47
    dbg() << _env.value("PATH");
48
#endif
49
    _envInitialised = true;
1✔
50
  }
51
}
5✔
52

53
/**
54
 * @brief Util::findPasswordStore look for common .password-store folder
55
 * location.
56
 * @return
57
 */
58
auto Util::findPasswordStore() -> QString {
2✔
59
  QString path;
2✔
60
  initialiseEnvironment();
2✔
61
  if (_env.contains("PASSWORD_STORE_DIR")) {
4✔
62
    path = _env.value("PASSWORD_STORE_DIR");
×
63
  } else {
64
#ifdef Q_OS_WIN
65
    path = QDir::homePath() + QDir::separator() + "password-store" +
66
           QDir::separator();
67
#else
68
    path = QDir::homePath() + QDir::separator() + ".password-store" +
4✔
69
           QDir::separator();
70
#endif
71
  }
72
  return Util::normalizeFolderPath(path);
4✔
73
}
74

75
/**
76
 * @brief Util::normalizeFolderPath let's always end folders with a
77
 * QDir::separator()
78
 * @param path
79
 * @return
80
 */
81
auto Util::normalizeFolderPath(QString path) -> QString {
11✔
82
  if (!path.endsWith("/") && !path.endsWith(QDir::separator())) {
22✔
83
    path += QDir::separator();
6✔
84
  }
85
  return QDir::toNativeSeparators(path);
11✔
86
}
87

88
/**
89
 * @brief Locate an executable by searching the process PATH and (on Windows) falling back to WSL.
90
 *
91
 * @param binary Executable name or relative path to locate (e.g., "gpg" or "pass").
92
 * @return QString Absolute path to the executable if found, empty QString otherwise.
93
 */
94

95
/**
96
 * @brief Determine whether required configuration or executables are missing.
97
 *
98
 * @return bool `true` if the password store's `.gpg-id` is missing or the configured executable
99
 *              (pass or gpg, depending on settings) does not exist; `false` otherwise.
100
 */
101

102
/**
103
 * @brief Get the selected folder path, either relative to the configured pass store or absolute.
104
 *
105
 * @param index Model index selecting the file or folder.
106
 * @param forPass If true, return the path relative to the pass store; otherwise return an absolute path.
107
 * @param model Filesystem model used to resolve the index.
108
 * @param storeModel StoreModel used to map view indexes to the filesystem model.
109
 * @return QString Folder path that always ends with the native directory separator. Returns an empty
110
 *                 string when `index` is invalid and `forPass` is true; otherwise returns the pass store root.
111
 */
112

113
/**
114
 * @brief Returns a regex to match file names that end with ".gpg".
115
 *
116
 * @return const QRegularExpression& Reference to a static regex matching "\.gpg$".
117
 */
118

119
/**
120
 * @brief Returns a regex to match URL-like protocols and their following path.
121
 *
122
 * @return const QRegularExpression& Reference to a static regex matching protocols like
123
 *                                  http/https/ftp/ssh/sftp/ftps/webdav/webdavs followed by a path.
124
 */
125

126
/**
127
 * @brief Returns a regex to match carriage return or newline characters.
128
 *
129
 * @return const QRegularExpression& Reference to a static regex matching "\r" or "\n".
130
 */
131
auto Util::findBinaryInPath(QString binary) -> QString {
3✔
132
  initialiseEnvironment();
3✔
133

134
  QString ret;
3✔
135

136
  binary.prepend(QDir::separator());
3✔
137

138
  if (_env.contains("PATH")) {
6✔
139
    QString path = _env.value("PATH");
6✔
140

141
    QStringList entries;
3✔
142
#ifndef Q_OS_WIN
143
    entries = path.split(':');
6✔
144
    if (entries.length() < 2) {
3✔
145
#endif
146
      entries = path.split(';');
×
147
#ifndef Q_OS_WIN
148
    }
149
#endif
150

151
    for (const QString &entryConst : entries) {
57✔
152
      QString fullPath = entryConst + binary;
52✔
153
      QScopedPointer<QFileInfo> qfi(new QFileInfo(fullPath));
52✔
154
#ifdef Q_OS_WIN
155
      if (!qfi->exists()) {
156
        QString fullPathExe = fullPath + ".exe";
157
        qfi.reset(new QFileInfo(fullPathExe));
158
      }
159

160
#endif
161
      if (!qfi->isExecutable()) {
52✔
162
        continue;
163
      }
164

165
      ret = qfi->absoluteFilePath();
2✔
166
      break;
167
    }
168
  }
169
#ifdef Q_OS_WIN
170
  if (ret.isEmpty()) {
171
    binary.remove(0, 1);
172
    binary.prepend("wsl ");
173
    QString out, err;
174
    if (Executor::executeBlocking(binary, {"--version"}, &out, &err) == 0 &&
175
        !out.isEmpty() && err.isEmpty())
176
      ret = binary;
177
  }
178
#endif
179

180
  return ret;
3✔
181
}
182

183
/**
184
 * @brief Util::checkConfig do we have prerequisite settings?
185
 * @return
186
 */
187
auto Util::checkConfig() -> bool {
1✔
188
  return !QFile(QDir(QtPassSettings::getPassStore()).filePath(".gpg-id"))
2✔
189
              .exists() ||
1✔
190
         (QtPassSettings::isUsePass()
1✔
191
              ? !QtPassSettings::getPassExecutable().startsWith("wsl ") &&
1✔
192
                    !QFile(QtPassSettings::getPassExecutable()).exists()
1✔
193
              : !QtPassSettings::getGpgExecutable().startsWith("wsl ") &&
1✔
194
                    !QFile(QtPassSettings::getGpgExecutable()).exists());
2✔
195
}
196

197
/**
198
 * @brief Util::getDir get selected folder path
199
 * @param index
200
 * @param forPass short or full path
201
 * @param model the filesystem model to operate on
202
 * @param storeModel our storemodel to operate on
203
 * @return path
204
 */
205
auto Util::getDir(const QModelIndex &index, bool forPass,
3✔
206
                  const QFileSystemModel &model, const StoreModel &storeModel)
207
    -> QString {
208
  QString abspath =
209
      QDir(QtPassSettings::getPassStore()).absolutePath() + QDir::separator();
9✔
210
  if (!index.isValid()) {
211
    return forPass ? "" : abspath;
2✔
212
  }
213
  QFileInfo info = model.fileInfo(storeModel.mapToSource(index));
1✔
214
  QString filePath =
215
      (info.isFile() ? info.absolutePath() : info.absoluteFilePath());
1✔
216
  if (forPass) {
1✔
217
    filePath = QDir(abspath).relativeFilePath(filePath);
×
218
  }
219
  filePath += QDir::separator();
1✔
220
  return filePath;
221
}
1✔
222

223
/**
224
 * @brief Returns a regex to match .gpg file extensions.
225
 * @return Reference to static regex
226
 */
227
auto Util::endsWithGpg() -> const QRegularExpression & {
22✔
228
  static const QRegularExpression expr{"\\.gpg$"};
22✔
229
  return expr;
22✔
230
}
231

232
/**
233
 * @brief Returns a regex to match URL protocols.
234
 * @return Reference to static regex
235
 */
236
auto Util::protocolRegex() -> const QRegularExpression & {
3✔
237
  static const QRegularExpression regex{
238
      "((?:https?|ftp|ssh|sftp|ftps|webdav|webdavs)://[^\" <>\\)\\]\\[]+)"};
3✔
239
  return regex;
3✔
240
}
241

242
/**
243
 * @brief Returns a regex to match newline characters.
244
 * @return Reference to static regex
245
 */
246
auto Util::newLinesRegex() -> const QRegularExpression & {
2✔
247
  static const QRegularExpression regex{"[\r\n]"};
2✔
248
  return regex;
2✔
249
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc