Don't write final block(s) if we already have.

This commit is contained in:
Felix Geyer 2015-07-20 21:02:57 +02:00
parent 61503a8047
commit abe5e8ecea
3 changed files with 27 additions and 12 deletions

View File

@ -54,7 +54,9 @@ void HashedBlockStream::init()
bool HashedBlockStream::reset() 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 (!m_buffer.isEmpty()) {
if (!writeHashedBlock()) { if (!writeHashedBlock()) {
return false; return false;
@ -74,7 +76,9 @@ bool HashedBlockStream::reset()
void HashedBlockStream::close() 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()) { if (!m_buffer.isEmpty()) {
writeHashedBlock(); writeHashedBlock();
} }

View File

@ -25,6 +25,7 @@ SymmetricCipherStream::SymmetricCipherStream(QIODevice* baseDevice, SymmetricCip
, m_bufferFilling(false) , m_bufferFilling(false)
, m_error(false) , m_error(false)
, m_isInitalized(false) , m_isInitalized(false)
, m_dataWritten(false)
{ {
} }
@ -43,6 +44,16 @@ bool SymmetricCipherStream::init(const QByteArray& key, const QByteArray& iv)
return m_isInitalized; 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) bool SymmetricCipherStream::open(QIODevice::OpenMode mode)
{ {
if (!m_isInitalized) { if (!m_isInitalized) {
@ -54,27 +65,25 @@ bool SymmetricCipherStream::open(QIODevice::OpenMode mode)
bool SymmetricCipherStream::reset() bool SymmetricCipherStream::reset()
{ {
if (isWritable()) { if (isWritable() && m_dataWritten) {
if (!writeBlock(true)) { if (!writeBlock(true)) {
return false; return false;
} }
} }
m_buffer.clear(); resetInternalState();
m_bufferPos = 0;
m_bufferFilling = false;
m_error = false;
m_cipher->reset();
return true; return true;
} }
void SymmetricCipherStream::close() void SymmetricCipherStream::close()
{ {
if (isWritable()) { if (isWritable() && m_dataWritten) {
writeBlock(true); writeBlock(true);
} }
resetInternalState();
LayeredStream::close(); LayeredStream::close();
} }
@ -186,6 +195,7 @@ qint64 SymmetricCipherStream::writeData(const char* data, qint64 maxSize)
return -1; return -1;
} }
m_dataWritten = true;
qint64 bytesRemaining = maxSize; qint64 bytesRemaining = maxSize;
qint64 offset = 0; qint64 offset = 0;
@ -214,6 +224,8 @@ qint64 SymmetricCipherStream::writeData(const char* data, qint64 maxSize)
bool SymmetricCipherStream::writeBlock(bool lastBlock) bool SymmetricCipherStream::writeBlock(bool lastBlock)
{ {
Q_ASSERT(lastBlock || (m_buffer.size() == m_cipher->blockSize()));
if (lastBlock) { if (lastBlock) {
// PKCS7 padding // PKCS7 padding
int padLen = m_cipher->blockSize() - m_buffer.size(); int padLen = m_cipher->blockSize() - m_buffer.size();
@ -221,9 +233,6 @@ bool SymmetricCipherStream::writeBlock(bool lastBlock)
m_buffer.append(static_cast<char>(padLen)); m_buffer.append(static_cast<char>(padLen));
} }
} }
else if (m_buffer.isEmpty()) {
return true;
}
if (!m_cipher->processInPlace(m_buffer)) { if (!m_cipher->processInPlace(m_buffer)) {
m_error = true; m_error = true;

View File

@ -42,6 +42,7 @@ protected:
qint64 writeData(const char* data, qint64 maxSize) Q_DECL_OVERRIDE; qint64 writeData(const char* data, qint64 maxSize) Q_DECL_OVERRIDE;
private: private:
void resetInternalState();
bool readBlock(); bool readBlock();
bool writeBlock(bool lastBlock); bool writeBlock(bool lastBlock);
@ -51,6 +52,7 @@ private:
bool m_bufferFilling; bool m_bufferFilling;
bool m_error; bool m_error;
bool m_isInitalized; bool m_isInitalized;
bool m_dataWritten;
}; };
#endif // KEEPASSX_SYMMETRICCIPHERSTREAM_H #endif // KEEPASSX_SYMMETRICCIPHERSTREAM_H