Truncate file if it became smaller in all cases

This commit is contained in:
Martchus 2023-11-07 16:18:41 +01:00
parent 962054a3fe
commit 1f42f5fffb
3 changed files with 27 additions and 1 deletions

View File

@ -53,6 +53,7 @@ use_cpp_utilities(VISIBILITY PUBLIC)
include(3rdParty)
use_zlib()
use_crypto()
use_standard_filesystem()
# include modules to apply configuration
include(BasicConfig)

View File

@ -17,6 +17,7 @@
#include <zlib.h>
#include <cstring>
#include <filesystem>
#include <functional>
#include <limits>
#include <memory>
@ -400,7 +401,9 @@ void PasswordFile::save(PasswordFileSaveFlags options)
}
// use already opened and writable file; otherwise re-open the file
auto fileSize = std::size_t();
if (m_file.good() && m_file.is_open() && !(m_openOptions & PasswordFileOpenFlags::ReadOnly)) {
fileSize = size();
m_file.seekp(0);
} else {
m_file.clear();
@ -418,8 +421,16 @@ void PasswordFile::save(PasswordFileSaveFlags options)
}
}
// write entries
write(options);
m_file.flush();
// truncate file if it became smaller
const auto newSize = static_cast<std::size_t>(m_file.tellp());
if (fileSize && newSize < fileSize) {
m_file.close();
std::filesystem::resize_file(m_path, newSize);
}
}
/*!

View File

@ -208,7 +208,7 @@ void PasswordFileTests::testExtendedWriting()
CPPUNIT_ASSERT_EQUAL(""s, file.extendedHeader());
CPPUNIT_ASSERT_EQUAL(""s, file.encryptedExtendedHeader());
file.rootEntry()->setLabel("testfile2 - modified");
new AccountEntry("newAccount", file.rootEntry());
auto *const newAccount = new AccountEntry("newAccount", file.rootEntry());
file.setPassword("654321");
file.extendedHeader() = "foo";
file.encryptedExtendedHeader() = "bar";
@ -220,4 +220,18 @@ void PasswordFileTests::testExtendedWriting()
// check backup files
testReading("extended writing", testfile1 + ".backup", "123456", testfile2 + ".backup", string(), false, false);
// remove newAccount again to check what happens if the file size decreases
const auto fileSize = file.size();
delete newAccount;
file.save(PasswordFileSaveFlags::Encryption | PasswordFileSaveFlags::PasswordHashing);
file.close();
file.clearEntries();
file.open();
CPPUNIT_ASSERT_LESS(fileSize, file.size());
file.load();
auto path = std::list<std::string>{"newAccount"};
CPPUNIT_ASSERT(file.rootEntry());
CPPUNIT_ASSERT(!file.rootEntry()->entryByPath(path));
}