diff options
| author | saturneric <[email protected]> | 2026-09-14 23:02:44 +0200 |
|---|---|---|
| committer | saturneric <[email protected]> | 2026-09-14 23:02:44 +0200 |
| commit | 8cc5f09dbd09eff076901a3b497a206e23c2c690 (patch) | |
| tree | 9184c9093c06ac6ad9be0ce005903c5384a88db6 /src | |
| parent | fix(email): free verification error string (diff) | |
| download | modules-8cc5f09dbd09eff076901a3b497a206e23c2c690.tar.gz modules-8cc5f09dbd09eff076901a3b497a206e23c2c690.zip | |
refactor(email): migrate to list-based GPG APIs
- replace raw recipient and address arrays with SDK list handles
- use borrowed accessors with centralized list release
- update key lookup rendering to consume key brief lists safely
Diffstat (limited to 'src')
| -rw-r--r-- | src/m_email/EMailPageView.cpp | 72 | ||||
| -rw-r--r-- | src/m_email/EMailSecurityView.cpp | 39 |
2 files changed, 60 insertions, 51 deletions
diff --git a/src/m_email/EMailPageView.cpp b/src/m_email/EMailPageView.cpp index b8bcb4a..f1511a7 100644 --- a/src/m_email/EMailPageView.cpp +++ b/src/m_email/EMailPageView.cpp @@ -29,7 +29,9 @@ #include "EMailPageView.h" #include <GFSDKGpg.h> +#include <GFSDKGpgList.h> +#include <GFSDKBuffer.hpp> #include <QAbstractItemView> #include <QApplication> #include <QButtonGroup> @@ -1934,27 +1936,28 @@ void EMailPageView::refresh_locked_capability(const QStringList& named) { // for mail encrypted to someone else who happened to share an address. const auto* ciphertext = FindEncryptedCiphertextPart(tree_root_); if (ciphertext != nullptr) { - GFGpgEncRecipient* raw = nullptr; - int count = 0; - if (GFGpgSniffEncryptedRecipients( - GFGpgCurrentGpgContextChannel(), ciphertext->data.constData(), - static_cast<int>(ciphertext->data.size()), &raw, &count) == 0) { + auto in = GFBuf::Copy(ciphertext->data); + GFGpgRecipientListRef list = nullptr; + if (GFGpgSniffRecipients(GFGpgCurrentGpgContextChannel(), in.View(), + &list) == 0) { + const auto count = GFGpgRecipientListCount(list); QList<EMailEncRecipient> recipients; - recipients.reserve(count); - for (int i = 0; i < count; ++i) { - // Copied rather than taken: these strings belong to the array that - // GFGpgFreeEncRecipients releases as a whole. + recipients.reserve(static_cast<qsizetype>(count)); + for (size_t i = 0; i < count; ++i) { + // Copied rather than taken: every accessor here returns a BORROWED + // pointer that dies with the list. There is no per-element free to + // get wrong, and no count to hand back on release. recipients.append(EMailEncRecipient{ - QString::fromUtf8(raw[i].key_id), - QString::fromUtf8(raw[i].pub_algo), - QString::fromUtf8(raw[i].fingerprint), - QString::fromUtf8(raw[i].uid), - raw[i].key_found != 0, - raw[i].has_secret != 0, - raw[i].hidden != 0, + QString::fromUtf8(GFGpgRecipientKeyId(list, i)), + QString::fromUtf8(GFGpgRecipientPubAlgo(list, i)), + QString::fromUtf8(GFGpgRecipientFingerprint(list, i)), + QString::fromUtf8(GFGpgRecipientUid(list, i)), + GFGpgRecipientKeyFound(list, i) != 0, + GFGpgRecipientHasSecret(list, i) != 0, + GFGpgRecipientHidden(list, i) != 0, }); } - GFGpgFreeEncRecipients(raw, count); + GFGpgRecipientListRelease(list); if (!recipients.isEmpty()) { show_decrypt_capability(DescribeDecryptCapability(recipients)); @@ -2014,20 +2017,20 @@ void EMailPageView::refresh_locked_capability_by_address( // the key a message is encrypted to need not carry any of these addresses -- // so it is reached only when the message itself could not be read, and every // wording below is hedged accordingly. - char** addresses = nullptr; - int count = 0; - if (GFGpgListKeyAddresses(GFGpgCurrentGpgContextChannel(), 1, &addresses, - &count) != 0) { + GFStringListRef addresses = nullptr; + if (GFGpgListAddresses(GFGpgCurrentGpgContextChannel(), 1, &addresses) != 0) { locked_capability_->setVisible(false); return; } QStringList mine; - for (int i = 0; i < count; ++i) { - const auto address = AddressOfUid(QString::fromUtf8(addresses[i])); + const auto count = GFStringListCount(addresses); + for (size_t i = 0; i < count; ++i) { + const auto address = + AddressOfUid(QString::fromUtf8(GFStringListAt(addresses, i))); if (!address.isEmpty()) mine.append(address.toLower()); } - GFGpgFreeStringArray(addresses, count); + GFStringListRelease(addresses); // Nothing knowable either way: no recipient is named, or the keyring holds // no private key at all. Saying something in that case would be inventing @@ -2358,20 +2361,21 @@ void EMailPageView::refresh_send_state() { */ void EMailPageView::install_address_hints() { const auto addresses = [](bool secret_only) { - char** raw = nullptr; - int count = 0; - if (GFGpgListKeyAddresses(GFGpgCurrentGpgContextChannel(), - secret_only ? 1 : 0, &raw, &count) != 0) { + GFStringListRef raw = nullptr; + if (GFGpgListAddresses(GFGpgCurrentGpgContextChannel(), secret_only ? 1 : 0, + &raw) != 0) { return QStringList{}; } + const auto count = GFStringListCount(raw); QStringList out; - out.reserve(count); - // Copied rather than taken: UnStrDup FREES what it is handed, and these - // strings belong to the array that GFGpgFreeStringArray releases as a - // whole. - for (int i = 0; i < count; ++i) out.append(QString::fromUtf8(raw[i])); - GFGpgFreeStringArray(raw, count); + out.reserve(static_cast<qsizetype>(count)); + // Copied rather than taken: the accessor returns a BORROWED pointer that + // dies with the list, which goes back in a single release below. + for (size_t i = 0; i < count; ++i) { + out.append(QString::fromUtf8(GFStringListAt(raw, i))); + } + GFStringListRelease(raw); return out; }; diff --git a/src/m_email/EMailSecurityView.cpp b/src/m_email/EMailSecurityView.cpp index 3b6e15c..2f32af5 100644 --- a/src/m_email/EMailSecurityView.cpp +++ b/src/m_email/EMailSecurityView.cpp @@ -29,6 +29,7 @@ #include "EMailSecurityView.h" #include <GFSDKGpg.h> +#include <GFSDKGpgList.h> #include <QAbstractItemView> #include <QApplication> @@ -529,9 +530,11 @@ void EMailSecurityView::add_key_section(const QStringList& addresses, if (email.isEmpty() || seen.contains(email)) continue; seen.append(email); - GFGpgKeyBrief* briefs = nullptr; - int count = 0; - GFGpgFindKeysByEmail(channel, email.toUtf8().constData(), &briefs, &count); + // The address stays ours: every SDK argument is borrowed, so the + // QByteArray below is safe to let die at the end of the statement. + GFGpgKeyBriefListRef briefs = nullptr; + GFGpgFindKeys(channel, email.toUtf8().constData(), &briefs); + const auto count = static_cast<int>(GFGpgKeyBriefListCount(briefs)); auto* item = new QTreeWidgetItem(group); item->setText(kColItem, email); @@ -542,31 +545,33 @@ void EMailSecurityView::add_key_section(const QStringList& addresses, // Recorded on the row so the menu knows this is an address with nothing // behind it, which is the one case where importing is worth offering. item->setData(kColItem, kRoleMissingKey, true); - GFGpgFreeKeyBriefs(briefs, count); + GFGpgKeyBriefListRelease(briefs); continue; } item->setText(kColValue, count == 1 ? tr("1 key") : tr("%1 keys").arg(count)); - for (int i = 0; i < count; ++i) { - const auto& brief = briefs[i]; - + for (size_t i = 0; i < static_cast<size_t>(count); ++i) { + // Borrowed accessors throughout: nothing here is separately releasable, + // so the whole list goes back in one call at the end. auto* key_item = new QTreeWidgetItem(item); - key_item->setText(kColItem, QString::fromUtf8(brief.uid)); + key_item->setText(kColItem, + QString::fromUtf8(GFGpgKeyBriefUid(briefs, i))); // Usability. Says whether the key can be used at all -- and nothing // whatsoever about whose key it is. - key_item->setText( - kColValue, tr("key is %1").arg(DescribeUsability(brief.usability))); + const auto usability = GFGpgKeyBriefUsability(briefs, i); + key_item->setText(kColValue, + tr("key is %1").arg(DescribeUsability(usability))); EMailSetCellTone( key_item, kColValue, - brief.usability == kUSABLE ? EMailTone::kGOOD : EMailTone::kWARN, - this); + usability == kUSABLE ? EMailTone::kGOOD : EMailTone::kWARN, this); auto* fpr = new QTreeWidgetItem(key_item); fpr->setText(kColItem, tr("Fingerprint")); - fpr->setText(kColValue, QString::fromUtf8(brief.fingerprint)); + fpr->setText(kColValue, + QString::fromUtf8(GFGpgKeyBriefFingerprint(briefs, i))); EMailSetCellTone(fpr, kColItem, EMailTone::kMUTED, this); // Identity binding, kept as its own row. A usable key carrying this @@ -574,11 +579,11 @@ void EMailSecurityView::add_key_section(const QStringList& addresses, // single combined verdict would bury. auto* identity = new QTreeWidgetItem(key_item); identity->setText(kColItem, tr("Identity")); - if (brief.matched_uid_revoked != 0) { + if (GFGpgKeyBriefMatchedUidRevoked(briefs, i) != 0) { identity->setText( kColValue, tr("this address is on a REVOKED user ID of the key")); EMailSetCellTone(identity, kColValue, EMailTone::kWARN, this); - } else if (brief.matched_uid_is_primary != 0) { + } else if (GFGpgKeyBriefMatchedUidIsPrimary(briefs, i) != 0) { identity->setText(kColValue, tr("this address is the key's primary " "user ID")); EMailSetCellTone(identity, kColValue, EMailTone::kGOOD, this); @@ -588,7 +593,7 @@ void EMailSecurityView::add_key_section(const QStringList& addresses, EMailSetCellTone(identity, kColValue, EMailTone::kMUTED, this); } - if (brief.can_encrypt == 0) { + if (GFGpgKeyBriefCanEncrypt(briefs, i) == 0) { auto* note = new QTreeWidgetItem(key_item); note->setText(kColItem, tr("Note")); note->setText(kColValue, tr("this key cannot be used for encryption")); @@ -596,7 +601,7 @@ void EMailSecurityView::add_key_section(const QStringList& addresses, } } - GFGpgFreeKeyBriefs(briefs, count); + GFGpgKeyBriefListRelease(briefs); } } |
