From 3bf0564436475c06e3092c74ab717e4f3d675ab4 Mon Sep 17 00:00:00 2001 From: Felix Geyer Date: Thu, 26 Aug 2010 00:31:07 +0200 Subject: [PATCH] Handle CustomData element. This should make support for reading and writing KeePass 2 XML files complete (closes #1). --- src/CMakeLists.txt | 1 - src/core/Database.h | 3 --- src/core/DbAttribute.cpp | 22 ---------------------- src/core/DbAttribute.h | 33 --------------------------------- src/core/Parser.cpp | 26 ++++++++++++++++++++++++-- src/core/Parser.h | 1 + src/core/Writer.cpp | 20 +++++++++++++++++--- src/core/Writer.h | 1 + tests/NewDatabase.xml | 11 ++++++++++- tests/TestParser.cpp | 14 ++++++++++++-- 10 files changed, 65 insertions(+), 67 deletions(-) delete mode 100644 src/core/DbAttribute.cpp delete mode 100644 src/core/DbAttribute.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d65755068..5f39d2f90 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,6 @@ configure_file( config-keepassx.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-keepa set(keepassx_SOURCES core/Database.cpp - core/DbAttribute.cpp core/Entry.cpp core/Group.cpp core/Metadata.cpp diff --git a/src/core/Database.h b/src/core/Database.h index 19e129948..cb3e299b4 100644 --- a/src/core/Database.h +++ b/src/core/Database.h @@ -20,8 +20,6 @@ #include "Group.h" -#include "DbAttribute.h" - #include #include @@ -64,7 +62,6 @@ private: Metadata* m_metadata; Group* m_rootGroup; QHash m_customIcons; - DbAttribute m_unhandledAttirbute; QList m_deletedObjects; }; diff --git a/src/core/DbAttribute.cpp b/src/core/DbAttribute.cpp deleted file mode 100644 index 7626e8bda..000000000 --- a/src/core/DbAttribute.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2010 Felix Geyer - * - * 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 . - */ - -#include "DbAttribute.h" - -DbAttribute::DbAttribute() -{ -} diff --git a/src/core/DbAttribute.h b/src/core/DbAttribute.h deleted file mode 100644 index e694b07ef..000000000 --- a/src/core/DbAttribute.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010 Felix Geyer - * - * 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 . - */ - -#ifndef KEEPASSX_DBATTRIBUTE_H -#define KEEPASSX_DBATTRIBUTE_H - -#include - -class DbAttribute -{ -public: - DbAttribute(); - -private: - QHash properties; - QHash children; -}; - -#endif // KEEPASSX_DBATTRIBUTE_H diff --git a/src/core/Parser.cpp b/src/core/Parser.cpp index 062622523..80a31292a 100644 --- a/src/core/Parser.cpp +++ b/src/core/Parser.cpp @@ -210,9 +210,31 @@ void Parser::parseCustomData() { Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "CustomData"); - // TODO implement while (!m_xml.error() && m_xml.readNextStartElement()) { - skipCurrentElement(); + if (m_xml.name() == "Item") { + parseCustomDataItem(); + } + else { + skipCurrentElement(); + } + } +} + +void Parser::parseCustomDataItem() +{ + Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Item"); + + QString key; + while (!m_xml.error() && m_xml.readNextStartElement()) { + if (m_xml.name() == "Key") { + key = readString(); + } + else if (m_xml.name() == "Value") { + m_meta->addCustomField(key, readString()); + } + else { + skipCurrentElement(); + } } } diff --git a/src/core/Parser.h b/src/core/Parser.h index 0d2e5c933..b38bef226 100644 --- a/src/core/Parser.h +++ b/src/core/Parser.h @@ -46,6 +46,7 @@ private: void parseCustomIcons(); void parseIcon(); void parseCustomData(); + void parseCustomDataItem(); void parseRoot(); Group* parseGroup(); void parseDeletedObjects(); diff --git a/src/core/Writer.cpp b/src/core/Writer.cpp index 5673b3e2f..0de34fb95 100644 --- a/src/core/Writer.cpp +++ b/src/core/Writer.cpp @@ -100,8 +100,9 @@ void Writer::writeCustomIcons() { m_xml.writeStartElement("CustomIcons"); - Q_FOREACH (const Uuid& uuid, m_meta->customIcons().keys()) { - writeIcon(uuid, m_meta->customIcons().value(uuid)); + QHash customIcons = m_meta->customIcons(); + Q_FOREACH (const Uuid& uuid, customIcons.keys()) { + writeIcon(uuid, customIcons.value(uuid)); } m_xml.writeEndElement(); @@ -127,7 +128,20 @@ void Writer::writeCustomData() { m_xml.writeStartElement("CustomData"); - // TODO implement + QHash customFields = m_meta->customFields(); + Q_FOREACH (const QString& key, customFields.keys()) { + writeCustomDataItem(key, customFields.value(key)); + } + + m_xml.writeEndElement(); +} + +void Writer::writeCustomDataItem(const QString& key, const QString& value) +{ + m_xml.writeStartElement("Item"); + + writeString("Key", key); + writeString("Value", value); m_xml.writeEndElement(); } diff --git a/src/core/Writer.h b/src/core/Writer.h index eeffe9b2f..62d0fb649 100644 --- a/src/core/Writer.h +++ b/src/core/Writer.h @@ -46,6 +46,7 @@ private: void writeCustomIcons(); void writeIcon(const Uuid& uuid, const QImage& image); void writeCustomData(); + void writeCustomDataItem(const QString& key, const QString& value); void writeRoot(); void writeGroup(const Group* group); void writeTimes(const TimeInfo& ti); diff --git a/tests/NewDatabase.xml b/tests/NewDatabase.xml index c4b12fb87..26b245f24 100644 --- a/tests/NewDatabase.xml +++ b/tests/NewDatabase.xml @@ -30,7 +30,16 @@ 2010-08-08T17:24:19Z lmU+9n0aeESKZvcEze+bRg== lmU+9n0aeESKZvcEze+bRg== - + + + A Sample Test Key + valu + + + custom key + blub + + diff --git a/tests/TestParser.cpp b/tests/TestParser.cpp index d085cf60a..85b193064 100644 --- a/tests/TestParser.cpp +++ b/tests/TestParser.cpp @@ -40,7 +40,8 @@ class TestParser : public QObject private Q_SLOTS: void initTestCase(); void testMetadata(); - void testCustomIcon(); + void testCustomIcons(); + void testCustomData(); void testGroupRoot(); void testGroup1(); void testGroup2(); @@ -97,7 +98,7 @@ void TestParser::testMetadata() QVERIFY(m_db->metadata()->lastTopVisibleGroup() == m_db->metadata()->lastSelectedGroup()); } -void TestParser::testCustomIcon() +void TestParser::testCustomIcons() { QCOMPARE(m_db->metadata()->customIcons().size(), 1); Uuid uuid = Uuid::fromBase64("++vyI+daLk6omox4a6kQGA=="); @@ -115,6 +116,15 @@ void TestParser::testCustomIcon() } } +void TestParser::testCustomData() +{ + QHash 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 TestParser::testGroupRoot() { const Group* group = m_db->rootGroup();