···
1
+
From c977424a1d39751fc5055131ad3f7819d421dcc8 Mon Sep 17 00:00:00 2001
2
+
From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= <dev@ingo-kloecker.de>
3
+
Date: Wed, 17 Aug 2022 14:51:19 +0200
4
+
Subject: [PATCH 1/5] qt: Make sure expiration time is interpreted as unsigned
7
+
* lang/qt/src/qgpgmeaddexistingsubkeyjob.cpp (add_subkey): Convert
8
+
expiration time to uint_least32_t.
11
+
This fixes the corresponding test on 32-bit systems where time_t (the
12
+
return type of expirationTime()) is a signed 32-bit integer type.
16
+
lang/qt/src/qgpgmeaddexistingsubkeyjob.cpp | 3 ++-
17
+
1 file changed, 2 insertions(+), 1 deletion(-)
19
+
diff --git a/lang/qt/src/qgpgmeaddexistingsubkeyjob.cpp b/lang/qt/src/qgpgmeaddexistingsubkeyjob.cpp
20
+
index 32e2c292..b74e7a06 100644
21
+
--- a/lang/qt/src/qgpgmeaddexistingsubkeyjob.cpp
22
+
+++ b/lang/qt/src/qgpgmeaddexistingsubkeyjob.cpp
23
+
@@ -64,7 +64,8 @@ static QGpgMEAddExistingSubkeyJob::result_type add_subkey(Context *ctx, const Ke
24
+
std::unique_ptr<GpgAddExistingSubkeyEditInteractor> interactor{new GpgAddExistingSubkeyEditInteractor{subkey.keyGrip()}};
26
+
if (!subkey.neverExpires()) {
27
+
- const auto expiry = QDateTime::fromSecsSinceEpoch(subkey.expirationTime(), Qt::UTC).toString(u"yyyyMMdd'T'hhmmss").toStdString();
28
+
+ const auto expiry = QDateTime::fromSecsSinceEpoch(uint_least32_t(subkey.expirationTime()),
29
+
+ Qt::UTC).toString(u"yyyyMMdd'T'hhmmss").toStdString();
30
+
interactor->setExpiry(expiry);
37
+
From 81d4b7f2d7077297d76af5728949d8f2bdff8cd5 Mon Sep 17 00:00:00 2001
38
+
From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= <dev@ingo-kloecker.de>
39
+
Date: Wed, 17 Aug 2022 14:56:13 +0200
40
+
Subject: [PATCH 2/5] qt,tests: Log the actual error code if the assertion
43
+
* lang/qt/tests/t-addexistingsubkey.cpp (
44
+
AddExistingSubkeyJobTest::testAddExistingSubkeyAsync,
45
+
AddExistingSubkeyJobTest::testAddExistingSubkeySync,
46
+
AddExistingSubkeyJobTest::testAddExistingSubkeyWithExpiration): Use
47
+
QCOMPARE instead of QVERIFY for asserting equality.
52
+
lang/qt/tests/t-addexistingsubkey.cpp | 6 +++---
53
+
1 file changed, 3 insertions(+), 3 deletions(-)
55
+
diff --git a/lang/qt/tests/t-addexistingsubkey.cpp b/lang/qt/tests/t-addexistingsubkey.cpp
56
+
index 589c90bf..2e654cec 100644
57
+
--- a/lang/qt/tests/t-addexistingsubkey.cpp
58
+
+++ b/lang/qt/tests/t-addexistingsubkey.cpp
59
+
@@ -168,7 +168,7 @@ private Q_SLOTS:
60
+
QSignalSpy spy (this, SIGNAL(asyncDone()));
61
+
QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
63
+
- QVERIFY(result.code() == GPG_ERR_NO_ERROR);
64
+
+ QCOMPARE(result.code(), static_cast<int>(GPG_ERR_NO_ERROR));
66
+
QCOMPARE(key.numSubkeys(), 3u);
68
+
@@ -190,7 +190,7 @@ private Q_SLOTS:
70
+
const auto result = job->exec(key, sourceSubkey);
72
+
- QVERIFY(result.code() == GPG_ERR_NO_ERROR);
73
+
+ QCOMPARE(result.code(), static_cast<int>(GPG_ERR_NO_ERROR));
75
+
QCOMPARE(key.numSubkeys(), 3u);
76
+
QCOMPARE(key.subkey(2).expirationTime(), 0);
77
+
@@ -213,7 +213,7 @@ private Q_SLOTS:
79
+
const auto result = job->exec(key, sourceSubkey);
81
+
- QVERIFY(result.code() == GPG_ERR_NO_ERROR);
82
+
+ QCOMPARE(result.code(), static_cast<int>(GPG_ERR_NO_ERROR));
84
+
QCOMPARE(key.numSubkeys(), 3u);
90
+
From f2b48de26b8f8c48c293423eda712831544924f6 Mon Sep 17 00:00:00 2001
91
+
From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= <dev@ingo-kloecker.de>
92
+
Date: Wed, 17 Aug 2022 15:22:29 +0200
93
+
Subject: [PATCH 3/5] qt,tests: Make sure expiration time is interpreted as
96
+
* lang/qt/tests/t-addexistingsubkey.cpp,
97
+
lang/qt/tests/t-changeexpiryjob.cpp: Convert expiration time to
101
+
This doesn't change the outcome of the tests (they also pass without
102
+
this change because of the expiration dates of the test keys), but it's
103
+
still good practise to treat the expiration time as an unsigned number
104
+
if the assertions check that the expiration time is in some range.
108
+
lang/qt/tests/t-addexistingsubkey.cpp | 6 +++---
109
+
lang/qt/tests/t-changeexpiryjob.cpp | 26 +++++++++++++-------------
110
+
2 files changed, 16 insertions(+), 16 deletions(-)
112
+
diff --git a/lang/qt/tests/t-addexistingsubkey.cpp b/lang/qt/tests/t-addexistingsubkey.cpp
113
+
index 2e654cec..87eadf43 100644
114
+
--- a/lang/qt/tests/t-addexistingsubkey.cpp
115
+
+++ b/lang/qt/tests/t-addexistingsubkey.cpp
116
+
@@ -222,9 +222,9 @@ private Q_SLOTS:
118
+
const auto allowedDeltaTSeconds = 1;
119
+
const auto expectedExpirationRange = std::make_pair(
120
+
- sourceSubkey.expirationTime() - allowedDeltaTSeconds,
121
+
- sourceSubkey.expirationTime() + allowedDeltaTSeconds);
122
+
- const auto actualExpiration = key.subkey(2).expirationTime();
123
+
+ uint_least32_t(sourceSubkey.expirationTime()) - allowedDeltaTSeconds,
124
+
+ uint_least32_t(sourceSubkey.expirationTime()) + allowedDeltaTSeconds);
125
+
+ const auto actualExpiration = uint_least32_t(key.subkey(2).expirationTime());
126
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
127
+
("actual: " + std::to_string(actualExpiration) +
128
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
129
+
diff --git a/lang/qt/tests/t-changeexpiryjob.cpp b/lang/qt/tests/t-changeexpiryjob.cpp
130
+
index 090002f3..3da74d46 100644
131
+
--- a/lang/qt/tests/t-changeexpiryjob.cpp
132
+
+++ b/lang/qt/tests/t-changeexpiryjob.cpp
133
+
@@ -70,7 +70,7 @@ private Q_SLOTS:
134
+
QVERIFY(!key.isNull());
135
+
QVERIFY(!key.subkey(0).isNull());
136
+
QVERIFY(!key.subkey(1).isNull());
137
+
- const auto subkeyExpiration = key.subkey(1).expirationTime();
138
+
+ const auto subkeyExpiration = uint_least32_t(key.subkey(1).expirationTime());
142
+
@@ -101,7 +101,7 @@ private Q_SLOTS:
143
+
newExpirationDate.toSecsSinceEpoch() - 10,
144
+
QDateTime::currentDateTime().addDays(1).toSecsSinceEpoch());
146
+
- const auto actualExpiration = key.subkey(0).expirationTime();
147
+
+ const auto actualExpiration = uint_least32_t(key.subkey(0).expirationTime());
148
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
149
+
("actual: " + std::to_string(actualExpiration) +
150
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
151
+
@@ -110,7 +110,7 @@ private Q_SLOTS:
152
+
"; expected: " + std::to_string(expectedExpirationRange.second)).c_str());
155
+
- const auto actualExpiration = key.subkey(1).expirationTime();
156
+
+ const auto actualExpiration = uint_least32_t(key.subkey(1).expirationTime());
157
+
QCOMPARE(actualExpiration, subkeyExpiration); // unchanged
160
+
@@ -133,7 +133,7 @@ private Q_SLOTS:
161
+
QVERIFY(!key.isNull());
162
+
QVERIFY(!key.subkey(0).isNull());
163
+
QVERIFY(!key.subkey(1).isNull());
164
+
- const auto primaryKeyExpiration = key.subkey(0).expirationTime();
165
+
+ const auto primaryKeyExpiration = uint_least32_t(key.subkey(0).expirationTime());
169
+
@@ -164,11 +164,11 @@ private Q_SLOTS:
170
+
newExpirationDate.toSecsSinceEpoch() - 10,
171
+
QDateTime::currentDateTime().addDays(2).toSecsSinceEpoch());
173
+
- const auto actualExpiration = key.subkey(0).expirationTime();
174
+
+ const auto actualExpiration = uint_least32_t(key.subkey(0).expirationTime());
175
+
QCOMPARE(actualExpiration, primaryKeyExpiration); // unchanged
178
+
- const auto actualExpiration = key.subkey(1).expirationTime();
179
+
+ const auto actualExpiration = uint_least32_t(key.subkey(1).expirationTime());
180
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
181
+
("actual: " + std::to_string(actualExpiration) +
182
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
183
+
@@ -196,7 +196,7 @@ private Q_SLOTS:
184
+
QVERIFY(!key.isNull());
185
+
QVERIFY(!key.subkey(0).isNull());
186
+
QVERIFY(!key.subkey(1).isNull());
187
+
- const auto subkeyExpiration = key.subkey(1).expirationTime();
188
+
+ const auto subkeyExpiration = uint_least32_t(key.subkey(1).expirationTime());
192
+
@@ -228,7 +228,7 @@ private Q_SLOTS:
193
+
newExpirationDate.toSecsSinceEpoch() - 10,
194
+
QDateTime::currentDateTime().addDays(3).toSecsSinceEpoch());
196
+
- const auto actualExpiration = key.subkey(0).expirationTime();
197
+
+ const auto actualExpiration = uint_least32_t(key.subkey(0).expirationTime());
198
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
199
+
("actual: " + std::to_string(actualExpiration) +
200
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
201
+
@@ -237,7 +237,7 @@ private Q_SLOTS:
202
+
"; expected: " + std::to_string(expectedExpirationRange.second)).c_str());
205
+
- const auto actualExpiration = key.subkey(1).expirationTime();
206
+
+ const auto actualExpiration = uint_least32_t(key.subkey(1).expirationTime());
207
+
QCOMPARE(actualExpiration, subkeyExpiration); // unchanged
210
+
@@ -291,7 +291,7 @@ private Q_SLOTS:
211
+
newExpirationDate.toSecsSinceEpoch() - 10,
212
+
QDateTime::currentDateTime().addDays(4).toSecsSinceEpoch());
214
+
- const auto actualExpiration = key.subkey(0).expirationTime();
215
+
+ const auto actualExpiration = uint_least32_t(key.subkey(0).expirationTime());
216
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
217
+
("actual: " + std::to_string(actualExpiration) +
218
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
219
+
@@ -300,7 +300,7 @@ private Q_SLOTS:
220
+
"; expected: " + std::to_string(expectedExpirationRange.second)).c_str());
223
+
- const auto actualExpiration = key.subkey(1).expirationTime();
224
+
+ const auto actualExpiration = uint_least32_t(key.subkey(1).expirationTime());
225
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
226
+
("actual: " + std::to_string(actualExpiration) +
227
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
228
+
@@ -359,7 +359,7 @@ private Q_SLOTS:
229
+
newExpirationDate.toSecsSinceEpoch() - 10,
230
+
QDateTime::currentDateTime().addDays(5).toSecsSinceEpoch());
232
+
- const auto actualExpiration = key.subkey(0).expirationTime();
233
+
+ const auto actualExpiration = uint_least32_t(key.subkey(0).expirationTime());
234
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
235
+
("actual: " + std::to_string(actualExpiration) +
236
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
237
+
@@ -368,7 +368,7 @@ private Q_SLOTS:
238
+
"; expected: " + std::to_string(expectedExpirationRange.second)).c_str());
241
+
- const auto actualExpiration = key.subkey(1).expirationTime();
242
+
+ const auto actualExpiration = uint_least32_t(key.subkey(1).expirationTime());
243
+
QVERIFY2(actualExpiration >= expectedExpirationRange.first,
244
+
("actual: " + std::to_string(actualExpiration) +
245
+
"; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
250
+
From 2fa5c80aeba4528b3bdf41ec5740e7db5d4b6d2b Mon Sep 17 00:00:00 2001
251
+
From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= <dev@ingo-kloecker.de>
252
+
Date: Thu, 18 Aug 2022 10:43:19 +0200
253
+
Subject: [PATCH 4/5] cpp: Fix handling of "no key" or "invalid time"
256
+
* lang/cpp/src/gpgaddexistingsubkeyeditinteractor.cpp
257
+
(GpgAddExistingSubkeyEditInteractor::Private::nextState): Fix inverted
258
+
logic of string comparisons.
261
+
This fixes the problem that the interactor didn't return the proper
262
+
error code if gpg didn't accept the key grip or the expiration date.
266
+
lang/cpp/src/gpgaddexistingsubkeyeditinteractor.cpp | 4 ++--
267
+
1 file changed, 2 insertions(+), 2 deletions(-)
269
+
diff --git a/lang/cpp/src/gpgaddexistingsubkeyeditinteractor.cpp b/lang/cpp/src/gpgaddexistingsubkeyeditinteractor.cpp
270
+
index 547e613d..8eec7460 100644
271
+
--- a/lang/cpp/src/gpgaddexistingsubkeyeditinteractor.cpp
272
+
+++ b/lang/cpp/src/gpgaddexistingsubkeyeditinteractor.cpp
273
+
@@ -136,7 +136,7 @@ unsigned int GpgAddExistingSubkeyEditInteractor::Private::nextState(unsigned int
274
+
strcmp(args, "keygen.flags") == 0) {
276
+
} else if (status == GPGME_STATUS_GET_LINE &&
277
+
- strcmp(args, "keygen.keygrip")) {
278
+
+ strcmp(args, "keygen.keygrip") == 0) {
279
+
err = NO_KEY_ERROR;
282
+
@@ -157,7 +157,7 @@ unsigned int GpgAddExistingSubkeyEditInteractor::Private::nextState(unsigned int
283
+
strcmp(args, "keyedit.prompt") == 0) {
285
+
} else if (status == GPGME_STATUS_GET_LINE &&
286
+
- strcmp(args, "keygen.valid")) {
287
+
+ strcmp(args, "keygen.valid") == 0) {
288
+
err = INV_TIME_ERROR;
295
+
From 2e7a61b898fccc1c20000b79dee83cd980901fa9 Mon Sep 17 00:00:00 2001
296
+
From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= <dev@ingo-kloecker.de>
297
+
Date: Thu, 18 Aug 2022 10:55:09 +0200
298
+
Subject: [PATCH 5/5] qt,tests: Make test pass on 32-bit systems
300
+
* lang/qt/tests/t-addexistingsubkey.cpp
301
+
(AddExistingSubkeyJobTest::testAddExistingSubkeyWithExpiration): Handle
302
+
negative expiration date.
305
+
On 32-bit systems the expiration date of the test key overflows. This
306
+
will cause the AddExistingSubkeyJob to fail. We expect it to fail with
307
+
an "invalid time" error.
311
+
lang/qt/tests/t-addexistingsubkey.cpp | 42 +++++++++++++++------------
312
+
1 file changed, 24 insertions(+), 18 deletions(-)
314
+
diff --git a/lang/qt/tests/t-addexistingsubkey.cpp b/lang/qt/tests/t-addexistingsubkey.cpp
315
+
index 87eadf43..c0eee57b 100644
316
+
--- a/lang/qt/tests/t-addexistingsubkey.cpp
317
+
+++ b/lang/qt/tests/t-addexistingsubkey.cpp
318
+
@@ -213,24 +213,30 @@ private Q_SLOTS:
320
+
const auto result = job->exec(key, sourceSubkey);
322
+
- QCOMPARE(result.code(), static_cast<int>(GPG_ERR_NO_ERROR));
324
+
- QCOMPARE(key.numSubkeys(), 3u);
326
+
- // allow 1 second different expiration because gpg calculates with
327
+
- // expiration as difference to current time and takes current time
329
+
- const auto allowedDeltaTSeconds = 1;
330
+
- const auto expectedExpirationRange = std::make_pair(
331
+
- uint_least32_t(sourceSubkey.expirationTime()) - allowedDeltaTSeconds,
332
+
- uint_least32_t(sourceSubkey.expirationTime()) + allowedDeltaTSeconds);
333
+
- const auto actualExpiration = uint_least32_t(key.subkey(2).expirationTime());
334
+
- QVERIFY2(actualExpiration >= expectedExpirationRange.first,
335
+
- ("actual: " + std::to_string(actualExpiration) +
336
+
- "; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
337
+
- QVERIFY2(actualExpiration <= expectedExpirationRange.second,
338
+
- ("actual: " + std::to_string(actualExpiration) +
339
+
- "; expected: " + std::to_string(expectedExpirationRange.second)).c_str());
340
+
+ if (sourceSubkey.expirationTime() > 0) {
341
+
+ QCOMPARE(result.code(), static_cast<int>(GPG_ERR_NO_ERROR));
343
+
+ QCOMPARE(key.numSubkeys(), 3u);
345
+
+ // allow 1 second different expiration because gpg calculates with
346
+
+ // expiration as difference to current time and takes current time
348
+
+ const auto allowedDeltaTSeconds = 1;
349
+
+ const auto expectedExpirationRange = std::make_pair(
350
+
+ uint_least32_t(sourceSubkey.expirationTime()) - allowedDeltaTSeconds,
351
+
+ uint_least32_t(sourceSubkey.expirationTime()) + allowedDeltaTSeconds);
352
+
+ const auto actualExpiration = uint_least32_t(key.subkey(2).expirationTime());
353
+
+ QVERIFY2(actualExpiration >= expectedExpirationRange.first,
354
+
+ ("actual: " + std::to_string(actualExpiration) +
355
+
+ "; expected: " + std::to_string(expectedExpirationRange.first)).c_str());
356
+
+ QVERIFY2(actualExpiration <= expectedExpirationRange.second,
357
+
+ ("actual: " + std::to_string(actualExpiration) +
358
+
+ "; expected: " + std::to_string(expectedExpirationRange.second)).c_str());
360
+
+ // on 32-bit systems the expiration date of the test key overflows;
361
+
+ // in this case we expect an appropriate error code
362
+
+ QCOMPARE(result.code(), static_cast<int>(GPG_ERR_INV_TIME));