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