void TestKeePass2Format::testXmlInvalidXmlChars() { 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)); auto entry = new Entry(); entry->setUuid(QUuid::createUuid()); 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); bool hasError; QString errorString; writeXml(&buffer, dbWrite.data(), hasError, errorString); QVERIFY(!hasError); buffer.seek(0); auto dbRead = readXml(&buffer, true, hasError, errorString); if (hasError) { qWarning("Database read error: %s", qPrintable(errorString)); } QVERIFY(!hasError); QVERIFY(dbRead.data()); QCOMPARE(dbRead->rootGroup()->entries().size(), 1); Entry* entryRead = dbRead->rootGroup()->entries().at(0); EntryAttributes* attrRead = entryRead->attributes(); QCOMPARE(attrRead->value("PlainInvalid"), QString()); QCOMPARE(attrRead->value("PlainValid"), strPlainValid); QCOMPARE(attrRead->value("SingleHighSurrogate1"), QString()); QCOMPARE(attrRead->value("SingleHighSurrogate2"), QString("12")); QCOMPARE(attrRead->value("HighHighSurrogate"), QString()); QCOMPARE(attrRead->value("SingleLowSurrogate1"), QString()); QCOMPARE(attrRead->value("SingleLowSurrogate2"), QString("12")); QCOMPARE(attrRead->value("LowLowSurrogate"), QString()); QCOMPARE(attrRead->value("SurrogateValid1"), strSurrogateValid1); QCOMPARE(attrRead->value("SurrogateValid2"), strSurrogateValid2); }