diff --git a/transactions/kgpgdecrypt.cpp b/transactions/kgpgdecrypt.cpp index b53ef990..e2adbf51 100644 --- a/transactions/kgpgdecrypt.cpp +++ b/transactions/kgpgdecrypt.cpp @@ -1,139 +1,155 @@ /* * Copyright (C) 2010,2011,2012 Rolf Eike Beer */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kgpgdecrypt.h" #include "gpgproc.h" #include "kgpgsettings.h" #include KGpgDecrypt::KGpgDecrypt(QObject *parent, const QString &text) : KGpgTextOrFileTransaction(parent, text), m_fileIndex(-1), m_plainLength(-1) { } KGpgDecrypt::KGpgDecrypt(QObject *parent, const QList &files) : KGpgTextOrFileTransaction(parent, files), m_fileIndex(0), m_plainLength(-1) { } KGpgDecrypt::KGpgDecrypt(QObject* parent, const QUrl& infile, const QUrl& outfile) : KGpgTextOrFileTransaction(parent, QList({infile})), m_fileIndex(0), m_plainLength(-1), m_outFilename(outfile.toLocalFile()) { } KGpgDecrypt::~KGpgDecrypt() { } QStringList KGpgDecrypt::command() const { QStringList ret; ret << QLatin1String("--decrypt") << QLatin1String("--command-fd=0"); if (!m_outFilename.isEmpty()) ret << QLatin1String("-o") << m_outFilename; ret << KGpgSettings::customDecrypt().simplified().split(QLatin1Char(' '), QString::SkipEmptyParts); return ret; } QStringList KGpgDecrypt::decryptedText() const { QStringList result; int txtlength = 0; for (const QString &line : getMessages()) if (!line.startsWith(QLatin1String("[GNUPG:] "))) { result.append(line); txtlength += line.length() + 1; } if (result.isEmpty()) return result; QString last = result.last(); // this may happen when the original text did not end with a newline if (last.endsWith(QLatin1String("[GNUPG:] DECRYPTION_OKAY"))) { // if GnuPG doesn't tell us the length assume that this happend // if it told us the length then check if it _really_ happend if (((m_plainLength != -1) && (txtlength != m_plainLength)) || (m_plainLength == -1)) { last.chop(24); result[result.count() - 1] = last; } } return result; } bool KGpgDecrypt::isEncryptedText(const QString &text, int *startPos, int *endPos) { int posStart = text.indexOf(QLatin1String("-----BEGIN PGP MESSAGE-----")); if (posStart == -1) return false; int posEnd = text.indexOf(QLatin1String("-----END PGP MESSAGE-----"), posStart); if (posEnd == -1) return false; if (startPos != nullptr) *startPos = posStart; if (endPos != nullptr) *endPos = posEnd; return true; } bool KGpgDecrypt::nextLine(const QString& line) { const QList &inputFiles = getInputFiles(); - if (!inputFiles.isEmpty()) { + if (line == QLatin1String("[GNUPG:] DECRYPTION_OKAY")) { + // Assume Gpg decryption was successful even if gpg returns + // an error code. + decryptSuccess = true; + } else if (!inputFiles.isEmpty()) { if (line == QLatin1String("[GNUPG:] BEGIN_DECRYPTION")) { emit statusMessage(i18nc("Status message 'Decrypting ' (operation starts)", "Decrypting %1", inputFiles.at(m_fileIndex).fileName())); emit infoProgress(2 * m_fileIndex + 1, inputFiles.count() * 2); } else if (line == QLatin1String("[GNUPG:] END_DECRYPTION")) { emit statusMessage(i18nc("Status message 'Decrypted ' (operation was completed)", "Decrypted %1", inputFiles.at(m_fileIndex).fileName())); m_fileIndex++; emit infoProgress(2 * m_fileIndex, inputFiles.count() * 2); } } else { if (line.startsWith(QLatin1String("[GNUPG:] PLAINTEXT_LENGTH "))) { bool ok; m_plainLength = line.midRef(26).toInt(&ok); if (!ok) m_plainLength = -1; } else if (line == QLatin1String("[GNUPG:] BEGIN_DECRYPTION")) { // close the command channel (if any) to signal GnuPG that it // can start sending the output. getProcess()->closeWriteChannel(); } } return KGpgTextOrFileTransaction::nextLine(line); } + +void +KGpgDecrypt::finish() +{ + if (decryptSuccess) { + // Gpg error code is ignored. + // https://bugs.kde.org/show_bug.cgi?id=357462 + setSuccess(TS_OK); + } else { + KGpgTextOrFileTransaction::finish(); + } +} diff --git a/transactions/kgpgdecrypt.h b/transactions/kgpgdecrypt.h index 5ab59f53..5c4abe0a 100644 --- a/transactions/kgpgdecrypt.h +++ b/transactions/kgpgdecrypt.h @@ -1,85 +1,88 @@ /* * Copyright (C) 2010,2011 Rolf Eike Beer */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KGPGDECRYPT_H #define KGPGDECRYPT_H #include #include #include "kgpgtextorfiletransaction.h" class QStringList; /** * @brief decrypt the given text or files */ class KGpgDecrypt: public KGpgTextOrFileTransaction { Q_OBJECT Q_DISABLE_COPY(KGpgDecrypt) KGpgDecrypt() = delete; public: /** * @brief decrypt given text * @param parent parent object * @param text text to decrypt */ explicit KGpgDecrypt(QObject *parent, const QString &text = QString()); /** * @brief decrypt file(s) * @param parent parent object * @param files list of file locations to decrypt */ KGpgDecrypt(QObject *parent, const QList &files); /** * @brief decrypt file to given output filename * @param parent parent object * @param infile name of file to decrypt * @param outfile name of file to write output to (will be overwritten) */ KGpgDecrypt(QObject *parent, const QUrl &infile, const QUrl &outfile); /** * @brief destructor */ virtual ~KGpgDecrypt(); /** * @brief get decryption result * @return decrypted text */ QStringList decryptedText() const; /** * @brief check if the given text contains an encoded message * @param text text to check * @param startPos if not nullptr start offset of encoded text will be returned here * @param endPos if not nullptr end offset of encoded text will be returned here */ static bool isEncryptedText(const QString &text, int *startPos = nullptr, int *endPos = nullptr); protected: QStringList command() const override; bool nextLine(const QString &line) override; + void finish() override; + private: int m_fileIndex; int m_plainLength; ///< length of decrypted plain text if given by GnuPG const QString m_outFilename; ///< name of file to write output to + bool decryptSuccess = false; //< flag to determine if decryption succeeded }; #endif // KGPGDECRYPT_H