From abe5e8ecea0325176440765df5b1e1af86f4e292 Mon Sep 17 00:00:00 2001 From: Felix Geyer Date: Mon, 20 Jul 2015 21:02:57 +0200 Subject: [PATCH] Don't write final block(s) if we already have. --- src/streams/HashedBlockStream.cpp | 8 ++++++-- src/streams/SymmetricCipherStream.cpp | 29 ++++++++++++++++++--------- src/streams/SymmetricCipherStream.h | 2 ++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/streams/HashedBlockStream.cpp b/src/streams/HashedBlockStream.cpp index cd43dc0bf..ec59769aa 100644 --- a/src/streams/HashedBlockStream.cpp +++ b/src/streams/HashedBlockStream.cpp @@ -54,7 +54,9 @@ void HashedBlockStream::init() bool HashedBlockStream::reset() { - if (isWritable()) { + // Write final block(s) only if device is writable and we haven't + // already written a final block. + if (isWritable() && (!m_buffer.isEmpty() || m_blockIndex != 0)) { if (!m_buffer.isEmpty()) { if (!writeHashedBlock()) { return false; @@ -74,7 +76,9 @@ bool HashedBlockStream::reset() void HashedBlockStream::close() { - if (isWritable()) { + // Write final block(s) only if device is writable and we haven't + // already written a final block. + if (isWritable() && (!m_buffer.isEmpty() || m_blockIndex != 0)) { if (!m_buffer.isEmpty()) { writeHashedBlock(); } diff --git a/src/streams/SymmetricCipherStream.cpp b/src/streams/SymmetricCipherStream.cpp index d230920f2..643aa0339 100644 --- a/src/streams/SymmetricCipherStream.cpp +++ b/src/streams/SymmetricCipherStream.cpp @@ -25,6 +25,7 @@ SymmetricCipherStream::SymmetricCipherStream(QIODevice* baseDevice, SymmetricCip , m_bufferFilling(false) , m_error(false) , m_isInitalized(false) + , m_dataWritten(false) { } @@ -43,6 +44,16 @@ bool SymmetricCipherStream::init(const QByteArray& key, const QByteArray& iv) return m_isInitalized; } +void SymmetricCipherStream::resetInternalState() +{ + m_buffer.clear(); + m_bufferPos = 0; + m_bufferFilling = false; + m_error = false; + m_dataWritten = false; + m_cipher->reset(); +} + bool SymmetricCipherStream::open(QIODevice::OpenMode mode) { if (!m_isInitalized) { @@ -54,27 +65,25 @@ bool SymmetricCipherStream::open(QIODevice::OpenMode mode) bool SymmetricCipherStream::reset() { - if (isWritable()) { + if (isWritable() && m_dataWritten) { if (!writeBlock(true)) { return false; } } - m_buffer.clear(); - m_bufferPos = 0; - m_bufferFilling = false; - m_error = false; - m_cipher->reset(); + resetInternalState(); return true; } void SymmetricCipherStream::close() { - if (isWritable()) { + if (isWritable() && m_dataWritten) { writeBlock(true); } + resetInternalState(); + LayeredStream::close(); } @@ -186,6 +195,7 @@ qint64 SymmetricCipherStream::writeData(const char* data, qint64 maxSize) return -1; } + m_dataWritten = true; qint64 bytesRemaining = maxSize; qint64 offset = 0; @@ -214,6 +224,8 @@ qint64 SymmetricCipherStream::writeData(const char* data, qint64 maxSize) bool SymmetricCipherStream::writeBlock(bool lastBlock) { + Q_ASSERT(lastBlock || (m_buffer.size() == m_cipher->blockSize())); + if (lastBlock) { // PKCS7 padding int padLen = m_cipher->blockSize() - m_buffer.size(); @@ -221,9 +233,6 @@ bool SymmetricCipherStream::writeBlock(bool lastBlock) m_buffer.append(static_cast(padLen)); } } - else if (m_buffer.isEmpty()) { - return true; - } if (!m_cipher->processInPlace(m_buffer)) { m_error = true; diff --git a/src/streams/SymmetricCipherStream.h b/src/streams/SymmetricCipherStream.h index c1865babc..fa446053f 100644 --- a/src/streams/SymmetricCipherStream.h +++ b/src/streams/SymmetricCipherStream.h @@ -42,6 +42,7 @@ protected: qint64 writeData(const char* data, qint64 maxSize) Q_DECL_OVERRIDE; private: + void resetInternalState(); bool readBlock(); bool writeBlock(bool lastBlock); @@ -51,6 +52,7 @@ private: bool m_bufferFilling; bool m_error; bool m_isInitalized; + bool m_dataWritten; }; #endif // KEEPASSX_SYMMETRICCIPHERSTREAM_H