[pim/kleopatra] src/crypto: Don't report successful decryption if decrypted file doesn't exist

Ingo Klöcker <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 1e07ddd4fcf64a94e0d53bf32c3f5627c9895f6b by Ingo Klöcker, on behalf of Ingo Klöcker.
Committed on 06/08/2026 at 14:24.
Pushed by kloecker into branch 'master'.

Don't report successful decryption if decrypted file doesn't exist

Some errors (e.g. out of disk space) are not correctly registered by
GpgME so that GpgME reports successful decryption although an error
occurred. GnuPG 2.5.21 removes partial results if an error occurred.
If the decrypted file doesn't exist although GpgME reported success, we
can assume that something has gone wrong and inform the user pointing
them to the GnuPG log for details.

GnuPG-bug-id: 8398

M  +10   -0    src/crypto/decryptverifytask.cpp

https://invent.kde.org/pim/kleopatra/-/commit/1e07ddd4fcf64a94e0d53bf32c3f5627c9895f6b

diff --git a/src/crypto/decryptverifytask.cpp b/src/crypto/decryptverifytask.cpp
index 5a4ee3faa..a4936ed53 100644
--- a/src/crypto/decryptverifytask.cpp
+++ b/src/crypto/decryptverifytask.cpp
@@ -284,6 +284,9 @@ public:
         } else if (error.code() == GPG_ERR_NO_SECKEY) {
             label += u' ' + Formatting::errorAsString(error) + u'.';
             label += "<br />"_L1 + i18nc("@info", "The data was not encrypted for any secret key in your certificate list.");
+        } else if ((error.code() == GPG_ERR_ENOENT) && (error.sourceID() == GPG_ERR_SOURCE_KLEO)) {
+            // handle our own error code that's used if the decrypted file doesn't exist although gpgme reported successful decryption
+            label += u' ' + i18nc("@info Diagnostics is the label of a button", "An unknown error occurred. Please check Diagnostics for details.");
         } else if (m_decryptionResult.isLegacyCipherNoMDC()) {
             label += u' ' + i18n("No integrity protection (MDC).");
         } else if (!m_errorString.isEmpty()) {
@@ -759,6 +762,13 @@ void DecryptVerifyTask::Private::slotResult(const DecryptionResult &dr, const Ve
         q->emitResult(q->fromDecryptResult(drErr ? dr.error() : Error::fromCode(GPG_ERR_EIO), errorString, auditLog));
         return;
     }
+    // double check that the decrypted file exists after (seemingly) successful decryption
+    if (!dr.isNull() && dr.error().isSuccess() && !m_extractArchive && !m_output && !m_outputFilePath.isEmpty() && !QFile::exists(m_outputFilePath)) {
+        DecryptionResult newDr{dr};
+        newDr.setError(Error::fromCode(GPG_ERR_ENOENT));
+        q->emitResult(q->fromDecryptVerifyResult(newDr, vr, plainText, m_output ? m_output->fileName() : m_outputFilePath, auditLog));
+        return;
+    }
 
     q->emitResult(q->fromDecryptVerifyResult(dr, vr, plainText, m_output ? m_output->fileName() : m_outputFilePath, auditLog));
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.