Make more key/value-type functions safe against reordered xml elements.

This commit is contained in:
Felix Geyer 2013-04-14 15:06:34 +02:00
parent 5588792344
commit 7a89510916

View file

@ -307,19 +307,27 @@ void KeePass2XmlReader::parseIcon()
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Icon"); Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Icon");
Uuid uuid; Uuid uuid;
QImage icon;
bool uuidSet = false;
bool iconSet = false;
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 = readUuid(); uuid = readUuid();
uuidSet = true;
} }
else if (m_xml.name() == "Data") { else if (m_xml.name() == "Data") {
QImage icon;
icon.loadFromData(readBinary()); icon.loadFromData(readBinary());
m_meta->addCustomIcon(uuid, icon); iconSet = true;
} }
else { else {
skipCurrentElement(); skipCurrentElement();
} }
} }
if (uuidSet && iconSet) {
m_meta->addCustomIcon(uuid, icon);
}
} }
void KeePass2XmlReader::parseBinaries() void KeePass2XmlReader::parseBinaries()
@ -372,17 +380,27 @@ void KeePass2XmlReader::parseCustomDataItem()
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Item"); Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Item");
QString key; QString key;
QString value;
bool keySet = false;
bool valueSet = false;
while (!m_xml.error() && m_xml.readNextStartElement()) { while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Key") { if (m_xml.name() == "Key") {
key = readString(); key = readString();
keySet = true;
} }
else if (m_xml.name() == "Value") { else if (m_xml.name() == "Value") {
m_meta->addCustomField(key, readString()); value = readString();
valueSet = true;
} }
else { else {
skipCurrentElement(); skipCurrentElement();
} }
} }
if (keySet && valueSet) {
m_meta->addCustomField(key, value);
}
} }
void KeePass2XmlReader::parseRoot() void KeePass2XmlReader::parseRoot()
@ -671,13 +689,19 @@ void KeePass2XmlReader::parseEntryString(Entry* entry)
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "String"); Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "String");
QString key; QString key;
QString value;
bool protect;
bool keySet = false;
bool valueSet = false;
while (!m_xml.error() && m_xml.readNextStartElement()) { while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Key") { if (m_xml.name() == "Key") {
key = readString(); key = readString();
keySet = true;
} }
else if (m_xml.name() == "Value") { else if (m_xml.name() == "Value") {
QXmlStreamAttributes attr = m_xml.attributes(); QXmlStreamAttributes attr = m_xml.attributes();
QString value = readString(); value = readString();
bool isProtected = attr.value("Protected") == "True"; bool isProtected = attr.value("Protected") == "True";
bool protectInMemory = attr.value("ProtectInMemory") == "True"; bool protectInMemory = attr.value("ProtectInMemory") == "True";
@ -691,12 +715,17 @@ void KeePass2XmlReader::parseEntryString(Entry* entry)
} }
} }
entry->attributes()->set(key, value, isProtected || protectInMemory); protect = isProtected || protectInMemory;
valueSet = true;
} }
else { else {
skipCurrentElement(); skipCurrentElement();
} }
} }
if (keySet && valueSet) {
entry->attributes()->set(key, value, protect);
}
} }
QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry) QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry)
@ -706,9 +735,14 @@ QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry)
QPair<QString, QString> poolRef; QPair<QString, QString> poolRef;
QString key; QString key;
QByteArray value;
bool keySet = false;
bool valueSet = false;
while (!m_xml.error() && m_xml.readNextStartElement()) { while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Key") { if (m_xml.name() == "Key") {
key = readString(); key = readString();
keySet = true;
} }
else if (m_xml.name() == "Value") { else if (m_xml.name() == "Value") {
QXmlStreamAttributes attr = m_xml.attributes(); QXmlStreamAttributes attr = m_xml.attributes();
@ -719,7 +753,7 @@ QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry)
} }
else { else {
// format compatbility // format compatbility
QByteArray value = readBinary(); value = readBinary();
bool isProtected = attr.hasAttribute("Protected") bool isProtected = attr.hasAttribute("Protected")
&& (attr.value("Protected") == "True"); && (attr.value("Protected") == "True");
@ -727,7 +761,7 @@ QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry)
m_randomStream->processInPlace(value); m_randomStream->processInPlace(value);
} }
entry->attachments()->set(key, value); valueSet = true;
} }
} }
else { else {
@ -735,6 +769,10 @@ QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry)
} }
} }
if (keySet && valueSet) {
entry->attachments()->set(key, value);
}
return poolRef; return poolRef;
} }
@ -766,18 +804,26 @@ void KeePass2XmlReader::parseAutoTypeAssoc(Entry* entry)
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Association"); Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Association");
AutoTypeAssociations::Association assoc; AutoTypeAssociations::Association assoc;
bool windowSet = false;
bool sequenceSet = false;
while (!m_xml.error() && m_xml.readNextStartElement()) { while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Window") { if (m_xml.name() == "Window") {
assoc.window = readString(); assoc.window = readString();
windowSet = true;
} }
else if (m_xml.name() == "KeystrokeSequence") { else if (m_xml.name() == "KeystrokeSequence") {
assoc.sequence = readString(); assoc.sequence = readString();
entry->autoTypeAssociations()->add(assoc); sequenceSet = true;
} }
else { else {
skipCurrentElement(); skipCurrentElement();
} }
} }
if (windowSet && sequenceSet) {
entry->autoTypeAssociations()->add(assoc);
}
} }
QList<Entry*> KeePass2XmlReader::parseEntryHistory() QList<Entry*> KeePass2XmlReader::parseEntryHistory()