mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-06-29 00:47:32 -04:00
Make KeePass2XmlReader::parseEntry() safe against reordered xml elements.
This commit is contained in:
parent
61ee763515
commit
3acb33e05a
2 changed files with 48 additions and 18 deletions
|
@ -28,6 +28,8 @@
|
||||||
#include "format/KeePass2RandomStream.h"
|
#include "format/KeePass2RandomStream.h"
|
||||||
#include "streams/QtIOCompressor"
|
#include "streams/QtIOCompressor"
|
||||||
|
|
||||||
|
typedef QPair<QString, QString> StringPair;
|
||||||
|
|
||||||
KeePass2XmlReader::KeePass2XmlReader()
|
KeePass2XmlReader::KeePass2XmlReader()
|
||||||
: m_randomStream(Q_NULLPTR)
|
: m_randomStream(Q_NULLPTR)
|
||||||
, m_db(Q_NULLPTR)
|
, m_db(Q_NULLPTR)
|
||||||
|
@ -553,7 +555,11 @@ Entry* KeePass2XmlReader::parseEntry(bool history)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Entry");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Entry");
|
||||||
|
|
||||||
Entry* entry = Q_NULLPTR;
|
Entry* entry = new Entry();
|
||||||
|
entry->setUpdateTimeinfo(false);
|
||||||
|
QList<Entry*> historyItems;
|
||||||
|
QList<StringPair> binaryRefs;
|
||||||
|
|
||||||
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "UUID") {
|
if (m_xml.name() == "UUID") {
|
||||||
Uuid uuid = readUuid();
|
Uuid uuid = readUuid();
|
||||||
|
@ -561,15 +567,8 @@ Entry* KeePass2XmlReader::parseEntry(bool history)
|
||||||
raiseError(6);
|
raiseError(6);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (history) {
|
|
||||||
entry = new Entry();
|
|
||||||
entry->setUpdateTimeinfo(false);
|
|
||||||
entry->setUuid(uuid);
|
entry->setUuid(uuid);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
entry = getEntry(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "IconID") {
|
else if (m_xml.name() == "IconID") {
|
||||||
int iconId = readNumber();
|
int iconId = readNumber();
|
||||||
|
@ -605,7 +604,10 @@ Entry* KeePass2XmlReader::parseEntry(bool history)
|
||||||
parseEntryString(entry);
|
parseEntryString(entry);
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "Binary") {
|
else if (m_xml.name() == "Binary") {
|
||||||
parseEntryBinary(entry);
|
QPair<QString, QString> ref = parseEntryBinary(entry);
|
||||||
|
if (!ref.first.isNull() && !ref.second.isNull()) {
|
||||||
|
binaryRefs.append(ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_xml.name() == "AutoType") {
|
else if (m_xml.name() == "AutoType") {
|
||||||
parseAutoType(entry);
|
parseAutoType(entry);
|
||||||
|
@ -615,7 +617,7 @@ Entry* KeePass2XmlReader::parseEntry(bool history)
|
||||||
raiseError(8);
|
raiseError(8);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parseEntryHistory(entry);
|
historyItems = parseEntryHistory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -623,6 +625,27 @@ Entry* KeePass2XmlReader::parseEntry(bool history)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (history) {
|
||||||
|
entry->setUpdateTimeinfo(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Entry* tmpEntry = entry;
|
||||||
|
|
||||||
|
entry = getEntry(tmpEntry->uuid());
|
||||||
|
entry->copyDataFrom(tmpEntry);
|
||||||
|
entry->setUpdateTimeinfo(false);
|
||||||
|
|
||||||
|
delete tmpEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_FOREACH (Entry* historyItem, historyItems) {
|
||||||
|
entry->addHistoryItem(historyItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_FOREACH (const StringPair& ref, binaryRefs) {
|
||||||
|
m_binaryMap.insertMulti(ref.first, qMakePair(entry, ref.second));
|
||||||
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,10 +682,12 @@ void KeePass2XmlReader::parseEntryString(Entry* entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeePass2XmlReader::parseEntryBinary(Entry* entry)
|
QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Binary");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Binary");
|
||||||
|
|
||||||
|
QPair<QString, QString> poolRef;
|
||||||
|
|
||||||
QString key;
|
QString key;
|
||||||
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Key") {
|
if (m_xml.name() == "Key") {
|
||||||
|
@ -672,7 +697,7 @@ void KeePass2XmlReader::parseEntryBinary(Entry* entry)
|
||||||
QXmlStreamAttributes attr = m_xml.attributes();
|
QXmlStreamAttributes attr = m_xml.attributes();
|
||||||
|
|
||||||
if (attr.hasAttribute("Ref")) {
|
if (attr.hasAttribute("Ref")) {
|
||||||
m_binaryMap.insertMulti(attr.value("Ref").toString(), qMakePair(entry, key));
|
poolRef = qMakePair(attr.value("Ref").toString(), key);
|
||||||
m_xml.skipCurrentElement();
|
m_xml.skipCurrentElement();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -692,6 +717,8 @@ void KeePass2XmlReader::parseEntryBinary(Entry* entry)
|
||||||
skipCurrentElement();
|
skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return poolRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeePass2XmlReader::parseAutoType(Entry* entry)
|
void KeePass2XmlReader::parseAutoType(Entry* entry)
|
||||||
|
@ -736,19 +763,22 @@ void KeePass2XmlReader::parseAutoTypeAssoc(Entry* entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeePass2XmlReader::parseEntryHistory(Entry* entry)
|
QList<Entry*> KeePass2XmlReader::parseEntryHistory()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "History");
|
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "History");
|
||||||
|
|
||||||
|
QList<Entry*> historyItems;
|
||||||
|
|
||||||
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
while (!m_xml.error() && m_xml.readNextStartElement()) {
|
||||||
if (m_xml.name() == "Entry") {
|
if (m_xml.name() == "Entry") {
|
||||||
Entry* historyItem = parseEntry(true);
|
historyItems.append(parseEntry(true));
|
||||||
entry->addHistoryItem(historyItem);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipCurrentElement();
|
skipCurrentElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return historyItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeInfo KeePass2XmlReader::parseTimes()
|
TimeInfo KeePass2XmlReader::parseTimes()
|
||||||
|
|
|
@ -63,10 +63,10 @@ private:
|
||||||
void parseDeletedObject();
|
void parseDeletedObject();
|
||||||
Entry* parseEntry(bool history);
|
Entry* parseEntry(bool history);
|
||||||
void parseEntryString(Entry* entry);
|
void parseEntryString(Entry* entry);
|
||||||
void parseEntryBinary(Entry* entry);
|
QPair<QString, QString> parseEntryBinary(Entry* entry);
|
||||||
void parseAutoType(Entry* entry);
|
void parseAutoType(Entry* entry);
|
||||||
void parseAutoTypeAssoc(Entry* entry);
|
void parseAutoTypeAssoc(Entry* entry);
|
||||||
void parseEntryHistory(Entry* entry);
|
QList<Entry*> parseEntryHistory();
|
||||||
TimeInfo parseTimes();
|
TimeInfo parseTimes();
|
||||||
|
|
||||||
QString readString();
|
QString readString();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue