diff options
author | Janek Bevendorff <janek@jbev.net> | 2018-02-28 00:38:05 +0300 |
---|---|---|
committer | Janek Bevendorff <janek@jbev.net> | 2018-02-28 00:38:05 +0300 |
commit | 4c0ed74341173482415c484a2ad07df204150213 (patch) | |
tree | 74ebd72444c8e9db43698383151ddca6d7fb4506 /tests/TestKeePass2XmlReader.cpp | |
parent | 4723f66d23db95f8318f04ee3aeae448d2305c9c (diff) | |
parent | 1db064425a22d997a2b6740c73a7b0cb1310fe07 (diff) |
Release 2.3.02.3.0
- Add support for KDBX 4.0, Argon2 and ChaCha20 [#148, #1179, #1230, #1494]
- Add SSH Agent feature [#1098, #1450, #1463]
- Add preview panel with details of the selected entry [#879, #1338]
- Add more and configurable columns to entry table and allow copying of values by double click [#1305]
- Add KeePassXC-Browser API as a replacement for KeePassHTTP [#608]
- Deprecate KeePassHTTP [#1392]
- Add support for Steam one-time passwords [#1206]
- Add support for multiple Auto-Type sequences for a single entry [#1390]
- Adjust YubiKey HMAC-SHA1 challenge-response key generation for KDBX 4.0 [#1060]
- Replace qHttp with cURL for website icon downloads [#1460]
- Remove lock file [#1231]
- Add option to create backup file before saving [#1385]
- Ask to save a generated password before closing the entry password generator [#1499]
- Resolve placeholders recursively [#1078]
- Add Auto-Type button to the toolbar [#1056]
- Improve window focus handling for Auto-Type dialogs [#1204, #1490]
- Auto-Type dialog and password generator can now be exited with ESC [#1252, #1412]
- Add optional dark tray icon [#1154]
- Add new "Unsafe saving" option to work around saving problems with file sync services [#1385]
- Add IBus support to AppImage and additional image formats to Windows builds [#1534, #1537]
- Add diceware password generator to CLI [#1406]
- Add --key-file option to CLI [#816, #824]
- Add DBus interface for opening and closing KeePassXC databases [#283]
- Add KDBX compression options to database settings [#1419]
- Discourage use of old fixed-length key files in favor of arbitrary files [#1326, #1327]
- Correct reference resolution in entry fields [#1486]
- Fix window state and recent databases not being remembered on exit [#1453]
- Correct history item generation when configuring TOTP for an entry [#1446]
- Correct multiple TOTP bugs [#1414]
- Automatic saving after every change is now a default [#279]
- Allow creation of new entries during search [#1398]
- Correct menu issues on macOS [#1335]
- Allow compilation on OpenBSD [#1328]
- Improve entry attachments view [#1139, #1298]
- Fix auto lock for Gnome and Xfce [#910, #1249]
- Don't remember key files in file dialogs when the setting is disabled [#1188]
- Improve database merging and conflict resolution [#807, #1165]
- Fix macOS pasteboard issues [#1202]
- Improve startup times on some platforms [#1205]
- Hide the notes field by default [#1124]
- Toggle main window by clicking tray icon with the middle mouse button [#992]
- Fix custom icons not copied over when databases are merged [#1008]
- Allow use of DEL key to delete entries [#914]
- Correct intermittent crash due to stale history items [#1527]
- Sanitize newline characters in title, username and URL fields [#1502]
- Reopen previously opened databases in correct order [#774]
- Use system's zxcvbn library if available [#701]
- Implement various i18n improvements [#690, #875, #1436]
Diffstat (limited to 'tests/TestKeePass2XmlReader.cpp')
-rw-r--r-- | tests/TestKeePass2XmlReader.cpp | 520 |
1 files changed, 0 insertions, 520 deletions
diff --git a/tests/TestKeePass2XmlReader.cpp b/tests/TestKeePass2XmlReader.cpp deleted file mode 100644 index 495b39acf..000000000 --- a/tests/TestKeePass2XmlReader.cpp +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (C) 2010 Felix Geyer <debfx@fobos.de> - * - * 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 "TestKeePass2XmlReader.h" - -#include <QBuffer> -#include <QFile> -#include <QTest> - -#include "core/Database.h" -#include "core/Group.h" -#include "core/Metadata.h" -#include "crypto/Crypto.h" -#include "format/KeePass2XmlReader.h" -#include "format/KeePass2XmlWriter.h" -#include "config-keepassx-tests.h" - -QTEST_GUILESS_MAIN(TestKeePass2XmlReader) - -namespace QTest { - template<> - char* toString(const Uuid& uuid) - { - QByteArray ba = "Uuid("; - ba += uuid.toBase64().toLatin1().constData(); - ba += ")"; - return qstrdup(ba.constData()); - } - - template<> - char* toString(const Group::TriState& triState) - { - QString value; - - if (triState == Group::Inherit) { - value = "null"; - } - else if (triState == Group::Enable) { - value = "true"; - } - else { - value = "false"; - } - - return qstrdup(value.toLocal8Bit().constData()); - } -} - -QDateTime TestKeePass2XmlReader::genDT(int year, int month, int day, int hour, int min, int second) -{ - QDate date(year, month, day); - QTime time(hour, min, second); - return QDateTime(date, time, Qt::UTC); -} - -QByteArray TestKeePass2XmlReader::strToBytes(const QString& str) -{ - QByteArray result; - - for (int i = 0; i < str.size(); i++) { - result.append(str.at(i).unicode() >> 8); - result.append(str.at(i).unicode() & 0xFF); - } - - return result; -} - -void TestKeePass2XmlReader::initTestCase() -{ - QVERIFY(Crypto::init()); - - KeePass2XmlReader reader; - reader.setStrictMode(true); - QString xmlFile = QString(KEEPASSX_TEST_DATA_DIR).append("/NewDatabase.xml"); - m_db = reader.readDatabase(xmlFile); - QVERIFY(m_db); - QVERIFY(!reader.hasError()); -} - -void TestKeePass2XmlReader::testMetadata() -{ - QCOMPARE(m_db->metadata()->generator(), QString("KeePass")); - QCOMPARE(m_db->metadata()->name(), QString("ANAME")); - QCOMPARE(m_db->metadata()->nameChanged(), genDT(2010, 8, 8, 17, 24, 53)); - QCOMPARE(m_db->metadata()->description(), QString("ADESC")); - QCOMPARE(m_db->metadata()->descriptionChanged(), genDT(2010, 8, 8, 17, 27, 12)); - QCOMPARE(m_db->metadata()->defaultUserName(), QString("DEFUSERNAME")); - QCOMPARE(m_db->metadata()->defaultUserNameChanged(), genDT(2010, 8, 8, 17, 27, 45)); - QCOMPARE(m_db->metadata()->maintenanceHistoryDays(), 127); - QCOMPARE(m_db->metadata()->color(), QColor(0xff, 0xef, 0x00)); - QCOMPARE(m_db->metadata()->masterKeyChanged(), genDT(2012, 4, 5, 17, 9, 34)); - QCOMPARE(m_db->metadata()->masterKeyChangeRec(), 101); - QCOMPARE(m_db->metadata()->masterKeyChangeForce(), -1); - QCOMPARE(m_db->metadata()->protectTitle(), false); - QCOMPARE(m_db->metadata()->protectUsername(), true); - QCOMPARE(m_db->metadata()->protectPassword(), false); - QCOMPARE(m_db->metadata()->protectUrl(), true); - QCOMPARE(m_db->metadata()->protectNotes(), false); - QCOMPARE(m_db->metadata()->recycleBinEnabled(), true); - QVERIFY(m_db->metadata()->recycleBin() != nullptr); - QCOMPARE(m_db->metadata()->recycleBin()->name(), QString("Recycle Bin")); - QCOMPARE(m_db->metadata()->recycleBinChanged(), genDT(2010, 8, 25, 16, 12, 57)); - QVERIFY(m_db->metadata()->entryTemplatesGroup() == nullptr); - QCOMPARE(m_db->metadata()->entryTemplatesGroupChanged(), genDT(2010, 8, 8, 17, 24, 19)); - QVERIFY(m_db->metadata()->lastSelectedGroup() != nullptr); - QCOMPARE(m_db->metadata()->lastSelectedGroup()->name(), QString("NewDatabase")); - QVERIFY(m_db->metadata()->lastTopVisibleGroup() == m_db->metadata()->lastSelectedGroup()); - QCOMPARE(m_db->metadata()->historyMaxItems(), -1); - QCOMPARE(m_db->metadata()->historyMaxSize(), 5242880); -} - -void TestKeePass2XmlReader::testCustomIcons() -{ - QCOMPARE(m_db->metadata()->customIcons().size(), 1); - Uuid uuid = Uuid::fromBase64("++vyI+daLk6omox4a6kQGA=="); - QVERIFY(m_db->metadata()->customIcons().contains(uuid)); - QImage icon = m_db->metadata()->customIcon(uuid); - QCOMPARE(icon.width(), 16); - QCOMPARE(icon.height(), 16); - - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - QRgb rgb = icon.pixel(x, y); - QCOMPARE(qRed(rgb), 128); - QCOMPARE(qGreen(rgb), 0); - QCOMPARE(qBlue(rgb), 128); - } - } -} - -void TestKeePass2XmlReader::testCustomData() -{ - QHash<QString, QString> customFields = m_db->metadata()->customFields(); - - QCOMPARE(customFields.size(), 2); - QCOMPARE(customFields.value("A Sample Test Key"), QString("valu")); - QCOMPARE(customFields.value("custom key"), QString("blub")); -} - -void TestKeePass2XmlReader::testGroupRoot() -{ - const Group* group = m_db->rootGroup(); - QVERIFY(group); - QCOMPARE(group->uuid().toBase64(), QString("lmU+9n0aeESKZvcEze+bRg==")); - QCOMPARE(group->name(), QString("NewDatabase")); - QCOMPARE(group->notes(), QString("")); - QCOMPARE(group->iconNumber(), 49); - QCOMPARE(group->iconUuid(), Uuid()); - QVERIFY(group->isExpanded()); - TimeInfo ti = group->timeInfo(); - QCOMPARE(ti.lastModificationTime(), genDT(2010, 8, 8, 17, 24, 27)); - QCOMPARE(ti.creationTime(), genDT(2010, 8, 7, 17, 24, 27)); - QCOMPARE(ti.lastAccessTime(), genDT(2010, 8, 9, 9, 9, 44)); - QCOMPARE(ti.expiryTime(), genDT(2010, 8, 8, 17, 24, 17)); - QVERIFY(!ti.expires()); - QCOMPARE(ti.usageCount(), 52); - QCOMPARE(ti.locationChanged(), genDT(2010, 8, 8, 17, 24, 27)); - QCOMPARE(group->defaultAutoTypeSequence(), QString("")); - 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_db->metadata()->recycleBin() == m_db->rootGroup()->children().at(2)); - - QCOMPARE(group->entries().size(), 2); -} - -void TestKeePass2XmlReader::testGroup1() -{ - const Group* group = m_db->rootGroup()->children().at(0); - - QCOMPARE(group->uuid().toBase64(), QString("AaUYVdXsI02h4T1RiAlgtg==")); - QCOMPARE(group->name(), QString("General")); - QCOMPARE(group->notes(), QString("Group Notez")); - QCOMPARE(group->iconNumber(), 48); - QCOMPARE(group->iconUuid(), Uuid()); - QCOMPARE(group->isExpanded(), true); - QCOMPARE(group->defaultAutoTypeSequence(), QString("{Password}{ENTER}")); - QCOMPARE(group->autoTypeEnabled(), Group::Enable); - QCOMPARE(group->searchingEnabled(), Group::Disable); - QVERIFY(!group->lastTopVisibleEntry()); -} - -void TestKeePass2XmlReader::testGroup2() -{ - const Group* group = m_db->rootGroup()->children().at(1); - - QCOMPARE(group->uuid().toBase64(), QString("1h4NtL5DK0yVyvaEnN//4A==")); - QCOMPARE(group->name(), QString("Windows")); - QCOMPARE(group->isExpanded(), false); - - QCOMPARE(group->children().size(), 1); - const Group* child = group->children().first(); - - QCOMPARE(child->uuid().toBase64(), QString("HoYE/BjLfUSW257pCHJ/eA==")); - QCOMPARE(child->name(), QString("Subsub")); - QCOMPARE(child->entries().size(), 1); - - const Entry* entry = child->entries().first(); - QCOMPARE(entry->uuid().toBase64(), QString("GZpdQvGXOU2kaKRL/IVAGg==")); - QCOMPARE(entry->title(), QString("Subsub Entry")); -} - -void TestKeePass2XmlReader::testEntry1() -{ - const Entry* entry = m_db->rootGroup()->entries().at(0); - - QCOMPARE(entry->uuid().toBase64(), QString("+wSUOv6qf0OzW8/ZHAs2sA==")); - QCOMPARE(entry->historyItems().size(), 2); - QCOMPARE(entry->iconNumber(), 0); - QCOMPARE(entry->iconUuid(), Uuid()); - QVERIFY(!entry->foregroundColor().isValid()); - QVERIFY(!entry->backgroundColor().isValid()); - QCOMPARE(entry->overrideUrl(), QString("")); - QCOMPARE(entry->tags(), QString("a b c")); - - const TimeInfo ti = entry->timeInfo(); - QCOMPARE(ti.lastModificationTime(), genDT(2010, 8, 25, 16, 19, 25)); - QCOMPARE(ti.creationTime(), genDT(2010, 8, 25, 16, 13, 54)); - QCOMPARE(ti.lastAccessTime(), genDT(2010, 8, 25, 16, 19, 25)); - QCOMPARE(ti.expiryTime(), genDT(2010, 8, 25, 16, 12, 57)); - QVERIFY(!ti.expires()); - QCOMPARE(ti.usageCount(), 8); - QCOMPARE(ti.locationChanged(), genDT(2010, 8, 25, 16, 13, 54)); - - QList<QString> attrs = entry->attributes()->keys(); - QCOMPARE(entry->attributes()->value("Notes"), QString("Notes")); - QVERIFY(!entry->attributes()->isProtected("Notes")); - QVERIFY(attrs.removeOne("Notes")); - QCOMPARE(entry->attributes()->value("Password"), QString("Password")); - QVERIFY(!entry->attributes()->isProtected("Password")); - QVERIFY(attrs.removeOne("Password")); - QCOMPARE(entry->attributes()->value("Title"), QString("Sample Entry 1")); - QVERIFY(!entry->attributes()->isProtected("Title")); - QVERIFY(attrs.removeOne("Title")); - QCOMPARE(entry->attributes()->value("URL"), QString("")); - QVERIFY(entry->attributes()->isProtected("URL")); - QVERIFY(attrs.removeOne("URL")); - QCOMPARE(entry->attributes()->value("UserName"), QString("User Name")); - QVERIFY(entry->attributes()->isProtected("UserName")); - QVERIFY(attrs.removeOne("UserName")); - QVERIFY(attrs.isEmpty()); - - QCOMPARE(entry->title(), entry->attributes()->value("Title")); - QCOMPARE(entry->url(), entry->attributes()->value("URL")); - QCOMPARE(entry->username(), entry->attributes()->value("UserName")); - QCOMPARE(entry->password(), entry->attributes()->value("Password")); - QCOMPARE(entry->notes(), entry->attributes()->value("Notes")); - - QCOMPARE(entry->attachments()->keys().size(), 1); - QCOMPARE(entry->attachments()->value("myattach.txt"), QByteArray("abcdefghijk")); - QCOMPARE(entry->historyItems().at(0)->attachments()->keys().size(), 1); - QCOMPARE(entry->historyItems().at(0)->attachments()->value("myattach.txt"), QByteArray("0123456789")); - QCOMPARE(entry->historyItems().at(1)->attachments()->keys().size(), 1); - QCOMPARE(entry->historyItems().at(1)->attachments()->value("myattach.txt"), QByteArray("abcdefghijk")); - - QCOMPARE(entry->autoTypeEnabled(), false); - QCOMPARE(entry->autoTypeObfuscation(), 0); - QCOMPARE(entry->defaultAutoTypeSequence(), QString("")); - QCOMPARE(entry->autoTypeAssociations()->size(), 1); - const AutoTypeAssociations::Association assoc1 = entry->autoTypeAssociations()->get(0); - QCOMPARE(assoc1.window, QString("Target Window")); - QCOMPARE(assoc1.sequence, QString("")); -} - -void TestKeePass2XmlReader::testEntry2() -{ - const Entry* entry = m_db->rootGroup()->entries().at(1); - - QCOMPARE(entry->uuid().toBase64(), QString("4jbADG37hkiLh2O0qUdaOQ==")); - QCOMPARE(entry->iconNumber(), 0); - QCOMPARE(entry->iconUuid().toBase64(), QString("++vyI+daLk6omox4a6kQGA==")); - // TODO: test entry->icon() - QCOMPARE(entry->foregroundColor(), QColor(255, 0, 0)); - QCOMPARE(entry->backgroundColor(), QColor(255, 255, 0)); - QCOMPARE(entry->overrideUrl(), QString("http://override.net/")); - QCOMPARE(entry->tags(), QString("")); - - const TimeInfo ti = entry->timeInfo(); - QCOMPARE(ti.usageCount(), 7); - - QList<QString> attrs = entry->attributes()->keys(); - QCOMPARE(entry->attributes()->value("CustomString"), QString("isavalue")); - QVERIFY(attrs.removeOne("CustomString")); - QCOMPARE(entry->attributes()->value("Notes"), QString("")); - QVERIFY(attrs.removeOne("Notes")); - QCOMPARE(entry->attributes()->value("Password"), QString("Jer60Hz8o9XHvxBGcRqT")); - QVERIFY(attrs.removeOne("Password")); - QCOMPARE(entry->attributes()->value("Protected String"), QString("y")); // TODO: should have a protection attribute - QVERIFY(attrs.removeOne("Protected String")); - QCOMPARE(entry->attributes()->value("Title"), QString("Sample Entry 2")); - QVERIFY(attrs.removeOne("Title")); - QCOMPARE(entry->attributes()->value("URL"), QString("http://www.keepassx.org/")); - QVERIFY(attrs.removeOne("URL")); - QCOMPARE(entry->attributes()->value("UserName"), QString("notDEFUSERNAME")); - QVERIFY(attrs.removeOne("UserName")); - QVERIFY(attrs.isEmpty()); - - QCOMPARE(entry->attachments()->keys().size(), 1); - QCOMPARE(QString::fromLatin1(entry->attachments()->value("myattach.txt")), QString("abcdefghijk")); - - QCOMPARE(entry->autoTypeEnabled(), true); - QCOMPARE(entry->autoTypeObfuscation(), 1); - QCOMPARE(entry->defaultAutoTypeSequence(), QString("{USERNAME}{TAB}{PASSWORD}{ENTER}")); - QCOMPARE(entry->autoTypeAssociations()->size(), 2); - const AutoTypeAssociations::Association assoc1 = entry->autoTypeAssociations()->get(0); - QCOMPARE(assoc1.window, QString("Target Window")); - QCOMPARE(assoc1.sequence, QString("{Title}{UserName}")); - const AutoTypeAssociations::Association assoc2 = entry->autoTypeAssociations()->get(1); - QCOMPARE(assoc2.window, QString("Target Window 2")); - QCOMPARE(assoc2.sequence, QString("{Title}{UserName} test")); -} - -void TestKeePass2XmlReader::testEntryHistory() -{ - const Entry* entryMain = m_db->rootGroup()->entries().at(0); - QCOMPARE(entryMain->historyItems().size(), 2); - - { - const Entry* entry = entryMain->historyItems().at(0); - QCOMPARE(entry->uuid(), entryMain->uuid()); - QVERIFY(!entry->parent()); - QCOMPARE(entry->timeInfo().lastModificationTime(), genDT(2010, 8, 25, 16, 13, 54)); - QCOMPARE(entry->timeInfo().usageCount(), 3); - QCOMPARE(entry->title(), QString("Sample Entry")); - QCOMPARE(entry->url(), QString("http://www.somesite.com/")); - } - - { - const Entry* entry = entryMain->historyItems().at(1); - QCOMPARE(entry->uuid(), entryMain->uuid()); - QVERIFY(!entry->parent()); - QCOMPARE(entry->timeInfo().lastModificationTime(), genDT(2010, 8, 25, 16, 15, 43)); - QCOMPARE(entry->timeInfo().usageCount(), 7); - QCOMPARE(entry->title(), QString("Sample Entry 1")); - QCOMPARE(entry->url(), QString("http://www.somesite.com/")); - } -} - -void TestKeePass2XmlReader::testDeletedObjects() -{ - QList<DeletedObject> objList = m_db->deletedObjects(); - DeletedObject delObj; - - delObj = objList.takeFirst(); - QCOMPARE(delObj.uuid.toBase64(), QString("5K/bzWCSmkCv5OZxYl4N/w==")); - QCOMPARE(delObj.deletionTime, genDT(2010, 8, 25, 16, 14, 12)); - - delObj = objList.takeFirst(); - QCOMPARE(delObj.uuid.toBase64(), QString("80h8uSNWgkKhKCp1TgXF7g==")); - QCOMPARE(delObj.deletionTime, genDT(2010, 8, 25, 16, 14, 14)); - - QVERIFY(objList.isEmpty()); -} - -void TestKeePass2XmlReader::testBroken() -{ - QFETCH(QString, baseName); - QFETCH(bool, strictMode); - QFETCH(bool, expectError); - - KeePass2XmlReader reader; - reader.setStrictMode(strictMode); - QString xmlFile = QString("%1/%2.xml").arg(KEEPASSX_TEST_DATA_DIR, baseName); - QVERIFY(QFile::exists(xmlFile)); - QScopedPointer<Database> db(reader.readDatabase(xmlFile)); - if (reader.hasError()) { - qWarning("Reader error: %s", qPrintable(reader.errorString())); - } - QCOMPARE(reader.hasError(), expectError); -} - -void TestKeePass2XmlReader::testBroken_data() -{ - QTest::addColumn<QString>("baseName"); - QTest::addColumn<bool>("strictMode"); - QTest::addColumn<bool>("expectError"); - - // testfile strict? error? - QTest::newRow("BrokenNoGroupUuid (strict)") << "BrokenNoGroupUuid" << true << true; - QTest::newRow("BrokenNoGroupUuid (not strict)") << "BrokenNoGroupUuid" << false << false; - QTest::newRow("BrokenNoEntryUuid (strict)") << "BrokenNoEntryUuid" << true << true; - QTest::newRow("BrokenNoEntryUuid (not strict)") << "BrokenNoEntryUuid" << false << false; - QTest::newRow("BrokenNoRootGroup (strict)") << "BrokenNoRootGroup" << true << true; - QTest::newRow("BrokenNoRootGroup (not strict)") << "BrokenNoRootGroup" << false << true; - QTest::newRow("BrokenTwoRoots (strict)") << "BrokenTwoRoots" << true << true; - QTest::newRow("BrokenTwoRoots (not strict)") << "BrokenTwoRoots" << false << true; - QTest::newRow("BrokenTwoRootGroups (strict)") << "BrokenTwoRootGroups" << true << true; - QTest::newRow("BrokenTwoRootGroups (not strict)") << "BrokenTwoRootGroups" << false << true; - QTest::newRow("BrokenGroupReference (strict)") << "BrokenGroupReference" << true << false; - QTest::newRow("BrokenGroupReference (not strict)") << "BrokenGroupReference" << false << false; - QTest::newRow("BrokenDeletedObjects (strict)") << "BrokenDeletedObjects" << true << true; - QTest::newRow("BrokenDeletedObjects (not strict)") << "BrokenDeletedObjects" << false << false; - QTest::newRow("BrokenDifferentEntryHistoryUuid (strict)") << "BrokenDifferentEntryHistoryUuid" << true << true; - QTest::newRow("BrokenDifferentEntryHistoryUuid (not strict)") << "BrokenDifferentEntryHistoryUuid" << false << false; -} - -void TestKeePass2XmlReader::testEmptyUuids() -{ - KeePass2XmlReader reader; - reader.setStrictMode(true); - QString xmlFile = QString("%1/%2.xml").arg(KEEPASSX_TEST_DATA_DIR, "EmptyUuids"); - QVERIFY(QFile::exists(xmlFile)); - QScopedPointer<Database> db(reader.readDatabase(xmlFile)); - if (reader.hasError()) { - qWarning("Reader error: %s", qPrintable(reader.errorString())); - } - QVERIFY(!reader.hasError()); -} - -void TestKeePass2XmlReader::testInvalidXmlChars() -{ - QScopedPointer<Database> dbWrite(new Database()); - - QString strPlainInvalid = QString().append(QChar(0x02)).append(QChar(0x19)) - .append(QChar(0xFFFE)).append(QChar(0xFFFF)); - QString strPlainValid = QString().append(QChar(0x09)).append(QChar(0x0A)) - .append(QChar(0x20)).append(QChar(0xD7FF)) - .append(QChar(0xE000)).append(QChar(0xFFFD)); - // U+10437 in UTF-16: D801 DC37 - // high low surrogate - QString strSingleHighSurrogate1 = QString().append(QChar(0xD801)); - QString strSingleHighSurrogate2 = QString().append(QChar(0x31)).append(QChar(0xD801)).append(QChar(0x32)); - QString strHighHighSurrogate = QString().append(QChar(0xD801)).append(QChar(0xD801)); - QString strSingleLowSurrogate1 = QString().append(QChar(0xDC37)); - QString strSingleLowSurrogate2 = QString().append(QChar((0x31))).append(QChar(0xDC37)).append(QChar(0x32)); - QString strLowLowSurrogate = QString().append(QChar(0xDC37)).append(QChar(0xDC37)); - QString strSurrogateValid1 = QString().append(QChar(0xD801)).append(QChar(0xDC37)); - QString strSurrogateValid2 = QString().append(QChar(0x31)).append(QChar(0xD801)).append(QChar(0xDC37)).append(QChar(0x32)); - - Entry* entry = new Entry(); - entry->setUuid(Uuid::random()); - entry->setGroup(dbWrite->rootGroup()); - entry->attributes()->set("PlainInvalid", strPlainInvalid); - entry->attributes()->set("PlainValid", strPlainValid); - entry->attributes()->set("SingleHighSurrogate1", strSingleHighSurrogate1); - entry->attributes()->set("SingleHighSurrogate2", strSingleHighSurrogate2); - entry->attributes()->set("HighHighSurrogate", strHighHighSurrogate); - entry->attributes()->set("SingleLowSurrogate1", strSingleLowSurrogate1); - entry->attributes()->set("SingleLowSurrogate2", strSingleLowSurrogate2); - entry->attributes()->set("LowLowSurrogate", strLowLowSurrogate); - entry->attributes()->set("SurrogateValid1", strSurrogateValid1); - entry->attributes()->set("SurrogateValid2", strSurrogateValid2); - - QBuffer buffer; - buffer.open(QIODevice::ReadWrite); - KeePass2XmlWriter writer; - writer.writeDatabase(&buffer, dbWrite.data()); - QVERIFY(!writer.hasError()); - buffer.seek(0); - - KeePass2XmlReader reader; - reader.setStrictMode(true); - QScopedPointer<Database> dbRead(reader.readDatabase(&buffer)); - if (reader.hasError()) { - qWarning("Database read error: %s", qPrintable(reader.errorString())); - } - QVERIFY(!reader.hasError()); - QVERIFY(!dbRead.isNull()); - QCOMPARE(dbRead->rootGroup()->entries().size(), 1); - Entry* entryRead = dbRead->rootGroup()->entries().at(0); - EntryAttributes* attrRead = entryRead->attributes(); - - QCOMPARE(strToBytes(attrRead->value("PlainInvalid")), QByteArray()); - QCOMPARE(strToBytes(attrRead->value("PlainValid")), strToBytes(strPlainValid)); - QCOMPARE(strToBytes(attrRead->value("SingleHighSurrogate1")), QByteArray()); - QCOMPARE(strToBytes(attrRead->value("SingleHighSurrogate2")), strToBytes(QString("12"))); - QCOMPARE(strToBytes(attrRead->value("HighHighSurrogate")), QByteArray()); - QCOMPARE(strToBytes(attrRead->value("SingleLowSurrogate1")), QByteArray()); - QCOMPARE(strToBytes(attrRead->value("SingleLowSurrogate2")), strToBytes(QString("12"))); - QCOMPARE(strToBytes(attrRead->value("LowLowSurrogate")), QByteArray()); - QCOMPARE(strToBytes(attrRead->value("SurrogateValid1")), strToBytes(strSurrogateValid1)); - QCOMPARE(strToBytes(attrRead->value("SurrogateValid2")), strToBytes(strSurrogateValid2)); -} - -void TestKeePass2XmlReader::testRepairUuidHistoryItem() -{ - KeePass2XmlReader reader; - QString xmlFile = QString("%1/%2.xml").arg(KEEPASSX_TEST_DATA_DIR, "BrokenDifferentEntryHistoryUuid"); - QVERIFY(QFile::exists(xmlFile)); - QScopedPointer<Database> db(reader.readDatabase(xmlFile)); - if (reader.hasError()) { - qWarning("Database read error: %s", qPrintable(reader.errorString())); - } - QVERIFY(!reader.hasError()); - - - - QList<Entry*> entries = db.data()->rootGroup()->entries(); - QCOMPARE(entries.size(), 1); - Entry* entry = entries.at(0); - - QList<Entry*> historyItems = entry->historyItems(); - QCOMPARE(historyItems.size(), 1); - Entry* historyItem = historyItems.at(0); - - QVERIFY(!entry->uuid().isNull()); - QVERIFY(!historyItem->uuid().isNull()); - QCOMPARE(historyItem->uuid(), entry->uuid()); -} - -void TestKeePass2XmlReader::cleanupTestCase() -{ - delete m_db; -} |