mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2026-03-11 08:54:48 +00:00
Fixes #5290 Fixes #9062 Fixes #8545 * Fix data loss on failed reload - External modifications to the db file can no longer be missed. - Fixed dialogFinished signal of DatabaseOpenDialog was not emitted when dialog was closed via the 'X' (close) button - For reloading with a modified db, an additional choice has been added to allow the user to ignore the changes in the file on disk. - User is now presented with an unlock database dialog if reload fails to open the db automatically. For example when the user removed the YubiKey, failed to touch the YubiKey within the timeout period, or db pw has been changed. - Mark db as modified when db file is gone or invalid. - Prevent saving when db is being reloaded - If merge is triggered by a save action, continue on with the save action after the user makes their choice --------- Co-authored-by: vuurvlieg <vuurvli3g@protonmail.com> Co-authored-by: Jonathan White <support@dmapps.us>
101 lines
2.7 KiB
C++
101 lines
2.7 KiB
C++
/*
|
|
* Copyright (C) 2024 KeePassXC Team <team@keepassxc.org>
|
|
*
|
|
* 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 or (at your option)
|
|
* version 3 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "HashingStream.h"
|
|
|
|
HashingStream::HashingStream(QIODevice* baseDevice)
|
|
: LayeredStream(baseDevice)
|
|
, m_hash(QCryptographicHash::Md5)
|
|
, m_sizeToHash(0)
|
|
{
|
|
init();
|
|
}
|
|
|
|
HashingStream::HashingStream(QIODevice* baseDevice, QCryptographicHash::Algorithm hashAlgo, qint64 sizeToHash)
|
|
: LayeredStream(baseDevice)
|
|
, m_hash(hashAlgo)
|
|
, m_sizeToHash(sizeToHash)
|
|
{
|
|
init();
|
|
}
|
|
|
|
HashingStream::~HashingStream()
|
|
{
|
|
close();
|
|
}
|
|
|
|
void HashingStream::init()
|
|
{
|
|
m_sizeHashed = 0;
|
|
m_sizeStreamed = 0;
|
|
m_hashFinalized = false;
|
|
}
|
|
|
|
bool HashingStream::reset()
|
|
{
|
|
init();
|
|
m_hash.reset();
|
|
return LayeredStream::reset();
|
|
}
|
|
|
|
QByteArray HashingStream::hashingResult()
|
|
{
|
|
if (m_sizeHashed <= 0 || (m_sizeToHash > 0 && m_sizeHashed != m_sizeToHash)) {
|
|
setErrorString("Not enough data to compute hash");
|
|
return {};
|
|
}
|
|
m_hashFinalized = true;
|
|
return m_hash.result();
|
|
}
|
|
|
|
qint64 HashingStream::readData(char* data, qint64 maxSize)
|
|
{
|
|
auto sizeRead = LayeredStream::readData(data, maxSize);
|
|
if (sizeRead > 0) {
|
|
if (!m_hashFinalized) {
|
|
qint64 sizeToHash = sizeRead;
|
|
if (m_sizeToHash > 0) {
|
|
sizeToHash = qMin(m_sizeToHash - m_sizeStreamed, sizeRead);
|
|
}
|
|
if (sizeToHash > 0) {
|
|
m_hash.addData(data, sizeToHash);
|
|
m_sizeHashed += sizeToHash;
|
|
}
|
|
}
|
|
m_sizeStreamed += sizeRead;
|
|
}
|
|
return sizeRead;
|
|
}
|
|
|
|
qint64 HashingStream::writeData(const char* data, qint64 maxSize)
|
|
{
|
|
auto sizeWritten = LayeredStream::writeData(data, maxSize);
|
|
if (sizeWritten > 0) {
|
|
if (!m_hashFinalized) {
|
|
qint64 sizeToHash = sizeWritten;
|
|
if (m_sizeToHash > 0) {
|
|
sizeToHash = qMin(m_sizeToHash - m_sizeStreamed, sizeWritten);
|
|
}
|
|
if (sizeToHash > 0) {
|
|
m_hash.addData(data, sizeToHash);
|
|
m_sizeHashed += sizeToHash;
|
|
}
|
|
}
|
|
m_sizeStreamed += sizeWritten;
|
|
}
|
|
return sizeWritten;
|
|
}
|