Properly save custom header data
Ensure adding custom data upgrades to KDBX4 Implement review feedback
This commit is contained in:
@@ -33,7 +33,6 @@ QTEST_GUILESS_MAIN(TestKdbx3)
|
||||
|
||||
void TestKdbx3::initTestCaseImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Database* TestKdbx3::readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString)
|
||||
|
||||
@@ -131,6 +131,7 @@ void TestKdbx4::testFormat400Upgrade()
|
||||
{
|
||||
QFETCH(Uuid, kdfUuid);
|
||||
QFETCH(Uuid, cipherUuid);
|
||||
QFETCH(bool, addCustomData);
|
||||
QFETCH(quint32, expectedVersion);
|
||||
|
||||
QScopedPointer<Database> sourceDb(new Database());
|
||||
@@ -147,6 +148,12 @@ void TestKdbx4::testFormat400Upgrade()
|
||||
// upgrade to KDBX 4 by changing KDF and Cipher
|
||||
sourceDb->changeKdf(KeePass2::uuidToKdf(kdfUuid));
|
||||
sourceDb->setCipher(cipherUuid);
|
||||
|
||||
if (addCustomData) {
|
||||
sourceDb->metadata()->customData()->set("CustomPublicData", "Hey look, I turned myself into a pickle!");
|
||||
sourceDb->rootGroup()->customData()->set("CustomGroupData", "I just killed my family! I don't care who they were!");
|
||||
}
|
||||
|
||||
KeePass2Writer writer;
|
||||
writer.writeDatabase(&buffer, sourceDb.data());
|
||||
if (writer.hasError()) {
|
||||
@@ -165,26 +172,39 @@ void TestKdbx4::testFormat400Upgrade()
|
||||
QCOMPARE(targetDb->metadata()->name(), sourceDb->metadata()->name());
|
||||
|
||||
QCOMPARE(reader.version(), expectedVersion);
|
||||
QCOMPARE(targetDb->kdf()->uuid(), sourceDb->kdf()->uuid());
|
||||
QCOMPARE(targetDb->cipher(), cipherUuid);
|
||||
QCOMPARE(*targetDb->metadata()->customData(), *sourceDb->metadata()->customData());
|
||||
QCOMPARE(*targetDb->rootGroup()->customData(), *sourceDb->rootGroup()->customData());
|
||||
}
|
||||
|
||||
void TestKdbx4::testFormat400Upgrade_data()
|
||||
{
|
||||
QTest::addColumn<Uuid>("kdfUuid");
|
||||
QTest::addColumn<Uuid>("cipherUuid");
|
||||
QTest::addColumn<bool>("addCustomData");
|
||||
QTest::addColumn<quint32>("expectedVersion");
|
||||
|
||||
auto constexpr kdbx3 = KeePass2::FILE_VERSION_3_1 & KeePass2::FILE_VERSION_CRITICAL_MASK;
|
||||
auto constexpr kdbx4 = KeePass2::FILE_VERSION_4 & KeePass2::FILE_VERSION_CRITICAL_MASK;
|
||||
|
||||
QTest::newRow("Argon2 + AES") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_AES << kdbx4;
|
||||
QTest::newRow("AES-KDF + AES") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + AES") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES << kdbx3;
|
||||
QTest::newRow("Argon2 + ChaCha20") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_CHACHA20 << kdbx4;
|
||||
QTest::newRow("AES-KDF + ChaCha20") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + ChaCha20") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << kdbx3;
|
||||
QTest::newRow("Argon2 + Twofish") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_TWOFISH << kdbx4;
|
||||
QTest::newRow("AES-KDF + Twofish") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + Twofish") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << kdbx3;
|
||||
QTest::newRow("Argon2 + AES") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_AES << false << kdbx4;
|
||||
QTest::newRow("AES-KDF + AES") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES << false << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + AES") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES << false << kdbx3;
|
||||
QTest::newRow("Argon2 + AES + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_AES << true << kdbx4;
|
||||
QTest::newRow("AES-KDF + AES + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES << true << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + AES + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES << true << kdbx4;
|
||||
|
||||
QTest::newRow("Argon2 + ChaCha20") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_CHACHA20 << false << kdbx4;
|
||||
QTest::newRow("AES-KDF + ChaCha20") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << false << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + ChaCha20") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << false << kdbx3;
|
||||
QTest::newRow("Argon2 + ChaCha20 + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_CHACHA20 << true << kdbx4;
|
||||
QTest::newRow("AES-KDF + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << true << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << true << kdbx4;
|
||||
|
||||
QTest::newRow("Argon2 + Twofish") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_TWOFISH << false << kdbx4;
|
||||
QTest::newRow("AES-KDF + Twofish") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << false << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + Twofish") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << false << kdbx3;
|
||||
QTest::newRow("Argon2 + Twofish + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_TWOFISH << true << kdbx4;
|
||||
QTest::newRow("AES-KDF + Twofish + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << true << kdbx4;
|
||||
QTest::newRow("AES-KDF (legacy) + Twofish + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << true << kdbx4;
|
||||
}
|
||||
|
||||
@@ -124,15 +124,6 @@ void TestKeePass2Format::testXmlCustomIcons()
|
||||
}
|
||||
}
|
||||
|
||||
void TestKeePass2Format::testXmlCustomData()
|
||||
{
|
||||
QHash<QString, QString> customFields = m_xmlDb->metadata()->customFields();
|
||||
|
||||
QCOMPARE(customFields.size(), 2);
|
||||
QCOMPARE(customFields.value("A Sample Test Key"), QString("valu"));
|
||||
QCOMPARE(customFields.value("custom key"), QString("blub"));
|
||||
}
|
||||
|
||||
void TestKeePass2Format::testXmlGroupRoot()
|
||||
{
|
||||
const Group* group = m_xmlDb->rootGroup();
|
||||
@@ -155,7 +146,6 @@ void TestKeePass2Format::testXmlGroupRoot()
|
||||
QCOMPARE(group->autoTypeEnabled(), Group::Inherit);
|
||||
QCOMPARE(group->searchingEnabled(), Group::Inherit);
|
||||
QCOMPARE(group->lastTopVisibleEntry()->uuid().toBase64(), QString("+wSUOv6qf0OzW8/ZHAs2sA=="));
|
||||
|
||||
QCOMPARE(group->children().size(), 3);
|
||||
QVERIFY(m_xmlDb->metadata()->recycleBin() == m_xmlDb->rootGroup()->children().at(2));
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ private slots:
|
||||
*/
|
||||
void testXmlMetadata();
|
||||
void testXmlCustomIcons();
|
||||
void testXmlCustomData();
|
||||
void testXmlGroupRoot();
|
||||
void testXmlGroup1();
|
||||
void testXmlGroup2();
|
||||
|
||||
@@ -40,31 +40,31 @@ void TestModified::testSignals()
|
||||
|
||||
CompositeKey compositeKey;
|
||||
|
||||
Database* db = new Database();
|
||||
Group* root = db->rootGroup();
|
||||
QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
|
||||
QScopedPointer<Database> db(new Database());
|
||||
auto* root = db->rootGroup();
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
|
||||
db->setKey(compositeKey);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
|
||||
Group* group1 = new Group();
|
||||
auto* group1 = new Group();
|
||||
group1->setParent(root);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
|
||||
Group* group2 = new Group();
|
||||
auto* group2 = new Group();
|
||||
group2->setParent(root);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
|
||||
group2->setParent(root, 0);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
|
||||
Entry* entry1 = new Entry();
|
||||
auto* entry1 = new Entry();
|
||||
entry1->setGroup(group1);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
|
||||
Database* db2 = new Database();
|
||||
Group* root2 = db2->rootGroup();
|
||||
QSignalSpy spyModified2(db2, SIGNAL(modifiedImmediate()));
|
||||
QScopedPointer<Database> db2(new Database());
|
||||
auto* root2 = db2->rootGroup();
|
||||
QSignalSpy spyModified2(db2.data(), SIGNAL(modifiedImmediate()));
|
||||
|
||||
group1->setParent(root2);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
@@ -74,7 +74,7 @@ void TestModified::testSignals()
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QCOMPARE(spyModified2.count(), ++spyCount2);
|
||||
|
||||
Entry* entry2 = new Entry();
|
||||
auto* entry2 = new Entry();
|
||||
entry2->setGroup(group2);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
QCOMPARE(spyModified2.count(), spyCount2);
|
||||
@@ -87,11 +87,11 @@ void TestModified::testSignals()
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QCOMPARE(spyModified2.count(), ++spyCount2);
|
||||
|
||||
Group* group3 = new Group();
|
||||
auto* group3 = new Group();
|
||||
group3->setParent(root);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
|
||||
Group* group4 = new Group();
|
||||
auto* group4 = new Group();
|
||||
group4->setParent(group3);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
|
||||
@@ -103,21 +103,18 @@ void TestModified::testSignals()
|
||||
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QCOMPARE(spyModified2.count(), spyCount2);
|
||||
|
||||
delete db;
|
||||
delete db2;
|
||||
}
|
||||
|
||||
void TestModified::testGroupSets()
|
||||
{
|
||||
int spyCount = 0;
|
||||
Database* db = new Database();
|
||||
Group* root = db->rootGroup();
|
||||
QScopedPointer<Database> db(new Database());
|
||||
auto* root = db->rootGroup();
|
||||
|
||||
Group* group = new Group();
|
||||
auto* group = new Group();
|
||||
group->setParent(root);
|
||||
|
||||
QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
|
||||
root->setUuid(Uuid::random());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
@@ -169,22 +166,20 @@ void TestModified::testGroupSets()
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
group->setIcon(group->iconUuid());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestModified::testEntrySets()
|
||||
{
|
||||
int spyCount = 0;
|
||||
Database* db = new Database();
|
||||
Group* root = db->rootGroup();
|
||||
QScopedPointer<Database> db(new Database());
|
||||
auto* root = db->rootGroup();
|
||||
|
||||
Group* group = new Group();
|
||||
auto* group = new Group();
|
||||
group->setParent(root);
|
||||
Entry* entry = new Entry();
|
||||
auto* entry = new Entry();
|
||||
entry->setGroup(group);
|
||||
|
||||
QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
|
||||
entry->setUuid(Uuid::random());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
@@ -284,8 +279,6 @@ void TestModified::testEntrySets()
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
entry->attributes()->set("test key2", entry->attributes()->value("test key2"), true);
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestModified::testHistoryItems()
|
||||
@@ -313,7 +306,7 @@ void TestModified::testHistoryItems()
|
||||
entry->setTitle("b");
|
||||
entry->endUpdate();
|
||||
QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
|
||||
Entry *historyEntry = entry->historyItems().at(historyItemsSize - 1);
|
||||
auto *historyEntry = entry->historyItems().at(historyItemsSize - 1);
|
||||
QCOMPARE(historyEntry->title(), QString("a"));
|
||||
QCOMPARE(historyEntry->uuid(), entry->uuid());
|
||||
QCOMPARE(historyEntry->tags(), entry->tags());
|
||||
@@ -342,12 +335,11 @@ void TestModified::testHistoryItems()
|
||||
QVERIFY(!entry->historyItems().at(historyItemsSize - 1)->attributes()->keys().contains("k"));
|
||||
|
||||
QScopedPointer<Database> db(new Database());
|
||||
Group* root = db->rootGroup();
|
||||
auto* root = db->rootGroup();
|
||||
db->metadata()->setHistoryMaxItems(3);
|
||||
db->metadata()->setHistoryMaxSize(-1);
|
||||
|
||||
Entry* historyEntry2;
|
||||
Entry* entry2 = new Entry();
|
||||
auto* entry2 = new Entry();
|
||||
entry2->setGroup(root);
|
||||
entry2->beginUpdate();
|
||||
entry2->setTitle("1");
|
||||
@@ -373,7 +365,7 @@ void TestModified::testHistoryItems()
|
||||
entry2->endUpdate();
|
||||
QCOMPARE(entry2->historyItems().size(), 1);
|
||||
|
||||
historyEntry2 = entry2->historyItems().at(0);
|
||||
auto* historyEntry2 = entry2->historyItems().at(0);
|
||||
QCOMPARE(historyEntry2->title(), QString("4"));
|
||||
|
||||
db->metadata()->setHistoryMaxItems(-1);
|
||||
@@ -451,7 +443,6 @@ void TestModified::testHistoryMaxSize()
|
||||
QScopedPointer<Database> db(new Database());
|
||||
const QString key("test");
|
||||
|
||||
|
||||
auto entry1 = new Entry();
|
||||
entry1->setGroup(db->rootGroup());
|
||||
QCOMPARE(entry1->historyItems().size(), 0);
|
||||
@@ -584,15 +575,15 @@ void TestModified::testHistoryMaxSize()
|
||||
void TestModified::testCustomData()
|
||||
{
|
||||
int spyCount = 0;
|
||||
Database* db = new Database();
|
||||
Group* root = db->rootGroup();
|
||||
QScopedPointer<Database> db(new Database());
|
||||
auto* root = db->rootGroup();
|
||||
|
||||
Group* group = new Group();
|
||||
auto* group = new Group();
|
||||
group->setParent(root);
|
||||
Entry* entry = new Entry();
|
||||
auto* entry = new Entry();
|
||||
entry->setGroup(group);
|
||||
|
||||
QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
|
||||
db->metadata()->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
@@ -608,6 +599,4 @@ void TestModified::testCustomData()
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
group->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
@@ -39,16 +39,6 @@
|
||||
<Binary ID="0" Compressed="True">H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/InZ29+7t3//0wcHD/wfGx4SmCgAAAA==</Binary>
|
||||
<Binary ID="1" Compressed="True">H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/IrLJdJafX8yLn377/wCfD1fOCwAAAA==</Binary>
|
||||
</Binaries>
|
||||
<CustomData>
|
||||
<Item>
|
||||
<Key>A Sample Test Key</Key>
|
||||
<Value>valu</Value>
|
||||
</Item>
|
||||
<Item>
|
||||
<Key>custom key</Key>
|
||||
<Value>blub</Value>
|
||||
</Item>
|
||||
</CustomData>
|
||||
</Meta>
|
||||
<Root>
|
||||
<Group>
|
||||
@@ -479,4 +469,4 @@
|
||||
</DeletedObject>
|
||||
</DeletedObjects>
|
||||
</Root>
|
||||
</KeePassFile>
|
||||
</KeePassFile>
|
||||
|
||||
Reference in New Issue
Block a user