Revision control
++ // Copyright (C) 2021 The Qt Company Ltd.
++ // Copyright (C) 2016 Intel Corporation.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++
++
++ #include <QtTest/QtTest>
++
++ #include <qtextcodec.h>
++ #include <qfile.h>
++ #include <time.h>
++ #if QT_CONFIG(process)
++ # include <qprocess.h>
++ #endif
++ #include <QThreadPool>
++
++ QT_BEGIN_NAMESPACE
++
++ class tst_QTextCodec : public QObject
++ {
++ Q_OBJECT
++
++ private slots:
++ void threadSafety();
++
++ void toUnicode_data();
++ void toUnicode();
++ void codecForName_data();
++ void codecForName();
++ void fromUnicode_data();
++ void fromUnicode();
++ void toUnicode_codecForHtml();
++ void toUnicode_incremental();
++ void codecForLocale();
++
++ void asciiToIscii() const;
++ void unicodeToISCII();
++
++ void nonFlaggedCodepointFFFF() const;
++ void flagF7808080() const;
++ void nonFlaggedEFBFBF() const;
++ void decode0D() const;
++ void aliasForUTF16() const;
++ void mibForTSCII() const;
++ void codecForTSCII() const;
++ void asciiToTSCII();
++ void unicodeToTSCII();
++
++ void iso8859_1() const;
++ void iso8859_15() const;
++ void iso8859_16() const;
++
++ void utf32Codec_data();
++ void utf32Codec();
++
++ void utf8Codec_data();
++ void utf8Codec();
++
++ void utf8bom_data();
++ void utf8bom();
++
++ void utf8stateful_data();
++ void utf8stateful();
++
++ void utfHeaders_data();
++ void utfHeaders();
++
++ void codecForHtml_data();
++ void codecForHtml();
++
++ void codecForUtfText_data();
++ void codecForUtfText();
++
++ #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
++ void toLocal8Bit();
++ #endif
++
++ void invalidNames();
++ void checkAliases_data();
++ void checkAliases();
++
++ void moreToFromUnicode_data();
++ void moreToFromUnicode();
++
++ void shiftJis();
++ void userCodec();
++
++ void nullInputZeroOrNegativeLength_data();
++ void nullInputZeroOrNegativeLength();
++
++ void retainNullness_data();
++ void retainNullness();
++
++ void canEncode();
++ void canEncode_data();
++
++ void tsciiEncoderDoesNotReadPastTheEnd_data();
++ void tsciiEncoderDoesNotReadPastTheEnd();
++
++ void iconvEncoderPendingSurrogateDoesNotOverflow();
++
++ void icuNoIntOverflowInFromUnicode();
++ };
++
++ void tst_QTextCodec::toUnicode_data()
++ {
++ QTest::addColumn<QString>("fileName");
++ QTest::addColumn<QString>("codecName");
++
++ QTest::newRow( "korean-eucKR" ) << QFINDTESTDATA("korean.txt") << "eucKR";
++ QTest::newRow( "UTF-8" ) << QFINDTESTDATA("utf8.txt") << "UTF-8";
++ }
++
++ void tst_QTextCodec::toUnicode()
++ {
++ QFETCH( QString, fileName );
++ QFETCH( QString, codecName );
++
++ QFile file( fileName );
++
++ if (file.open(QT_PREPEND_NAMESPACE(QIODevice::ReadOnly))) {
++ QByteArray ba = file.readAll();
++ QVERIFY(!ba.isEmpty());
++ QTextCodec *c = QTextCodec::codecForName( codecName.toLatin1() );
++ QVERIFY(c != 0);
++ QString uniString = c->toUnicode( ba );
++ if (codecName == QLatin1String("UTF-8")) {
++ QCOMPARE(uniString, QString::fromUtf8(ba));
++ QCOMPARE(ba, uniString.toUtf8());
++ }
++ QVERIFY(!uniString.isEmpty());
++ QCOMPARE( ba, c->fromUnicode( uniString ) );
++ QCOMPARE(ba, c->fromUnicode(QStringView(uniString)) );
++
++ char ch = '\0';
++ QVERIFY(c->toUnicode(&ch, 1).size() == 1);
++ QVERIFY(c->toUnicode(&ch, 1).at(0).unicode() == 0);
++ } else {
++ QFAIL(qPrintable("File could not be opened: " + file.errorString()));
++ }
++ }
++
++ void tst_QTextCodec::codecForName_data()
++ {
++ QTest::addColumn<QString>("hint");
++ QTest::addColumn<QString>("actualCodecName");
++
++ QTest::newRow("data1") << "iso88591" << "ISO-8859-1";
++ QTest::newRow("data2") << "iso88592" << "ISO-8859-2";
++ QTest::newRow("data3") << " IsO(8)8/5*9-2 " << "ISO-8859-2";
++ QTest::newRow("data4") << " IsO(8)8/5*2-9 " << "";
++ QTest::newRow("data5") << "latin2" << "ISO-8859-2";
++ }
++
++ void tst_QTextCodec::codecForName()
++ {
++ QFETCH(QString, hint);
++ QFETCH(QString, actualCodecName);
++
++ QTextCodec *codec = QTextCodec::codecForName(hint.toLatin1());
++ if (actualCodecName.isEmpty()) {
++ QVERIFY(!codec);
++ } else {
++ QVERIFY(codec != 0);
++ QCOMPARE(QString(codec->name()), actualCodecName);
++ }
++ }
++
++ void tst_QTextCodec::fromUnicode_data()
++ {
++ QTest::addColumn<QString>("codecName");
++ QTest::addColumn<bool>("eightBit");
++
++ QTest::newRow("ISO-8859-1") << "ISO-8859-1" << true;
++ QTest::newRow("ISO-8859-2") << "ISO-8859-2" << true;
++ QTest::newRow("ISO-8859-3") << "ISO-8859-3" << true;
++ QTest::newRow("ISO-8859-4") << "ISO-8859-4" << true;
++ QTest::newRow("ISO-8859-5") << "ISO-8859-5" << true;
++ QTest::newRow("ISO-8859-6") << "ISO-8859-6" << true;
++ QTest::newRow("ISO-8859-7") << "ISO-8859-7" << true;
++ QTest::newRow("ISO-8859-8") << "ISO-8859-8" << true;
++ QTest::newRow("ISO-8859-9") << "ISO-8859-9" << true;
++ QTest::newRow("ISO-8859-10") << "ISO-8859-10" << true;
++ QTest::newRow("ISO-8859-13") << "ISO-8859-13" << true;
++ QTest::newRow("ISO-8859-14") << "ISO-8859-14" << true;
++ QTest::newRow("ISO-8859-15") << "ISO-8859-15" << true;
++ // QTest::newRow("ISO-8859-16") << "ISO-8859-16" << true;
++
++ QTest::newRow("IBM850") << "IBM850" << true;
++ QTest::newRow("IBM874") << "IBM874" << true;
++ QTest::newRow("IBM866") << "IBM866" << true;
++
++ QTest::newRow("windows-1250") << "windows-1250" << true;
++ QTest::newRow("windows-1251") << "windows-1251" << true;
++ QTest::newRow("windows-1252") << "windows-1252" << true;
++ QTest::newRow("windows-1253") << "windows-1253" << true;
++ QTest::newRow("windows-1254") << "windows-1254" << true;
++ QTest::newRow("windows-1255") << "windows-1255" << true;
++ QTest::newRow("windows-1256") << "windows-1256" << true;
++ QTest::newRow("windows-1257") << "windows-1257" << true;
++ QTest::newRow("windows-1258") << "windows-1258" << true;
++
++ QTest::newRow("Apple Roman") << "Apple Roman" << true;
++ //QTest::newRow("WINSAMI2") << "WINSAMI2" << true;
++ QTest::newRow("TIS-620") << "TIS-620" << true;
++ QTest::newRow("SJIS") << "SJIS" << false;
++
++ // all codecs from documentation
++ QTest::newRow("Big5") << "Big5" << false;
++ QTest::newRow("Big5-HKSCS") << "Big5-HKSCS" << false;
++ QTest::newRow("CP949") << "CP949" << false;
++ QTest::newRow("windows-949") << "windows-949" << false;
++ QTest::newRow("EUC-JP") << "EUC-JP" << false;
++ QTest::newRow("EUC-KR") << "EUC-KR" << false;
++ QTest::newRow("GB18030") << "GB18030" << false;
++ QTest::newRow("HP-ROMAN8") << "HP-ROMAN8" << false;
++ QTest::newRow("IBM 850") << "IBM 850" << false;
++ QTest::newRow("IBM 866") << "IBM 866" << false;
++ QTest::newRow("IBM 874") << "IBM 874" << false;
++ QTest::newRow("ISO 2022-JP") << "ISO 2022-JP" << false;
++ //ISO 8859-1 to 10 and ISO 8859-13 to 16 tested previously
++ // Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml tested in Iscii test
++ QTest::newRow("KOI8-R") << "KOI8-R" << false;
++ QTest::newRow("KOI8-U") << "KOI8-U" << false;
++ QTest::newRow("Macintosh") << "Macintosh" << true;
++ QTest::newRow("Shift-JIS") << "Shift-JIS" << false;
++ QTest::newRow("TIS-620") << "TIS-620" << false;
++ QTest::newRow("TSCII") << "TSCII" << false;
++ QTest::newRow("UTF-8") << "UTF-8" << false;
++ QTest::newRow("UTF-16") << "UTF-16" << false;
++ QTest::newRow("UTF-16BE") << "UTF-16BE" << false;
++ QTest::newRow("UTF-16LE") << "UTF-16LE" << false;
++ QTest::newRow("UTF-32") << "UTF-32" << false;
++ QTest::newRow("UTF-32BE") << "UTF-32BE" << false;
++ QTest::newRow("UTF-32LE") << "UTF-32LE" << false;
++ //Windows-1250 to 1258 tested previously
++ }
++
++ void tst_QTextCodec::fromUnicode()
++ {
++ QFETCH(QString, codecName);
++ QFETCH(bool, eightBit);
++
++ QTextCodec *codec = QTextCodec::codecForName(codecName.toLatin1());
++ QVERIFY(codec != 0);
++
++ // Check if the reverse lookup is what we expect
++ if (eightBit) {
++ char chars[128];
++ for (int i = 0; i < 128; ++i)
++ chars[i] = i + 128;
++ QString s = codec->toUnicode(chars, 128);
++ QByteArray c = codec->fromUnicode(s);
++ QCOMPARE(c.size(), 128);
++
++ int numberOfQuestionMarks = 0;
++ for (int i = 0; i < 128; ++i) {
++ if (c.at(i) == '?')
++ ++numberOfQuestionMarks;
++ else
++ QCOMPARE(c.at(i), char(i + 128));
++ }
++ QVERIFY(numberOfQuestionMarks != 128);
++ }
++
++ /*
++ If the encoding is a superset of ASCII, test that the byte
++ array is correct (no off by one, no trailing '\0').
++ */
++ QByteArray result = codec->fromUnicode(u"abc");
++ if (eightBit && result.startsWith('a')) {
++ QCOMPARE(result.size(), 3);
++ QCOMPARE(result, QByteArray("abc"));
++ } else {
++ QVERIFY(true);
++ }
++ }
++
++ void tst_QTextCodec::toUnicode_codecForHtml()
++ {
++ QFile file(QFINDTESTDATA("QT4-crashtest.txt"));
++ QVERIFY(file.open(QFile::ReadOnly));
++
++ QByteArray data = file.readAll();
++ QTextCodec *codec = QTextCodec::codecForHtml(data);
++ codec->toUnicode(data); // this line crashes
++ }
++
++
++ void tst_QTextCodec::toUnicode_incremental()
++ {
++ QByteArray ba;
++ ba += char(0xf0);
++ ba += char(0x90);
++ ba += char(0x80);
++ ba += char(0x80);
++ ba += char(0xf4);
++ ba += char(0x8f);
++ ba += char(0xbf);
++ ba += char(0xbd);
++
++ QString expected = QString::fromUtf8(ba);
++
++ QString incremental;
++ QTextDecoder *utf8Decoder = QTextCodec::codecForMib(106)->makeDecoder();
++
++ QString actual;
++ for (int i = 0; i < ba.size(); ++i)
++ utf8Decoder->toUnicode(&actual, ba.constData() + i, 1);
++
++ QCOMPARE(actual, expected);
++
++
++ delete utf8Decoder;
++ }
++
++ void tst_QTextCodec::codecForLocale()
++ {
++ QTextCodec *codec = QTextCodec::codecForLocale();
++ QVERIFY(codec != 0);
++
++ // The rest of this test is for Unix only
++ #if defined(Q_OS_UNIX)
++ // get a time string that is locale-encoded
++ QByteArray originalLocaleEncodedTimeString;
++ originalLocaleEncodedTimeString.resize(1024);
++ time_t t;
++ time(&t);
++ int r = strftime(originalLocaleEncodedTimeString.data(),
++ originalLocaleEncodedTimeString.size(),
++ "%A%a%B%b%Z",
++ localtime(&t));
++ QVERIFY(r != 0);
++ originalLocaleEncodedTimeString.resize(r);
++
++ QString unicodeTimeString = codec->toUnicode(originalLocaleEncodedTimeString);
++ QByteArray localeEncodedTimeString = codec->fromUnicode(unicodeTimeString);
++ QCOMPARE(localeEncodedTimeString, originalLocaleEncodedTimeString);
++
++ // find a codec that is not the codecForLocale()
++ QTextCodec *codec2 = 0;
++ const auto availableMibs = QTextCodec::availableMibs();
++ for (int mib : availableMibs ) {
++ if (mib != codec->mibEnum()) {
++ codec2 = QTextCodec::codecForMib(mib);
++ if (codec2)
++ break;
++ }
++ }
++
++ // Only run the rest of the test if we could find a codec that is not
++ // already the codecForLocale().
++ if (codec2) {
++ // set it, codecForLocale() should return it now
++ QTextCodec::setCodecForLocale(codec2);
++ QCOMPARE(QTextCodec::codecForLocale(), codec2);
++
++ // reset back to the default
++ QTextCodec::setCodecForLocale(0);
++ QCOMPARE(QTextCodec::codecForLocale(), codec);
++ }
++ #endif
++ }
++
++ void tst_QTextCodec::asciiToIscii() const
++ {
++ /* Add all low, 7-bit ASCII characters. */
++ QString ascii;
++ const int len = 0xA0 - 1;
++ ascii.resize(len);
++
++ for(int i = 0; i < len; ++i)
++ ascii[i] = QChar(i + 1);
++
++ static const char *const isciiCodecs[] =
++ {
++ "Iscii-Mlm",
++ "Iscii-Knd",
++ "Iscii-Tlg",
++ "Iscii-Tml",
++ "Iscii-Ori",
++ "Iscii-Gjr",
++ "Iscii-Pnj",
++ "Iscii-Bng",
++ "Iscii-Dev"
++ };
++ const int isciiCodecsLen = sizeof(isciiCodecs) / sizeof(const char *);
++
++ for(int i = 0; i < isciiCodecsLen; ++i) {
++ /* For each codec. */
++
++ const QTextCodec *const textCodec = QTextCodec::codecForName(isciiCodecs[i]);
++ if (!textCodec)
++ QSKIP("No ISCII codecs available.");
++
++ for(int i2 = 0; i2 < len; ++i2) {
++ /* For each character in ascii. */
++ const QChar c(ascii[i2]);
++ QVERIFY2(textCodec->canEncode(c), qPrintable(QString::fromLatin1("Failed to encode %1 with encoding %2")
++ .arg(QString::number(c.unicode()), QString::fromLatin1(textCodec->name().constData()))));
++ }
++
++ QVERIFY2(textCodec->canEncode(ascii), qPrintable(QString::fromLatin1("Failed for full string with encoding %1")
++ .arg(QString::fromLatin1(textCodec->name().constData()))));
++ QVERIFY(textCodec->canEncode(QStringView(ascii)));
++ }
++ }
++
++ void tst_QTextCodec::unicodeToISCII()
++ {
++ auto codec = QTextCodec::codecForName("iscii-tml");
++ QVERIFY(codec != nullptr);
++
++ auto ba = QByteArray::fromHex("ABA3B3DD");
++ auto steel = QString("\u0b8e\u0b83\u0b95\u0bc1");
++
++ QTextCodec::ConverterState state;
++ QCOMPARE(codec->fromUnicode(steel.constData(), steel.size(), &state), ba);
++ state.clear();
++ QCOMPARE(codec->toUnicode(ba.constData(), ba.size(), &state), steel);
++
++ codec = QTextCodec::codecForName("iscii-dev");
++ QVERIFY(codec != nullptr);
++
++ ba = QByteArray::fromHex("e8e8");
++ auto zwnj = QString("\u094d\u200c");
++
++ state.clear();
++ QCOMPARE(codec->fromUnicode(zwnj.constData(), zwnj.size(), &state), ba);
++ state.clear();
++ QCOMPARE(codec->toUnicode(ba.constData(), ba.size(), &state), zwnj);
++
++ ba = QByteArray::fromHex("e8e9");
++ auto zwj = QString("\u094d\u200d");
++
++ state.clear();
++ QCOMPARE(codec->fromUnicode(zwj.constData(), zwj.size(), &state), ba);
++ state.clear();
++ QCOMPARE(codec->toUnicode(ba.constData(), ba.size(), &state), zwj);
++ }
++
++ void tst_QTextCodec::nonFlaggedCodepointFFFF() const
++ {
++ //Check that the code point 0xFFFF (=non-character code 0xEFBFBF) is not flagged
++ const QChar ch(0xFFFF);
++
++ QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
++ QVERIFY(codec);
++
++ const QByteArray asDecoded = codec->fromUnicode(QStringView(&ch, 1));
++ QCOMPARE(asDecoded, QByteArray("\357\277\277"));
++
++ QByteArray ffff("\357\277\277");
++ QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
++ QVERIFY(codec->toUnicode(ffff.constData(), ffff.size(), &state) == QByteArray::fromHex("EFBFBF"));
++ }
++
++ void tst_QTextCodec::flagF7808080() const
++ {
++ /* This test case stems from test not-wf-sa-170, tests/qxmlstream/XML-Test-Suite/xmlconf/xmltest/not-wf/sa/166.xml,
++ * whose description reads:
++ *
++ * "Four byte UTF-8 encodings can encode UCS-4 characters
++ * which are beyond the range of legal XML characters
++ * (and can't be expressed in Unicode surrogate pairs).
++ * This document holds such a character."
++ *
++ * In binary, this is:
++ * 11110111100000001000000010000000
++ * * * * *
++ * 11110www10xxxxxx10yyyyyy10zzzzzz
++ *
++ * With multibyte logic removed it is the codepoint 0x1C0000.
++ */
++ QByteArray input;
++ input.resize(4);
++ input[0] = char(0xF7);
++ input[1] = char(0x80);
++ input[2] = char(0x80);
++ input[3] = char(0x80);
++
++ QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
++ QVERIFY(codec);
++
++ //QVERIFY(!codec->canEncode(QChar(0x1C0000)));
++
++ QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
++ QCOMPARE(codec->toUnicode(input.constData(), input.size(), &state), QString(input.size(), QChar(0)));
++ }
++
++ void tst_QTextCodec::nonFlaggedEFBFBF() const
++ {
++ /* Check that the codec does NOT flag EFBFBF.
++ * This is a regression test; see QTBUG-33229
++ */
++ QByteArray validInput;
++ validInput.resize(3);
++ validInput[0] = char(0xEF);
++ validInput[1] = char(0xBF);
++ validInput[2] = char(0xBF);
++
++ const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
++ QVERIFY(codec);
++
++ {
++ //QVERIFY(!codec->canEncode(QChar(0xFFFF)));
++ QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
++ QVERIFY(codec->toUnicode(validInput.constData(), validInput.size(), &state) == QByteArray::fromHex("EFBFBF"));
++
++ QByteArray start("<?pi ");
++ start.append(validInput);
++ start.append("?>");
++ }
++
++ // Check that 0xEFBFBF is correctly decoded when preceded by an arbitrary character
++ {
++ QByteArray start("B");
++ start.append(validInput);
++
++ QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
++ QVERIFY(codec->toUnicode(start.constData(), start.size(), &state) == QByteArray("B").append(QByteArray::fromHex("EFBFBF")));
++ }
++ }
++
++ void tst_QTextCodec::decode0D() const
++ {
++ QByteArray input;
++ input.resize(3);
++ input[0] = 'A';
++ input[1] = '\r';
++ input[2] = 'B';
++
++ QCOMPARE(QString::fromUtf8(input.constData()).toUtf8(), input);
++ }
++
++ void tst_QTextCodec::aliasForUTF16() const
++ {
++ QVERIFY(QTextCodec::codecForName("UTF-16")->aliases().isEmpty());
++ }
++
++ void tst_QTextCodec::mibForTSCII() const
++ {
++ QTextCodec *codec = QTextCodec::codecForName("TSCII");
++ QVERIFY(codec);
++ QCOMPARE(codec->mibEnum(), 2107);
++ }
++
++ void tst_QTextCodec::codecForTSCII() const
++ {
++ QTextCodec *codec = QTextCodec::codecForMib(2107);
++ QVERIFY(codec);
++ QCOMPARE(codec->mibEnum(), 2107);
++ }
++
++ void tst_QTextCodec::asciiToTSCII()
++ {
++ /* Add all low, 7-bit ASCII characters. */
++ QString ascii;
++ const int len = 0x7F - 1;
++ ascii.resize(len);
++
++ for (int i = 0; i < len; ++i)
++ ascii[i] = QChar(i + 1);
++
++ QTextCodec* textCodec = QTextCodec::codecForName("TSCII");
++ QVERIFY(textCodec);
++
++ for (int i2 = 0; i2 < len; ++i2) {
++ /* For each character in ascii. */
++ const QChar c(ascii[i2]);
++ QVERIFY2(textCodec->canEncode(c),
++ qPrintable(QString::fromLatin1("Failed to encode %1 with encoding TSCII")
++ .arg(QString::number(c.unicode()))));
++ }
++
++ QVERIFY(textCodec->canEncode(QStringView(ascii)));
++ QVERIFY2(textCodec->canEncode(ascii), "Failed for full string with encoding TSCII");
++ }
++
++ void tst_QTextCodec::unicodeToTSCII()
++ {
++ QTextCodec* codec = QTextCodec::codecForName("TSCII");
++ QVERIFY(codec != nullptr);
++
++ auto st = QString("\u0BA4\u0BBE\u0BAF\u0BCDKCharselect unicode block name");
++ auto ba = QByteArray::fromHex("BEA1F6") + "KCharselect unicode block name";
++
++ QTextCodec::ConverterState state;
++ QCOMPARE(codec->fromUnicode(st.constData(), st.size(), &state), ba);
++ QCOMPARE(codec->toUnicode(ba.constData(), ba.size(), &state), st);
++
++ st = QString("\u0BB5\u0BA3\u0B95\u0BCD\u0B95\u0BAE\u0BCD"); // Welcome
++ ba = QByteArray::fromHex("c5bdecb8f5");
++
++ state.clear();
++ QCOMPARE(codec->fromUnicode(st.constData(), st.size(), &state), ba);
++ QCOMPARE(codec->toUnicode(ba.constData(), ba.size(), &state), st);
++ }
++
++ void tst_QTextCodec::iso8859_1() const
++ {
++ QTextCodec* codec = QTextCodec::codecForName("ISO8859-1");
++ QVERIFY(codec);
++ QCOMPARE(codec->name(), QByteArray("ISO-8859-1"));
++
++ auto st = QString("Invalid unicode character "
++ "\u20AC"); // EURO SIGN
++ auto ba = QByteArray::fromHex("496e76616c696420756e69636f646520636861726163746572203f");
++ QTextCodec::ConverterState state;
++ QCOMPARE(codec->fromUnicode(st.constData(), st.size(), &state), ba);
++ }
++
++ void tst_QTextCodec::iso8859_15() const
++ {
++ QTextCodec* codec = QTextCodec::codecForName("ISO8859-15");
++ QVERIFY(codec);
++ QCOMPARE(codec->name(), QByteArray("ISO-8859-15"));
++
++ auto st = QString("Special unicode characters "
++ "\u20AC, " // EURO SIGN
++ "\u0160, " // LATIN CAPITAL LETTER S WITH CARON
++ "\u0161, " // LATIN SMALL LETTER S WITH CARON
++ "\u017d, " // LATIN CAPITAL LETTER Z WITH CARON
++ "\u017e, " // LATIN SMALL LETTER Z WITH CARON
++ "\u0152, " // LATIN CAPITAL LIGATURE OE
++ "\u0153, " // LATIN SMALL LIGATURE OE
++ "\u0178"); // LATIN CAPITAL LETTER Y WITH DIAERESIS
++ auto ba = QByteArray::fromHex("5370656369616c20756e69636f6465206368617261637465727320"
++ "a42C20" // EURO SIGN
++ "a62C20" // LATIN CAPITAL LETTER S WITH CARON
++ "a82C20" // LATIN SMALL LETTER S WITH CARON
++ "b42C20" // LATIN CAPITAL LETTER Z WITH CARON
++ "b82C20" // LATIN SMALL LETTER Z WITH CARON
++ "bc2C20" // LATIN CAPITAL LIGATURE OE
++ "bd2C20" // LATIN SMALL LIGATURE OE
++ "be"); // LATIN CAPITAL LETTER Y WITH DIAERESIS
++
++ QTextCodec::ConverterState state;
++ QCOMPARE(codec->fromUnicode(st.constData(), st.size(), &state), ba);
++ QCOMPARE(codec->toUnicode(ba.constData(), ba.size(), &state), st);
++ }
++
++ void tst_QTextCodec::iso8859_16() const
++ {
++ QTextCodec *codec = QTextCodec::codecForName("ISO8859-16");
++ QVERIFY(codec);
++ QCOMPARE(codec->name(), QByteArray("ISO-8859-16"));
++ }
++
++ void tst_QTextCodec::utf32Codec_data()
++ {
++ QTest::addColumn<QVector<char32_t> >("utf32");
++ QTest::addColumn<QString>("utf16");
++
++ QTest::newRow("empty") << QVector<char32_t>{} << QString{};
++
++ auto addChakmaDigit = [](int n) {
++ const uint zeroVal = 0x11136; // Unicode's representation of Chakma zero
++ char32_t digit = zeroVal + n;
++ QVector<char32_t> utf32 = { digit };
++ QChar utf16_str[] = { QChar::highSurrogate(digit), QChar::lowSurrogate(digit) };
++ QString utf16(utf16_str, 2);
++ QTest::addRow("Chakma digit %d", n) << utf32 << utf16;
++ };
++ for (int n = 0; n < 10; ++n)
++ addChakmaDigit(n);
++ }
++
++ void tst_QTextCodec::utf32Codec()
++ {
++ QFETCH(const QVector<char32_t>, utf32);
++ QFETCH(const QString, utf16);
++ QByteArray encoded(reinterpret_cast<const char *>(utf32.data()),
++ sizeof(char32_t) * utf32.size());
++ QTextCodec *codec = QTextCodec::codecForName("UTF-32");
++
++ QCOMPARE(codec->toUnicode(encoded), utf16);
++
++ // prepend BOM because QTextCodec sets us up the BOM
++ char32_t bom = QChar::ByteOrderMark;
++ encoded.prepend(reinterpret_cast<const char *>(&bom), sizeof(bom));
++ QCOMPARE(codec->fromUnicode(utf16), encoded);
++ }
++
++ static QString fromInvalidUtf8Sequence(const QByteArray &ba)
++ {
++ return QString().fill(QChar::ReplacementCharacter, ba.size());
++ }
++
++ // copied from tst_QString::fromUtf8_data()
++ void tst_QTextCodec::utf8Codec_data()
++ {
++ QTest::addColumn<QByteArray>("utf8");
++ QTest::addColumn<QString>("res");
++ QTest::addColumn<int>("len");
++ QString str;
++
++ QTest::newRow("str0") << QByteArray("abcdefgh") << QString("abcdefgh") << -1;
++ QTest::newRow("str0-len") << QByteArray("abcdefgh") << QString("abc") << 3;
++ QTest::newRow("str1") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
++ << QString::fromLatin1("\366\344\374\326\304\334\370\346\345\330\306\305") << -1;
++ QTest::newRow("str1-len") << QByteArray("\303\266\303\244\303\274\303\226\303\204\303\234\303\270\303\246\303\245\303\230\303\206\303\205")
++ << QString::fromLatin1("\366\344\374\326\304") << 10;
++
++ str += QChar(0x05e9);
++ str += QChar(0x05d3);
++ str += QChar(0x05d2);
++ QTest::newRow("str2") << QByteArray("\327\251\327\223\327\222") << str << -1;
++
++ str = QChar(0x05e9);
++ QTest::newRow("str2-len") << QByteArray("\327\251\327\223\327\222") << str << 2;
++
++ str = QChar(0x20ac);
++ str += " some text";
++ QTest::newRow("str3") << QByteArray("\342\202\254 some text") << str << -1;
++
++ str = QChar(0x20ac);
++ str += " some ";
++ QTest::newRow("str3-len") << QByteArray("\342\202\254 some text") << str << 9;
++
++ str = "hello";
++ str += QChar::ReplacementCharacter;
++ str += QChar(0x68);
++ str += QChar::ReplacementCharacter;
++ str += QChar::ReplacementCharacter;
++ str += QChar::ReplacementCharacter;
++ str += QChar::ReplacementCharacter;
++ str += QChar(0x61);
++ str += QChar::ReplacementCharacter;
++ QTest::newRow("invalid utf8") << QByteArray("hello\344h\344\344\366\344a\304") << str << -1;
++ QTest::newRow("invalid utf8-len") << QByteArray("hello\344h\344\344\366\344a\304") << QString("hello") << 5;
++
++ str = "Prohl";
++ str += QChar::ReplacementCharacter;
++ str += QChar::ReplacementCharacter;
++ str += QLatin1Char('e');
++ str += QChar::ReplacementCharacter;
++ str += " plugin";
++ str += QChar::ReplacementCharacter;
++ str += " Netscape";
++
++ QTest::newRow("task28417") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << str << -1;
++ QTest::newRow("task28417-len") << QByteArray("Prohl\355\276e\350 plugin\371 Netscape") << QString("") << 0;
++
++ QTest::newRow("null-1") << QByteArray() << QString() << -1;
++ QTest::newRow("null0") << QByteArray() << QString() << 0;
++ // QTest::newRow("null5") << QByteArray() << QString() << 5;
++ QTest::newRow("empty-1") << QByteArray("\0abcd", 5) << QString() << -1;
++ QTest::newRow("empty0") << QByteArray() << QString() << 0;
++ QTest::newRow("empty5") << QByteArray("\0abcd", 5) << QString::fromLatin1("\0abcd", 5) << 5;
++ QTest::newRow("other-1") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab") << -1;
++ QTest::newRow("other5") << QByteArray("ab\0cd", 5) << QString::fromLatin1("ab\0cd", 5) << 5;
++
++ str = "Old Italic: ";
++ str += QChar(0xd800);
++ str += QChar(0xdf00);
++ str += QChar(0xd800);
++ str += QChar(0xdf01);
++ str += QChar(0xd800);
++ str += QChar(0xdf02);
++ str += QChar(0xd800);
++ str += QChar(0xdf03);
++ str += QChar(0xd800);
++ str += QChar(0xdf04);
++ QTest::newRow("surrogate") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str << -1;
++
++ QTest::newRow("surrogate-len") << QByteArray("Old Italic: \360\220\214\200\360\220\214\201\360\220\214\202\360\220\214\203\360\220\214\204") << str.left(16) << 20;
++
++
++ // 2.1.1 U+00000000
++ QByteArray utf8;
++ utf8 += char(0x00);
++ str = QChar(QChar::Null);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.1") << utf8 << str << 1;
++
++ // 2.1.2 U+00000080
++ utf8.clear();
++ utf8 += char(0xc2);
++ utf8 += char(0x80);
++ str = QChar(0x80);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.2") << utf8 << str << -1;
++
++ // 2.1.3 U+00000800
++ utf8.clear();
++ utf8 += char(0xe0);
++ utf8 += char(0xa0);
++ utf8 += char(0x80);
++ str = QChar(0x800);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.3") << utf8 << str << -1;
++
++ // 2.1.4 U+00010000
++ utf8.clear();
++ utf8 += char(0xf0);
++ utf8 += char(0x90);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str.clear();
++ str += QChar(0xd800);
++ str += QChar(0xdc00);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.4") << utf8 << str << -1;
++
++ // 2.1.5 U+00200000 (not a valid Unicode character)
++ utf8.clear();
++ utf8 += char(0xf8);
++ utf8 += char(0x88);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.5") << utf8 << str << -1;
++
++ // 2.1.6 U+04000000 (not a valid Unicode character)
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x84);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.1.6") << utf8 << str << -1;
++
++ // 2.2.1 U+0000007F
++ utf8.clear();
++ utf8 += char(0x7f);
++ str = QChar(0x7f);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.1") << utf8 << str << -1;
++
++ // 2.2.2 U+000007FF
++ utf8.clear();
++ utf8 += char(0xdf);
++ utf8 += char(0xbf);
++ str = QChar(0x7ff);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.2") << utf8 << str << -1;
++
++ // 2.2.3 U+000FFFF - non-character code
++ utf8.clear();
++ utf8 += char(0xef);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = QString::fromUtf8(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.3") << utf8 << str << -1;
++
++ // 2.2.4 U+001FFFFF
++ utf8.clear();
++ utf8 += char(0xf7);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.4") << utf8 << str << -1;
++
++ // 2.2.5 U+03FFFFFF (not a valid Unicode character)
++ utf8.clear();
++ utf8 += char(0xfb);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.5") << utf8 << str << -1;
++
++ // 2.2.6 U+7FFFFFFF
++ utf8.clear();
++ utf8 += char(0xfd);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.6") << utf8 << str << -1;
++
++ // 2.3.1 U+0000D7FF
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0x9f);
++ utf8 += char(0xbf);
++ str = QChar(0xd7ff);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.1") << utf8 << str << -1;
++
++ // 2.3.2 U+0000E000
++ utf8.clear();
++ utf8 += char(0xee);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = QChar(0xe000);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.2") << utf8 << str << -1;
++
++ // 2.3.3 U+0000FFFD
++ utf8.clear();
++ utf8 += char(0xef);
++ utf8 += char(0xbf);
++ utf8 += char(0xbd);
++ str = QChar(QChar::ReplacementCharacter);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.3") << utf8 << str << -1;
++
++ // 2.3.4 U+0010FFFD
++ utf8.clear();
++ utf8 += char(0xf4);
++ utf8 += char(0x8f);
++ utf8 += char(0xbf);
++ utf8 += char(0xbd);
++ str.clear();
++ str += QChar(0xdbff);
++ str += QChar(0xdffd);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.4") << utf8 << str << -1;
++
++ // 2.3.5 U+00110000
++ utf8.clear();
++ utf8 += char(0xf4);
++ utf8 += char(0x90);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.5") << utf8 << str << -1;
++
++ // 3.1.1
++ utf8.clear();
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.1") << utf8 << str << -1;
++
++ // 3.1.2
++ utf8.clear();
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.2") << utf8 << str << -1;
++
++ // 3.1.3
++ utf8.clear();
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.3") << utf8 << str << -1;
++
++ // 3.1.4
++ utf8.clear();
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.4") << utf8 << str << -1;
++
++ // 3.1.5
++ utf8.clear();
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.5") << utf8 << str << -1;
++
++ // 3.1.6
++ utf8.clear();
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.6") << utf8 << str << -1;
++
++ // 3.1.7
++ utf8.clear();
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.7") << utf8 << str << -1;
++
++ // 3.1.8
++ utf8.clear();
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ utf8 += char(0xbf);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.8") << utf8 << str << -1;
++
++ // 3.1.9
++ utf8.clear();
++ for (uint i = 0x80; i<= 0xbf; ++i)
++ utf8 += i;
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.1.9") << utf8 << str << -1;
++
++ // 3.2.1
++ utf8.clear();
++ str.clear();
++ for (uint i = 0xc8; i <= 0xdf; ++i) {
++ utf8 += i;
++ utf8 += char(0x20);
++
++ str += QChar::ReplacementCharacter;
++ str += QChar(0x0020);
++ }
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.1") << utf8 << str << -1;
++
++ // 3.2.2
++ utf8.clear();
++ str.clear();
++ for (uint i = 0xe0; i <= 0xef; ++i) {
++ utf8 += i;
++ utf8 += char(0x20);
++
++ str += QChar::ReplacementCharacter;
++ str += QChar(0x0020);
++ }
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.2") << utf8 << str << -1;
++
++ // 3.2.3
++ utf8.clear();
++ str.clear();
++ for (uint i = 0xf0; i <= 0xf7; ++i) {
++ utf8 += i;
++ utf8 += 0x20;
++
++ str += QChar::ReplacementCharacter;
++ str += QChar(0x0020);
++ }
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.3") << utf8 << str << -1;
++
++ // 3.2.4
++ utf8.clear();
++ str.clear();
++ for (uint i = 0xf8; i <= 0xfb; ++i) {
++ utf8 += i;
++ utf8 += 0x20;
++
++ str += QChar::ReplacementCharacter;
++ str += QChar(0x0020);
++ }
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.4") << utf8 << str << -1;
++
++ // 3.2.5
++ utf8.clear();
++ str.clear();
++ for (uint i = 0xfc; i <= 0xfd; ++i) {
++ utf8 += i;
++ utf8 += 0x20;
++
++ str += QChar::ReplacementCharacter;
++ str += QChar(0x0020);
++ }
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.2.5") << utf8 << str << -1;
++
++ // 3.3.1
++ utf8.clear();
++ utf8 += char(0xc0);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.1") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.1-1") << utf8 << str << -1;
++
++ // 3.3.2
++ utf8.clear();
++ utf8 += char(0xe0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xe0);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-2") << utf8 << str << -1;
++ utf8 += 0x30;
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.2-3") << utf8 << str << -1;
++
++ // 3.3.3
++ utf8.clear();
++ utf8 += char(0xf0);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xf0);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-3") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xf0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-4") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.3-5") << utf8 << str << -1;
++
++ // 3.3.4
++ utf8.clear();
++ utf8 += char(0xf8);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xf8);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-3") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xf8);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-4") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-5") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xf8);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-6") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.4-7") << utf8 << str << -1;
++
++ // 3.3.5
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-3") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-4") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-5") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-6") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-7") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfc);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-8") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.5-9") << utf8 << str << -1;
++
++ // 3.3.6
++ utf8.clear();
++ utf8 += char(0xdf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.6") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.6-1") << utf8 << str << -1;
++
++ // 3.3.7
++ utf8.clear();
++ utf8 += char(0xef);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xef);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.7-3") << utf8 << str << -1;
++
++ // 3.3.8
++ utf8.clear();
++ utf8 += char(0xf7);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xf7);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-3") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xf7);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-4") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.8-5") << utf8 << str << -1;
++
++ // 3.3.9
++ utf8.clear();
++ utf8 += char(0xfb);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfb);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-3") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfb);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-4") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-5") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfb);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-6") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.9-7") << utf8 << str << -1;
++
++ // 3.3.10
++ utf8.clear();
++ utf8 += char(0xfd);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-1") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfd);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-2") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-3") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfd);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-4") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-5") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfd);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-6") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-7") << utf8 << str << -1;
++
++ utf8.clear();
++ utf8 += char(0xfd);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-8") << utf8 << str << -1;
++ utf8 += char(0x30);
++ str += QChar(0x30);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.3.10-9") << utf8 << str << -1;
++
++ // 3.4
++ utf8.clear();
++ utf8 += char(0xc0);
++ utf8 += char(0xe0);
++ utf8 += char(0x80);
++ utf8 += char(0xf0);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0xf8);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0xfc);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0xdf);
++ utf8 += char(0xef);
++ utf8 += char(0xbf);
++ utf8 += char(0xf7);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xfb);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xfd);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.4") << utf8 << str << -1;
++
++ // 3.5.1
++ utf8.clear();
++ utf8 += char(0xfe);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.1") << utf8 << str << -1;
++
++ // 3.5.2
++ utf8.clear();
++ utf8 += char(0xff);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2") << utf8 << str << -1;
++
++ // 3.5.2
++ utf8.clear();
++ utf8 += char(0xfe);
++ utf8 += char(0xfe);
++ utf8 += char(0xff);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 3.5.2-1") << utf8 << str << -1;
++
++ // 4.1.1
++ utf8.clear();
++ utf8 += char(0xc0);
++ utf8 += char(0xaf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.1") << utf8 << str << -1;
++
++ // 4.1.2
++ utf8.clear();
++ utf8 += char(0xe0);
++ utf8 += char(0x80);
++ utf8 += char(0xaf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.2") << utf8 << str << -1;
++
++ // 4.1.3
++ utf8.clear();
++ utf8 += char(0xf0);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0xaf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.3") << utf8 << str << -1;
++
++ // 4.1.4
++ utf8.clear();
++ utf8 += char(0xf8);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0xaf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.4") << utf8 << str << -1;
++
++ // 4.1.5
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0xaf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.5") << utf8 << str << -1;
++
++ // 4.2.1
++ utf8.clear();
++ utf8 += char(0xc1);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.1") << utf8 << str << -1;
++
++ // 4.2.2
++ utf8.clear();
++ utf8 += char(0xe0);
++ utf8 += char(0x9f);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.2") << utf8 << str << -1;
++
++ // 4.2.3
++ utf8.clear();
++ utf8 += char(0xf0);
++ utf8 += char(0x8f);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.3") << utf8 << str << -1;
++
++ // 4.2.4
++ utf8.clear();
++ utf8 += char(0xf8);
++ utf8 += char(0x87);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.4") << utf8 << str << -1;
++
++ // 4.2.5
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x83);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.5") << utf8 << str << -1;
++
++ // 4.3.1
++ utf8.clear();
++ utf8 += char(0xc0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.1") << utf8 << str << -1;
++
++ // 4.3.2
++ utf8.clear();
++ utf8 += char(0xe0);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.2") << utf8 << str << -1;
++
++ // 4.3.3
++ utf8.clear();
++ utf8 += char(0xf0);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.3") << utf8 << str << -1;
++
++ // 4.3.4
++ utf8.clear();
++ utf8 += char(0xf8);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.4") << utf8 << str << -1;
++
++ // 4.3.5
++ utf8.clear();
++ utf8 += char(0xfc);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.5") << utf8 << str << -1;
++
++ // 5.1.1
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xa0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.1") << utf8 << str << -1;
++
++ // 5.1.2
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xad);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.2") << utf8 << str << -1;
++
++ // 5.1.3
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xae);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.3") << utf8 << str << -1;
++
++ // 5.1.4
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xaf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.4") << utf8 << str << -1;
++
++ // 5.1.5
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xb0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.5") << utf8 << str << -1;
++
++ // 5.1.6
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xbe);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.6") << utf8 << str << -1;
++
++ // 5.1.7
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.7") << utf8 << str << -1;
++
++ // 5.2.1
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xa0);
++ utf8 += char(0x80);
++ utf8 += char(0xed);
++ utf8 += char(0xb0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.1") << utf8 << str << -1;
++
++ // 5.2.2
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xa0);
++ utf8 += char(0x80);
++ utf8 += char(0xed);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.2") << utf8 << str << -1;
++
++ // 5.2.3
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xad);
++ utf8 += char(0xbf);
++ utf8 += char(0xed);
++ utf8 += char(0xb0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.3") << utf8 << str << -1;
++
++ // 5.2.4
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xad);
++ utf8 += char(0xbf);
++ utf8 += char(0xed);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.4") << utf8 << str << -1;
++
++ // 5.2.5
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xae);
++ utf8 += char(0x80);
++ utf8 += char(0xed);
++ utf8 += char(0xb0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.5") << utf8 << str << -1;
++
++ // 5.2.6
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xae);
++ utf8 += char(0x80);
++ utf8 += char(0xed);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.6") << utf8 << str << -1;
++
++ // 5.2.7
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xaf);
++ utf8 += char(0xbf);
++ utf8 += char(0xed);
++ utf8 += char(0xb0);
++ utf8 += char(0x80);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.7") << utf8 << str << -1;
++
++ // 5.2.8
++ utf8.clear();
++ utf8 += char(0xed);
++ utf8 += char(0xaf);
++ utf8 += char(0xbf);
++ utf8 += char(0xed);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ str = fromInvalidUtf8Sequence(utf8);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.8") << utf8 << str << -1;
++
++ // 5.3.1 - non-character code
++ utf8.clear();
++ utf8 += char(0xef);
++ utf8 += char(0xbf);
++ utf8 += char(0xbe);
++ //str = QChar(QChar::ReplacementCharacter);
++ str = QChar(0xfffe);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.1") << utf8 << str << -1;
++
++ // 5.3.2 - non-character code
++ utf8.clear();
++ utf8 += char(0xef);
++ utf8 += char(0xbf);
++ utf8 += char(0xbf);
++ //str = QChar(QChar::ReplacementCharacter);
++ str = QChar(0xffff);
++ QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.2") << utf8 << str << -1;
++ }
++
++ void tst_QTextCodec::utf8Codec()
++ {
++ QTextCodec *codec = QTextCodec::codecForMib(106); // UTF-8
++ QVERIFY(codec != 0);
++
++ QFETCH(QByteArray, utf8);
++ QFETCH(QString, res);
++ QFETCH(int, len);
++
++ QString str = codec->toUnicode(utf8.isNull() ? 0 : utf8.constData(),
++ len < 0 ? int(qstrlen(utf8.constData())) : len);
++ QCOMPARE(str, res);
++
++ str = QString::fromUtf8(utf8.isNull() ? 0 : utf8.constData(), len);
++ QCOMPARE(str, res);
++ }
++
++ void tst_QTextCodec::utf8bom_data()
++ {
++ QTest::addColumn<QByteArray>("data");
++ QTest::addColumn<QString>("result");
++
++ QTest::newRow("nobom")
++ << QByteArray("\302\240", 2)
++ << QString::fromLatin1("\240");
++
++ {
++ static const char16_t data[] = { 0x201d };
++ QTest::newRow("nobom 2")
++ << QByteArray("\342\200\235", 3)
++ << QString::fromUtf16(data, std::size(data));
++ }
++
++ {
++ static const char16_t data[] = { 0xf000 };
++ QTest::newRow("bom1")
++ << QByteArray("\357\200\200", 3)
++ << QString::fromUtf16(data, std::size(data));
++ }
++
++ {
++ static const char16_t data[] = { 0xfec0 };
++ QTest::newRow("bom2")
++ << QByteArray("\357\273\200", 3)
++ << QString::fromUtf16(data, std::size(data));
++ }
++
++ {
++ QTest::newRow("normal-bom")
++ << QByteArray("\357\273\277a", 4)
++ << QString("a");
++ }
++
++ { // test the non-SIMD code-path
++ static const char16_t data[] = { 0x61, 0xfeff, 0x62 };
++ QTest::newRow("middle-bom (non SIMD)")
++ << QByteArray("a\357\273\277b")
++ << QString::fromUtf16(data, std::size(data));
++ }
++
++ { // test the SIMD code-path
++ static const char16_t data[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0xfeff, 0x6d };
++ QTest::newRow("middle-bom (SIMD)")
++ << QByteArray("abcdefghijkl\357\273\277m")
++ << QString::fromUtf16(data, std::size(data));
++ }
++ }
++
++ void tst_QTextCodec::utf8bom()
++ {
++ QFETCH(QByteArray, data);
++ QFETCH(QString, result);
++
++ QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
++ QVERIFY(codec);
++
++ QCOMPARE(codec->toUnicode(data.constData(), data.size(), 0), result);
++
++ QTextCodec::ConverterState state;
++ QCOMPARE(codec->toUnicode(data.constData(), data.size(), &state), result);
++ }
++
++ void tst_QTextCodec::utf8stateful_data()
++ {
++ QTest::addColumn<QByteArray>("buffer1");
++ QTest::addColumn<QByteArray>("buffer2");
++ QTest::addColumn<QString>("result"); // null QString indicates decoder error
++
++ // valid buffer continuations
++ QTest::newRow("1of2+valid") << QByteArray("\xc2") << QByteArray("\xa0") << "\xc2\xa0";
++ QTest::newRow("1of3+valid") << QByteArray("\xe0") << QByteArray("\xa0\x80") << "\xe0\xa0\x80";
++ QTest::newRow("2of3+valid") << QByteArray("\xe0\xa0") << QByteArray("\x80") << "\xe0\xa0\x80";
++ QTest::newRow("1of4+valid") << QByteArray("\360") << QByteArray("\220\210\203") << "\360\220\210\203";
++ QTest::newRow("2of4+valid") << QByteArray("\360\220") << QByteArray("\210\203") << "\360\220\210\203";
++ QTest::newRow("3of4+valid") << QByteArray("\360\220\210") << QByteArray("\203") << "\360\220\210\203";
++ QTest::newRow("1ofBom+valid") << QByteArray("\xef") << QByteArray("\xbb\xbf") << "";
++ QTest::newRow("2ofBom+valid") << QByteArray("\xef\xbb") << QByteArray("\xbf") << "";
++
++ // invalid continuation
++ QTest::newRow("1of2+invalid") << QByteArray("\xc2") << QByteArray("a") << QString();
++ QTest::newRow("1of3+invalid") << QByteArray("\xe0") << QByteArray("a") << QString();
++ QTest::newRow("2of3+invalid") << QByteArray("\xe0\xa0") << QByteArray("a") << QString();
++ QTest::newRow("1of4+invalid") << QByteArray("\360") << QByteArray("a") << QString();
++ QTest::newRow("2of4+invalid") << QByteArray("\360\220") << QByteArray("a") << QString();
++ QTest::newRow("3of4+invalid") << QByteArray("\360\220\210") << QByteArray("a") << QString();
++
++ // overlong sequence:
++ QTest::newRow("overlong-1of2") << QByteArray("\xc1") << QByteArray("\x81") << QString();
++ QTest::newRow("overlong-1of3") << QByteArray("\xe0") << QByteArray("\x81\x81") << QString();
++ QTest::newRow("overlong-2of3") << QByteArray("\xe0\x81") << QByteArray("\x81") << QString();
++ QTest::newRow("overlong-1of4") << QByteArray("\xf0") << QByteArray("\x80\x81\x81") << QString();
++ QTest::newRow("overlong-2of4") << QByteArray("\xf0\x80") << QByteArray("\x81\x81") << QString();
++ QTest::newRow("overlong-3of4") << QByteArray("\xf0\x80\x81") << QByteArray("\x81") << QString();
++
++ // out of range:
++ // leading byte 0xF4 can produce codepoints above U+10FFFF, which aren't valid
++ QTest::newRow("outofrange1-1of4") << QByteArray("\xf4") << QByteArray("\x90\x80\x80") << QString();
++ QTest::newRow("outofrange1-2of4") << QByteArray("\xf4\x90") << QByteArray("\x80\x80") << QString();
++ QTest::newRow("outofrange1-3of4") << QByteArray("\xf4\x90\x80") << QByteArray("\x80") << QString();
++ QTest::newRow("outofrange2-1of4") << QByteArray("\xf5") << QByteArray("\x90\x80\x80") << QString();
++ QTest::newRow("outofrange2-2of4") << QByteArray("\xf5\x90") << QByteArray("\x80\x80") << QString();
++ QTest::newRow("outofrange2-3of4") << QByteArray("\xf5\x90\x80") << QByteArray("\x80") << QString();
++ QTest::newRow("outofrange-1of5") << QByteArray("\xf8") << QByteArray("\x88\x80\x80\x80") << QString();
++ QTest::newRow("outofrange-2of5") << QByteArray("\xf8\x88") << QByteArray("\x80\x80\x80") << QString();
++ QTest::newRow("outofrange-3of5") << QByteArray("\xf8\x88\x80") << QByteArray("\x80\x80") << QString();
++ QTest::newRow("outofrange-4of5") << QByteArray("\xf8\x88\x80\x80") << QByteArray("\x80") << QString();
++ QTest::newRow("outofrange-1of6") << QByteArray("\xfc") << QByteArray("\x84\x80\x80\x80\x80") << QString();
++ QTest::newRow("outofrange-2of6") << QByteArray("\xfc\x84") << QByteArray("\x80\x80\x80\x80") << QString();
++ QTest::newRow("outofrange-3of6") << QByteArray("\xfc\x84\x80") << QByteArray("\x80\x80\x80") << QString();
++ QTest::newRow("outofrange-4of6") << QByteArray("\xfc\x84\x80\x80") << QByteArray("\x80\x80") << QString();
++ QTest::newRow("outofrange-5of6") << QByteArray("\xfc\x84\x80\x80\x80") << QByteArray("\x80") << QString();
++ }
++
++ void tst_QTextCodec::utf8stateful()
++ {
++ QFETCH(const QByteArray, buffer1);
++ QFETCH(const QByteArray, buffer2);
++ QFETCH(QString, result);
++
++ QTextCodec *utf8codec = QTextCodec::codecForName("utf-8");
++ QVERIFY(utf8codec);
++
++ QTextCodec::ConverterState state;
++
++ QString decoded1 = utf8codec->toUnicode(buffer1.data(), buffer1.size(), &state);
++ if (result.isNull()) {
++ // the decoder may have found an early error (invalidChars > 0):
++ // if it has, remainingChars == 0;
++ // if it hasn't, then it must have a state
++ QVERIFY2((state.remainingChars == 0) != (state.invalidChars == 0),
++ ("remainingChars = " + QByteArray::number(state.remainingChars) +
++ "; invalidChars = " + QByteArray::number(state.invalidChars)).constData());
++ } else {
++ QVERIFY(state.remainingChars > 0);
++ QCOMPARE(state.invalidChars, 0);
++ }
++
++ QString decoded2 = utf8codec->toUnicode(buffer2.data(), buffer2.size(), &state);
++ QCOMPARE(state.remainingChars, 0);
++ if (result.isNull()) {
++ QVERIFY(state.invalidChars > 0);
++ } else {
++ QCOMPARE(decoded1 + decoded2, result);
++ }
++ }
++
++ void tst_QTextCodec::utfHeaders_data()
++ {
++ QTest::addColumn<QByteArray>("codecName");
++ QTest::addColumn<int>("flags");
++ QTest::addColumn<QByteArray>("encoded");
++ QTest::addColumn<QString>("unicode");
++ QTest::addColumn<bool>("toUnicode");
++
++ QTest::newRow("utf8 bom")
++ << QByteArray("UTF-8")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\xef\xbb\xbfhello")
++ << QString::fromLatin1("hello")
++ << true;
++ QTest::newRow("utf8 nobom")
++ << QByteArray("UTF-8")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("hello")
++ << QString::fromLatin1("hello")
++ << true;
++ QTest::newRow("utf8 bom ignore header")
++ << QByteArray("UTF-8")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\xef\xbb\xbfhello")
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hello"))
++ << true;
++ QTest::newRow("utf8 nobom ignore header")
++ << QByteArray("UTF-8")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("hello")
++ << QString::fromLatin1("hello")
++ << true;
++
++ QTest::newRow("utf16 bom be")
++ << QByteArray("UTF-16")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\xfe\xff\0h\0e\0l", 8)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf16 bom le")
++ << QByteArray("UTF-16")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\xff\xfeh\0e\0l\0", 8)
++ << QString::fromLatin1("hel")
++ << true;
++ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
++ QTest::newRow("utf16 nobom")
++ << QByteArray("UTF-16")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\0h\0e\0l", 6)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf16 bom be ignore header")
++ << QByteArray("UTF-16")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\xfe\xff\0h\0e\0l", 8)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++ } else {
++ QTest::newRow("utf16 nobom")
++ << QByteArray("UTF-16")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("h\0e\0l\0", 6)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf16 bom le ignore header")
++ << QByteArray("UTF-16")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\xff\xfeh\0e\0l\0", 8)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++ }
++
++ QTest::newRow("utf16-be bom be")
++ << QByteArray("UTF-16BE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\xfe\xff\0h\0e\0l", 8)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf16-be nobom")
++ << QByteArray("UTF-16BE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\0h\0e\0l", 6)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf16-be bom be ignore header")
++ << QByteArray("UTF-16BE")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\xfe\xff\0h\0e\0l", 8)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++
++ QTest::newRow("utf16-le bom le")
++ << QByteArray("UTF-16LE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\xff\xfeh\0e\0l\0", 8)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf16-le nobom")
++ << QByteArray("UTF-16LE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("h\0e\0l\0", 6)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf16-le bom le ignore header")
++ << QByteArray("UTF-16LE")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\xff\xfeh\0e\0l\0", 8)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++
++
++ QTest::newRow("utf32 bom be")
++ << QByteArray("UTF-32")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf32 bom le")
++ << QByteArray("UTF-32")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
++ << QString::fromLatin1("hel")
++ << true;
++ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
++ QTest::newRow("utf32 nobom")
++ << QByteArray("UTF-32")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf32 bom be ignore header")
++ << QByteArray("UTF-32")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++ } else {
++ QTest::newRow("utf32 nobom")
++ << QByteArray("UTF-32")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("h\0\0\0e\0\0\0l\0\0\0", 12)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf32 bom le ignore header")
++ << QByteArray("UTF-32")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++ }
++
++
++ QTest::newRow("utf32-be bom be")
++ << QByteArray("UTF-32BE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf32-be nobom")
++ << QByteArray("UTF-32BE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf32-be bom be ignore header")
++ << QByteArray("UTF-32BE")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++
++
++ QTest::newRow("utf32-le bom le")
++ << QByteArray("UTF-32LE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf32-le nobom")
++ << QByteArray("UTF-32LE")
++ << (int)QTextCodec::DefaultConversion
++ << QByteArray("h\0\0\0e\0\0\0l\0\0\0", 12)
++ << QString::fromLatin1("hel")
++ << true;
++ QTest::newRow("utf32-le bom le ignore header")
++ << QByteArray("UTF-32LE")
++ << (int)QTextCodec::IgnoreHeader
++ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
++ << (QString(QChar(0xfeff)) + QString::fromLatin1("hel"))
++ << true;
++ }
++
++ void tst_QTextCodec::utfHeaders()
++ {
++ QFETCH(QByteArray, codecName);
++ QTextCodec *codec = QTextCodec::codecForName(codecName);
++ QVERIFY(codec != 0);
++
++ QFETCH(int, flags);
++ QTextCodec::ConversionFlags cFlags = QTextCodec::ConversionFlags(flags);
++ QTextCodec::ConverterState state(cFlags);
++
++ QFETCH(QByteArray, encoded);
++ QFETCH(QString, unicode);
++
++ QFETCH(bool, toUnicode);
++
++ QLatin1String ignoreReverseTestOn = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? QLatin1String(" le") : QLatin1String(" be");
++ QString rowName(QTest::currentDataTag());
++
++ if (toUnicode) {
++ QString result = codec->toUnicode(encoded.constData(), encoded.size(), &state);
++ QCOMPARE(result.size(), unicode.size());
++ QCOMPARE(result, unicode);
++
++ if (!rowName.endsWith("nobom") && !rowName.contains(ignoreReverseTestOn)) {
++ QTextCodec::ConverterState state2(cFlags);
++ QByteArray reencoded = codec->fromUnicode(unicode.unicode(), unicode.size(), &state2);
++ QCOMPARE(reencoded, encoded);
++ }
++ } else {
++ QByteArray result = codec->fromUnicode(unicode.unicode(), unicode.size(), &state);
++ QCOMPARE(result, encoded);
++ }
++ }
++
++ void tst_QTextCodec::codecForHtml_data()
++ {
++ QTest::addColumn<QByteArray>("html");
++ QTest::addColumn<int>("defaultCodecMib");
++ QTest::addColumn<int>("expectedMibEnum");
++
++ int noDefault = -1;
++ int fallback = 4; // latin 1
++ QByteArray html = "<html><head></head><body>blah</body></html>";
++ QTest::newRow("no charset, latin 1") << html << noDefault << fallback;
++
++ QTest::newRow("no charset, default UTF-8") << html << 106 << 106;
++
++ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-15\" /></head></html>";
++ QTest::newRow("latin 15, default UTF-8") << html << 106 << 111;
++
++ html = "<html><head><meta content=\"text/html; charset=ISO-8859-15\" http-equiv=\"content-type\" /></head></html>";
++ QTest::newRow("latin 15, default UTF-8 (#2)") << html << 106 << 111;
++
++ html = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><title>Test</title></head>";
++ QTest::newRow("UTF-8, no default") << html << noDefault << 106;
++
++ html = "<!DOCTYPE html><html><head><meta charset=\"ISO_8859-1:1987\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><title>Test</title></head>";
++ QTest::newRow("latin 1, no default") << html << noDefault << 4;
++
++ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"utf-8\"><title>Test</title></head>";
++ QTest::newRow("UTF-8, no default (#2)") << html << noDefault << 106;
++
++ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8/></head></html>";
++ QTest::newRow("UTF-8, no quotes") << html << noDefault << 106;
++
++ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset='UTF-8'/></head></html>";
++ QTest::newRow("UTF-8, single quotes") << html << noDefault << 106;
++
++ html = "<!DOCTYPE html><html><head><meta charset=utf-8><title>Test</title></head>";
++ QTest::newRow("UTF-8, > terminator") << html << noDefault << 106;
++
++ html = "<!DOCTYPE html><html><head><meta charset= utf-8 ><title>Test</title></head>";
++ QTest::newRow("UTF-8, > terminator with spaces") << html << noDefault << 106;
++
++ html = "<!DOCTYPE html><html><head><meta charset= utf/8 ><title>Test</title></head>";
++ QTest::newRow("UTF-8, > teminator with early backslash)") << html << noDefault << 106;
++
++ // Test invalid charsets.
++ html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=invalid-foo\" /></head></html>";
++ QTest::newRow("invalid charset, no default") << html << noDefault << fallback;
++ QTest::newRow("invalid charset, default UTF-8") << html << 106 << 106;
++
++ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"";
++ html.prepend(QByteArray().fill(' ', 512 - html.size()));
++ QTest::newRow("invalid charset (large header)") << html << noDefault << fallback;
++
++ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset=\"utf-8";
++ QTest::newRow("invalid charset (no closing double quote)") << html << noDefault << fallback;
++
++ html = "<!DOCTYPE html><html><head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=9,chrome=1\"><meta charset='utf-8";
++ QTest::newRow("invalid charset (no closing single quote)") << html << noDefault << fallback;
++
++ html = "<!DOCTYPE html><html><head><meta charset=utf-8 foo=bar><title>Test</title></head>";
++ QTest::newRow("invalid (space terminator)") << html << noDefault << fallback;
++
++ html = "<!DOCTYPE html><html><head><meta charset=\" utf' 8 /><title>Test</title></head>";
++ QTest::newRow("invalid charset, early terminator (')") << html << noDefault << fallback;
++
++ const char src[] = { char(0xff), char(0xfe), char(0x7a), char(0x03), 0, 0 };
++ html = src;
++ QTest::newRow("greek text UTF-16LE") << html << 106 << 1014;
++
++ html = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><span style=\"color: rgb(0, 0, 0); font-family: "
++ "'Galatia SIL'; font-size: 27px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; "
++ "line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: "
++ "auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: "
++ "none;\">ͻ</span>\000";
++ QTest::newRow("greek text UTF-8") << html << 106 << 106;
++
++ html = "<!DOCTYPE html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=unicode\">"
++ "<head/><body><p>bla</p></body></html>"; // QTBUG-41998, ICU will return UTF-16.
++ QTest::newRow("legacy unicode UTF-8") << html << 106 << 106;
++ }
++
++ void tst_QTextCodec::codecForHtml()
++ {
++ QFETCH(QByteArray, html);
++ QFETCH(int, defaultCodecMib);
++ QFETCH(int, expectedMibEnum);
++
++ if (defaultCodecMib != -1)
++ QCOMPARE(QTextCodec::codecForHtml(html, QTextCodec::codecForMib(defaultCodecMib))->mibEnum(), expectedMibEnum);
++ else // Test one parameter version when there is no default codec.
++ QCOMPARE(QTextCodec::codecForHtml(html)->mibEnum(), expectedMibEnum);
++ }
++
++ void tst_QTextCodec::codecForUtfText_data()
++ {
++ QTest::addColumn<QByteArray>("encoded");
++ QTest::addColumn<bool>("detected");
++ QTest::addColumn<int>("mib");
++
++
++ QTest::newRow("utf8 bom")
++ << QByteArray("\xef\xbb\xbfhello")
++ << true
++ << 106;
++ QTest::newRow("utf8 nobom")
++ << QByteArray("hello")
++ << false
++ << 0;
++
++ QTest::newRow("utf16 bom be")
++ << QByteArray("\xfe\xff\0h\0e\0l", 8)
++ << true
++ << 1013;
++ QTest::newRow("utf16 bom le")
++ << QByteArray("\xff\xfeh\0e\0l\0", 8)
++ << true
++ << 1014;
++ QTest::newRow("utf16 nobom")
++ << QByteArray("\0h\0e\0l", 6)
++ << false
++ << 0;
++
++ QTest::newRow("utf32 bom be")
++ << QByteArray("\0\0\xfe\xff\0\0\0h\0\0\0e\0\0\0l", 16)
++ << true
++ << 1018;
++ QTest::newRow("utf32 bom le")
++ << QByteArray("\xff\xfe\0\0h\0\0\0e\0\0\0l\0\0\0", 16)
++ << true
++ << 1019;
++ QTest::newRow("utf32 nobom")
++ << QByteArray("\0\0\0h\0\0\0e\0\0\0l", 12)
++ << false
++ << 0;
++ }
++
++ void tst_QTextCodec::codecForUtfText()
++ {
++ QFETCH(QByteArray, encoded);
++ QFETCH(bool, detected);
++ QFETCH(int, mib);
++
++ QTextCodec *codec = QTextCodec::codecForUtfText(encoded, 0);
++ if (detected)
++ QCOMPARE(codec->mibEnum(), mib);
++ else
++ QVERIFY(!codec);
++ }
++
++ #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
++ void tst_QTextCodec::toLocal8Bit()
++ {
++ #if !QT_CONFIG(process)
++ QSKIP("No qprocess support");
++ #else
++ QProcess process;
++ process.start(QFINDTESTDATA("echo_helper"));
++ QString string(QChar(0x410));
++ process.write((const char*)string.utf16(), string.size()*2);
++
++ process.closeWriteChannel();
++ process.waitForFinished();
++ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
++ QCOMPARE(process.exitCode(), 0);
++ #endif
++ }
++ #endif // defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID)
++
++ class LoadAndConvert: public QRunnable
++ {
++ public:
++ LoadAndConvert(const QByteArray &source, QByteArray *destination)
++ : codecName(source), target(destination)
++ {}
++ QByteArray codecName;
++ QByteArray *target;
++ void run() override
++ {
++ QTextCodec *c = QTextCodec::codecForName(codecName);
++ if (!c) {
++ qWarning() << "WARNING" << codecName << "not found?";
++ return;
++ }
++ QString str = QString::fromLatin1(codecName);
++ QByteArray b = c->fromUnicode(str);
++ c->toUnicode(b);
++ *target = codecName;
++ }
++ };
++
++ class LoadAndConvertMIB: public QRunnable
++ {
++ public:
++ LoadAndConvertMIB(int mib, int *target)
++ : mib(mib), target(target)
++ {}
++ int mib;
++ int *target;
++ void run() override
++ {
++ QTextCodec *c = QTextCodec::codecForMib(mib);
++ if (!c) {
++ qWarning() << "WARNING" << mib << "not found?";
++ return;
++ }
++ QString str = QString::number(mib);
++ QByteArray b = c->fromUnicode(str);
++ c->toUnicode(b);
++ *target = mib;
++ }
++ };
++
++
++ void tst_QTextCodec::threadSafety()
++ {
++ QList<QByteArray> codecList = QTextCodec::availableCodecs();
++ const QList<int> mibList = QTextCodec::availableMibs().toVector();
++ QThreadPool::globalInstance()->setMaxThreadCount(12);
++
++ QList<QByteArray> res;
++ res.resize(codecList.size());
++ for (int i = 0; i < codecList.size(); ++i) {
++ QThreadPool::globalInstance()->start(new LoadAndConvert(codecList.at(i), &res[i]));
++ }
++
++ QList<int> res2;
++ res2.resize(mibList.size());
++ for (int i = 0; i < mibList.size(); ++i) {
++ QThreadPool::globalInstance()->start(new LoadAndConvertMIB(mibList.at(i), &res2[i]));
++ }
++
++ // wait for all threads to finish working
++ QThreadPool::globalInstance()->waitForDone();
++
++ QCOMPARE(res.toList(), codecList);
++ QCOMPARE(res2, mibList);
++ }
++
++ void tst_QTextCodec::invalidNames()
++ {
++ QVERIFY(!QTextCodec::codecForName(""));
++ QVERIFY(!QTextCodec::codecForName(QByteArray()));
++ QVERIFY(!QTextCodec::codecForName("-"));
++ QVERIFY(!QTextCodec::codecForName("\1a\2b\3a\4d\5c\6s\7a\xffr\xec_\x9c_"));
++ QVERIFY(!QTextCodec::codecForName("\n"));
++ QVERIFY(!QTextCodec::codecForName("don't exist"));
++ QByteArray huge = "azertyuiop^$qsdfghjklm<wxcvbn,;:=1234567890�_";
++ huge = huge + huge + huge + huge + huge + huge + huge + huge;
++ huge = huge + huge + huge + huge + huge + huge + huge + huge;
++ huge = huge + huge + huge + huge + huge + huge + huge + huge;
++ huge = huge + huge + huge + huge + huge + huge + huge + huge;
++ QVERIFY(!QTextCodec::codecForName(huge));
++ // check we don't read past the end of a non-null-terminated QBA:
++ {
++ constexpr char ISO_8859_15[] = "ISO-8859-15";
++ const QByteArray ISO_8859_1 = QByteArray::fromRawData(ISO_8859_15, sizeof ISO_8859_15 - 2);
++ const auto codec = QTextCodec::codecForName(ISO_8859_1);
++ QVERIFY(codec);
++ QCOMPARE(codec->name(), "ISO-8859-1");
++ }
++ }
++
++ void tst_QTextCodec::checkAliases_data()
++ {
++ QTest::addColumn<QByteArray>("codecName");
++ const QList<QByteArray> codecList = QTextCodec::availableCodecs();
++ for (const QByteArray &a : codecList)
++ QTest::newRow( a.constData() ) << a;
++ }
++
++ void tst_QTextCodec::checkAliases()
++ {
++ QFETCH( QByteArray, codecName );
++ QTextCodec *c = QTextCodec::codecForName(codecName);
++ QVERIFY(c);
++ QCOMPARE(QTextCodec::codecForName(codecName), c);
++ QCOMPARE(QTextCodec::codecForName(c->name()), c);
++
++ const auto aliases = c->aliases();
++ for (const QByteArray &a : aliases) {
++ QCOMPARE(QTextCodec::codecForName(a), c);
++ }
++ }
++
++
++ void tst_QTextCodec::moreToFromUnicode_data() {
++ QTest::addColumn<QByteArray>("codecName");
++ QTest::addColumn<QByteArray>("testData");
++
++ QTest::newRow("russian") << QByteArray("ISO-8859-5")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF\x00");
++
++ QTest::newRow("arabic") << QByteArray("ISO-8859-6")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA4\xAC\xAD\xBB\xBF\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2");
++
++ QTest::newRow("greek") << QByteArray("ISO-8859-7")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA6\xA7\xA8\xA9\xAB\xAC\xAD\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE");
++
++ QTest::newRow("turkish") << QByteArray("ISO-8859-9")
++ << QByteArray("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("latin1") << QByteArray("ISO-8859-1")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QByteArray sms7bit_ba;
++ for (int i=1; i <= 0x7f; ++i) {
++ if (i!='\x1b') {
++ sms7bit_ba.append(i);
++ }
++ }
++
++ QTest::newRow("latin2") << QByteArray("ISO-8859-2")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("latin3") << QByteArray("ISO-8859-3")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBF\xC0\xC1\xC2\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("latin4") << QByteArray("ISO-8859-4")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("russian 2") << QByteArray("ISO-8859-5")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("arabic 2") << QByteArray("ISO-8859-6")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA4\xAC\xAD\xBB\xBF\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2");
++
++ QTest::newRow("greek 2") << QByteArray("ISO-8859-7")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA6\xA7\xA8\xA9\xAB\xAC\xAD\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE");
++
++ QTest::newRow("latin5") << QByteArray("ISO-8859-9")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("latin6") << QByteArray("ISO-8859-10")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ #if 0
++ QByteArray iso8859_11_ba;
++ for (int x=0x20; x<=0x7f; ++x) {
++ iso8859_11_ba.append(x);
++ }
++ for (int x=0xa0; x<0xff; ++x) {
++ if ((x>=0xdb && x<0xdf) || x>0xfb){
++ continue;
++ }
++ iso8859_11_ba.append(x);
++ }
++ QTest::newRow("latin-thai") << QByteArray("ISO-8859-11") << iso8859_11_ba;
++ #endif
++
++ QTest::newRow("latin7") << QByteArray("ISO-8859-13")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("celtic") << QByteArray("ISO-8859-14")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("latin9") << QByteArray("ISO-8859-15")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ // QTest::newRow("latin10") << QByteArray("ISO-8859-16")
++ // << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("cp850") << QByteArray("CP850")
++ << QByteArray("\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff");
++
++ QTest::newRow("cp874") << QByteArray("CP874")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x85\x91\x92\x93\x94\x95\x96\x97\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB");
++
++ QTest::newRow("cp1250") << QByteArray("CP1250")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x84\x85\x86\x87\x89\x8A\x8B\x8C\x8D\x8E\x8F\x91\x92\x93\x94\x95\x96\x97\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("cp1251") << QByteArray("CP1251")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("cp1252") << QByteArray("CP1252")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8E\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("cp1253") << QByteArray("CP1253")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x89\x8B\x91\x92\x93\x94\x95\x96\x97\x99\x9B\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE");
++
++ QTest::newRow("cp1254") << QByteArray("CP1254")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("cp1255") << QByteArray("CP1255")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89,x8B\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9B\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFD\xFE");
++
++ QTest::newRow("cp1256") << QByteArray("CP1256")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("cp1257") << QByteArray("CP1257")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x84\x85\x86\x87\x89\x8B\x8D\x8E\x8F\x91\x92\x93\x94\x95\x96\x97\x99\x9B\x9D\x9E\xA0\xA2\xA3\xA4\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QTest::newRow("cp1258") << QByteArray("CP1258")
++ << QByteArray("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8B\x8C\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9B\x9C\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
++
++ QByteArray koi8_r_ba;
++ for (int x=0x20; x<=0xff; ++x) {
++ if (x!=0x9A && x!=0xbf) {
++ koi8_r_ba.append(x);
++ }
++ }
++ QTest::newRow("KOI8-R") << QByteArray("KOI8-R") << koi8_r_ba;
++
++ QByteArray koi8_u_ba;
++ for (int x=0x20; x<=0xff; ++x) {
++ koi8_u_ba.append(x);
++ }
++ QTest::newRow("KOI8-U") << QByteArray("KOI8-U") << koi8_u_ba;
++
++
++ QByteArray big5_ba;
++ for (unsigned char u=0xa1; u<=0xf9; u++) {
++ if (u==0xc8) {
++ continue;
++ }
++ for (unsigned char v=0x40; v<=0x7e; v++) {
++ big5_ba.append(u);
++ big5_ba.append(v);
++ }
++ unsigned char v_up;
++ switch (u) {
++ case 0xa2: v_up=0xa1; break;
++ case 0xa3: v_up=0xbf; break;
++ case 0xc7: v_up=0xfc; break;
++ case 0xf9: v_up=0xd5; break;
++ default: v_up=0xfe;
++ }
++
++ for (unsigned char v=0xa1; v<=v_up; v++) {
++ if (u==0xa2 && (v==0xcc || v==0xce)) {
++ continue;
++ }
++ big5_ba.append(u);
++ big5_ba.append(v);
++ }
++ }
++
++ QTest::newRow("BIG5") << QByteArray("BIG5") << big5_ba;
++
++ QByteArray gb2312_ba;
++ for (unsigned char u=0xa1; u<=0xf7; u++) {
++ for (unsigned char v=0xa1; v<=0xfe; v++) {
++ gb2312_ba.append(u);
++ gb2312_ba.append(v);
++ }
++ }
++
++ QTest::newRow("GB2312") << QByteArray("GB2312") << gb2312_ba;
++ }
++
++ void tst_QTextCodec::moreToFromUnicode()
++ {
++ QFETCH( QByteArray, codecName );
++ QFETCH( QByteArray, testData );
++
++ QTextCodec *c = QTextCodec::codecForName( codecName.data() );
++ QVERIFY(c);
++
++ QString uStr = c->toUnicode(testData);
++ QByteArray cStr = c->fromUnicode(uStr);
++ QCOMPARE(testData, cStr);
++ }
++
++ void tst_QTextCodec::shiftJis()
++ {
++ QByteArray backslashTilde("\\~");
++ QTextCodec* codec = QTextCodec::codecForName("shift_jis");
++ QString string = codec->toUnicode(backslashTilde);
++ QCOMPARE(string.size(), 2);
++ QCOMPARE(string.at(0), QChar(QLatin1Char('\\')));
++ QCOMPARE(string.at(1), QChar(QLatin1Char('~')));
++
++ QByteArray encoded = codec->fromUnicode(string);
++ QCOMPARE(encoded, backslashTilde);
++ }
++
++ struct UserCodec : public QTextCodec
++ {
++ // implement pure virtuals
++ QByteArray name() const override
++ { return "UserCodec"; }
++ QList<QByteArray> aliases() const override
++ { return QList<QByteArray>() << "usercodec" << "user-codec"; }
++ int mibEnum() const override
++ { return 5000; }
++
++ virtual QString convertToUnicode(const char *, int, ConverterState *) const override
++ { return QString(); }
++ virtual QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override
++ { return QByteArray(); }
++ };
++
++ void tst_QTextCodec::userCodec()
++ {
++ // check that it isn't there
++ static bool executedOnce = false;
++ if (executedOnce)
++ QSKIP("Test already executed once");
++
++ QVERIFY(!QTextCodec::availableCodecs().contains("UserCodec"));
++ QVERIFY(!QTextCodec::codecForName("UserCodec"));
++
++ UserCodec *codec = new UserCodec;
++ executedOnce = true;
++
++ QList<QByteArray> availableCodecs = QTextCodec::availableCodecs();
++ QVERIFY(availableCodecs.contains("UserCodec"));
++ QVERIFY(availableCodecs.contains("usercodec"));
++ QVERIFY(availableCodecs.contains("user-codec"));
++
++ QTextCodec *pcodec = QTextCodec::codecForName("UserCodec");
++ QCOMPARE(pcodec, codec);
++
++ pcodec = QTextCodec::codecForName("user-codec");
++ QCOMPARE(pcodec, codec);
++
++ pcodec = QTextCodec::codecForName("User-Codec");
++ QCOMPARE(pcodec, codec);
++
++ pcodec = QTextCodec::codecForMib(5000);
++ QCOMPARE(pcodec, codec);
++
++ delete codec;
++
++ pcodec = QTextCodec::codecForName("UserCodec");
++ QCOMPARE(pcodec, nullptr);
++ }
++
++ struct DontCrashAtExit {
++ ~DontCrashAtExit() {
++ QTextCodec *c = QTextCodec::codecForName("utf8");
++ if (c)
++ c->toUnicode("azerty");
++
++ }
++ } dontCrashAtExit;
++
++ void tst_QTextCodec::nullInputZeroOrNegativeLength_data()
++ {
++ QTest::addColumn<QString>("codecName");
++ QTest::addColumn<int>("mibEnum");
++
++ QTest::newRow("Big5") << "Big5" << 2026;
++ QTest::newRow("Big5-HKSCS") << "Big5-HKSCS" << 2101;
++ QTest::newRow("EUC-JP") << "EUC-JP" << 18;
++ QTest::newRow("iscii-dev") << "iscii-dev" << -3000;
++ QTest::newRow("iscii-bng") << "iscii-bng" << -3001;
++ QTest::newRow("iscii-pnj") << "iscii-pnj" << -3002;
++ QTest::newRow("iscii-gjr") << "iscii-gjr" << -3003;
++ QTest::newRow("iscii-ori") << "iscii-ori" << -3004;
++ QTest::newRow("iscii-tml") << "iscii-tml" << -3005;
++ QTest::newRow("iscii-tlg") << "iscii-tlg" << -3006;
++ QTest::newRow("iscii-knd") << "iscii-knd" << -3007;
++ QTest::newRow("iscii-mlm") << "iscii-mlm" << -3008;
++ QTest::newRow("ISO-2022-JP") << "ISO-2022-JP" << 39;
++ QTest::newRow("ISO-8859-1") << "ISO-8859-1" << 4;
++ QTest::newRow("ISO-8859-15") << "ISO-8859-15" << 111;
++ QTest::newRow("KOI8-R") << "KOI8-R" << 2084;
++ QTest::newRow("KOI8-U") << "KOI8-U" << 2088;
++ QTest::newRow("ISO-8859-1") << "ISO-8859-1" << 4;
++ QTest::newRow("ISO-8859-2") << "ISO-8859-2" << 5;
++ QTest::newRow("ISO-8859-3") << "ISO-8859-3" << 6;
++ QTest::newRow("ISO-8859-4") << "ISO-8859-4" << 7;
++ QTest::newRow("ISO-8859-5") << "ISO-8859-5" << 8;
++ QTest::newRow("ISO-8859-9") << "ISO-8859-9" << 12;
++ QTest::newRow("ISO-8859-10") << "ISO-8859-10" << 13;
++ QTest::newRow("ISO-8859-13") << "ISO-8859-13" << 109;
++ QTest::newRow("ISO-8859-14") << "ISO-8859-14" << 110;
++ QTest::newRow("ISO-8859-16") << "ISO-8859-16" << 112;
++ QTest::newRow("IBM850") << "IBM850" << 2009;
++ QTest::newRow("IBM866") << "IBM866" << 2086;
++ QTest::newRow("windows-1250") << "windows-1250" << 2250;
++ QTest::newRow("windows-1251") << "windows-1251" << 2251;
++ QTest::newRow("windows-1252") << "windows-1252" << 2252;
++ QTest::newRow("windows-1253") << "windows-1253" << 2253;
++ QTest::newRow("windows-1254") << "windows-1254" << 2254;
++ QTest::newRow("windows-1255") << "windows-1255" << 2255;
++ QTest::newRow("windows-1256") << "windows-1256" << 2256;
++ QTest::newRow("windows-1257") << "windows-1257" << 2257;
++ QTest::newRow("windows-1258") << "windows-1258" << 2258;
++ QTest::newRow("macintosh") << "macintosh" << 2027;
++ QTest::newRow("TIS-620") << "TIS-620" << 2259;
++ QTest::newRow("hp-roman8") << "hp-roman8" << 2004;
++ QTest::newRow("Shift_JIS") << "Shift_JIS" << 17;
++ QTest::newRow("TSCII") << "TSCII" << 2107;
++ QTest::newRow("UTF-8") << "UTF-8" << 106;
++ QTest::newRow("UTF-16") << "UTF-16" << 1015;
++ QTest::newRow("UTF-16BE") << "UTF-16BE" << 1013;
++ QTest::newRow("UTF-16LE") << "UTF-16LE" << 1014;
++ QTest::newRow("UTF-32") << "UTF-32" << 1017;
++ QTest::newRow("UTF-32BE") << "UTF-32BE" << 1018;
++ QTest::newRow("UTF-32LE") << "UTF-32LE" << 1019;
++ #ifdef Q_OS_WIN
++ QTest::newRow("EUC-KR") << "EUC-KR" << 38;
++ QTest::newRow("windows-949") << "windows-949" << -949;
++ QTest::newRow("GBK") << "GBK" << 113;
++ QTest::newRow("GB2312") << "GB2312" << 2025;
++ QTest::newRow("ISO-8859-6") << "ISO-8859-6" << 82;
++ QTest::newRow("ISO-8859-7") << "ISO-8859-7" << 10;
++ QTest::newRow("ISO-8859-8") << "ISO-8859-8" << 85;
++ QTest::newRow("IBM874") << "IBM874" << -874;
++ QTest::newRow("WINSAMI2") << "WINSAMI2" << -165;
++ QTest::newRow("System") << "System" << 0;
++ #endif
++ }
++
++ void tst_QTextCodec::nullInputZeroOrNegativeLength()
++ {
++ QFETCH(QString, codecName);
++ QFETCH(int, mibEnum);
++
++ QTextCodec* codec = QTextCodec::codecForName(codecName.toLatin1());
++ QVERIFY(codec != nullptr);
++ QCOMPARE(codec->mibEnum(), mibEnum);
++
++ // null input
++ QCOMPARE(codec->toUnicode(nullptr), QString());
++ QCOMPARE(codec->toUnicode(nullptr, 0), QString());
++ QCOMPARE(codec->toUnicode(nullptr, -1), QString());
++ QCOMPARE(codec->toUnicode(nullptr, 128), QString());
++
++ // zero, negative length
++ QCOMPARE(codec->toUnicode("abc", 0), QString());
++ QCOMPARE(codec->toUnicode("abc", -1), QString());
++
++ // null input
++ QCOMPARE(codec->fromUnicode(nullptr, 0), QByteArray());
++ QCOMPARE(codec->fromUnicode(nullptr, -1), QByteArray());
++ QCOMPARE(codec->fromUnicode(nullptr, 128), QByteArray());
++
++ // zero, negative length
++ QCOMPARE(codec->fromUnicode(QString("abc").constData(), 0), QByteArray());
++ QCOMPARE(codec->fromUnicode(QString("abc").constData(), -1), QByteArray());
++ }
++
++ void tst_QTextCodec::retainNullness_data()
++ {
++ // QTest doesn't support 'const char *' as the column type, so we have
++ // to get a bit naughty.
++ QTest::addColumn<char *>("input");
++ QTest::addColumn<int>("length");
++ QTest::addColumn<bool>("isNull");
++
++ static char n = '\0';
++ char *empty = &n;
++ char *null = nullptr;
++
++ QTest::addRow("Empty, strlen") << empty << -1 << false;
++ QTest::addRow("Empty, 0") << empty << 0 << false;
++ QTest::addRow("nullptr") << null << -1 << true;
++ }
++
++ void tst_QTextCodec::retainNullness()
++ {
++ QTextCodec* codec = QTextCodec::codecForName("ISO 8859-1");
++
++ QFETCH(char *, input);
++ QFETCH(int, length);
++ QFETCH(bool, isNull);
++
++ const QByteArray ba = length >= 0
++ ? QByteArray(input, length)
++ : QByteArray(input);
++ const QString unicode = length >= 0
++ ? codec->toUnicode(input, length)
++ : codec->toUnicode(input);
++
++ QVERIFY(unicode.isEmpty());
++ QCOMPARE(unicode.isNull(), isNull);
++ QCOMPARE(codec->toUnicode(ba).isEmpty(), ba.isEmpty());
++ QEXPECT_FAIL("nullptr", "Maintaining Qt 5.15 compatibility", Continue);
++ QCOMPARE(codec->toUnicode(ba).isNull(), ba.isNull());
++
++ const QStringView stringView(unicode);
++ QCOMPARE(codec->fromUnicode(unicode).isEmpty(), unicode.isEmpty());
++ QEXPECT_FAIL("nullptr", "Maintaining Qt 5.15 compatibility", Continue);
++ QCOMPARE(codec->fromUnicode(unicode).isNull(), unicode.isNull());
++ QCOMPARE(codec->fromUnicode(stringView).isEmpty(), stringView.isEmpty());
++ QEXPECT_FAIL("nullptr", "Maintaining Qt 5.15 compatibility", Continue);
++ QCOMPARE(codec->fromUnicode(stringView).isNull(), stringView.isNull());
++ }
++
++
++ void tst_QTextCodec::canEncode()
++ {
++ QFETCH(QString, codecName);
++ QFETCH(QString, inputString);
++ QFETCH(QByteArray, expectedData);
++ QFETCH(bool, canEncode);
++
++ QTextCodec *codec = QTextCodec::codecForName(codecName.toLatin1());
++ QVERIFY(codec != nullptr);
++
++ QCOMPARE(codec->canEncode(inputString), canEncode);
++ QByteArray encoded = codec->fromUnicode(inputString);
++ QCOMPARE(encoded, expectedData);
++ }
++
++ void tst_QTextCodec::canEncode_data()
++ {
++ QTest::addColumn<QString>("codecName");
++ QTest::addColumn<QString>("inputString");
++ QTest::addColumn<QByteArray>("expectedData");
++ QTest::addColumn<bool>("canEncode");
++
++ QTest::newRow("English ISO-8859-1") << "ISO-8859-1" << "Hello World"
++ << QByteArray("Hello World") << true;
++ QTest::newRow("English big5") << "Big5" << "Hello World" << QByteArray("Hello World") << true;
++
++ QTest::newRow("Greek win1252")
++ << "Windows-1252"
++ << QString("\u03c0\u03bf\u03bb\u03cd\u03c4\u03c1\u03bf\u03c0\u03bf\u03bd")
++ << QByteArray("??????????") << false;
++ QTest::newRow("Greek win1253")
++ << "Windows-1253"
++ << QString("\u03c0\u03bf\u03bb\u03cd\u03c4\u03c1\u03bf\u03c0\u03bf\u03bd")
++ << QByteArray("\xF0\xEF\xEB\xFD\xF4\xF1\xEF\xF0\xEF\xED") << true;
++
++ QTest::newRow("Russian win1252")
++ << "Windows-1252" << QString("\u041f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0440")
++ << QByteArray("?????? ???") << false;
++ QTest::newRow("Russian win1251")
++ << "Windows-1251" << QString("\u041f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0440")
++ << QByteArray("\xCF\xF0\xE8\xE2\xE5\xF2 \xEC\xE8\xF0") << true;
++
++ QTest::newRow("English from ucs4")
++ << "ISO-8859-1" << QString("\u0048\u0065\u006c\u006c\u006f\u0021")
++ << QByteArray("Hello!") << true;
++
++ QTest::newRow("With null") << "ISO-8859-1" << QString::fromUcs4(U"Hello\u0000World", 11)
++ << QByteArray("Hello\x00World", 11) << true;
++ QTest::newRow("With special chars")
++ << "ISO-8859-1" << QString("\u0001\u0002\u0003\u0008\u0009\u000a\u000b\u000d")
++ << QByteArray("\x01\x02\x03\b\t\n\x0B\r") << true;
++
++ QTest::newRow("Pencil icon") << "ISO-8859-1" << QString("\u270f") << QByteArray("?") << false;
++ }
++
++ void tst_QTextCodec::tsciiEncoderDoesNotReadPastTheEnd_data()
++ {
++ QTest::addColumn<QString>("input");
++ QTest::addColumn<QString>("beyond");
++ QTest::addColumn<QByteArray>("expected");
++
++ // A single non-ASCII character: both uc[len] and uc[len + 1] are read,
++ // and U+0BE7 U+0BB7 U+0B82 is the one three-character sequence in the
++ // table, so the encoder answers 0x8C instead of 0x81 for U+0BE7 alone.
++ QTest::newRow("last-char")
++ << QStringLiteral("\u0BE7")
++ << QStringLiteral("\u0BB7\u0B82")
++ << QByteArray("\x81");
++
++ // Non-ASCII in the second to last position: only uc[len] is read, and
++ // it turns the two-character U+0BE7 U+0BB7 (0x87) into 0x8C again.
++ QTest::newRow("second-to-last-char")
++ << QStringLiteral("\u0BE7\u0BB7")
++ << QStringLiteral("\u0B82\u0000")
++ << QByteArray("\x87");
++
++ // Valid cases.
++ QTest::newRow("valid-three-chars")
++ << QStringLiteral("\u0BE7\u0BB7\u0B82")
++ << QStringLiteral("\u0BC1\u0000")
++ << QByteArray("\x8C");
++ QTest::newRow("valid-two-chars")
++ << QStringLiteral("\u0B95\u0BC2")
++ << QStringLiteral("\u0BCD\u0000")
++ << QByteArray("\xDC");
++ }
++
++ /*
++ This test hands the codec a buffer that is longer than the length it is
++ told about, and checks that the conversion of the first input.size()
++ characters does not depend on what follows them.
++
++ Before the fix, the look-ahead in QTsciiCodec::convertFromUnicode()
++ accesses uc[i + 1] and uc[i + 2] without checking the length, so this
++ fails with the wrong bytes.
++ In practice that could trigger a read past the end of the buffer.
++ */
++ void tst_QTextCodec::tsciiEncoderDoesNotReadPastTheEnd()
++ {
++ QFETCH(const QString, input);
++ QFETCH(const QString, beyond);
++ QFETCH(const QByteArray, expected);
++
++ QTextCodec *codec = QTextCodec::codecForName("TSCII");
++ QVERIFY(codec);
++
++ QCOMPARE(beyond.size(), 2);
++ // One buffer, holding the input followed by the characters that stand for
++ // whatever happens to be in memory after it. Only input.size() characters
++ // are ever passed to the codec.
++ const QString buffer = input + beyond;
++
++ const QChar *data = buffer.constData();
++ const int len = int(input.size());
++
++ QTextCodec::ConverterState state;
++ const QByteArray result = codec->fromUnicode(data, len, &state);
++ QCOMPARE(result, expected);
++
++ // Test with Stateless flag
++ const QByteArray stateless = codec->fromUnicode(QStringView(data, input.size()));
++ QCOMPARE(stateless, expected);
++ }
++
++ /*
++ This test catches a size miscalculation error in the Iconv codec
++ in the case when encoding continues with a high surrogate kept
++ in the state from the encoding of the previous chunk.
++ */
++ void tst_QTextCodec::iconvEncoderPendingSurrogateDoesNotOverflow()
++ {
++ constexpr char32_t Ucs4NonBmp = 0x10437; // DESERET SMALL LETTER YEE
++ // Before the fix such tail was leading to allocating 4096 bytes,
++ // while the full buffer required 4086 _QChars_ (so, almost twice more)
++ constexpr int IconvTailLength = 4064;
++
++ // QIconvCodec registers itself as "System", but it's only available
++ // when the configuration disables ICU and explicitly enables iconv.
++ QTextCodec *codec = QTextCodec::codecForName("System");
++ if (!codec)
++ QSKIP("QIconvCodec was not found (disable ICU and enable iconv explicitly)");
++
++ QString start(10, u'x');
++ start += QChar::highSurrogate(Ucs4NonBmp);
++
++ QString rest;
++ rest += QChar::lowSurrogate(Ucs4NonBmp);
++ rest += QString(IconvTailLength, u'x');
++
++ const QByteArray expected = codec->fromUnicode(start + rest);
++
++ // Encode the first block that ends with the high surrogate.
++ // It should be stored in the converter state.
++ QTextCodec::ConverterState state;
++ QByteArray continued = codec->fromUnicode(start.constData(), int(start.size()), &state);
++
++ // Encode the second block.
++ // Before the fix, this would cause an overrun in the QByteArray
++ // buffer. Detection left for an ASan or Valgrind-checked build.
++ continued += codec->fromUnicode(rest.constData(), int(rest.size()), &state);
++
++ QCOMPARE(continued, expected);
++ QCOMPARE(state.remainingChars, qsizetype(0));
++ }
++
++ /*
++ The ICU codec uses UCNV_GET_MAX_BYTES_FOR_STRING() macro that can
++ overflow on a long input string. As a result, we'll pass a negative
++ length to the c-tor of QByteArray, which will effectively lead to using
++ a global static empty instance. The code that then tries to populate
++ this buffer with the actual encoding results, will get stuck in an infinite
++ loop without a fix.
++ */
++ void tst_QTextCodec::icuNoIntOverflowInFromUnicode()
++ {
++ // Only ICU supports this codec
++ QTextCodec *codec = QTextCodec::codecForName("ISO-2022-KR"); // maxCharSize == 8
++ if (!codec)
++ QSKIP("This test requires ICU");
++
++ QT_TRY {
++ // Enough to trigger int overflow when calculating max buffer size
++ constexpr qsizetype InputLength = 300 * 1024 * 1024;
++ const QString input(InputLength, u'x');
++
++ QTest::ignoreMessage(QtWarningMsg,
++ QRegularExpression("Unable to allocate an output buffer.+"));
++ const QByteArray result = codec->fromUnicode(input);
++ QVERIFY(result.isNull());
++ } QT_CATCH(const std::bad_alloc &) {
++ QSKIP("The test could not allocate enough memory");
++ }
++ }
++
++ QT_END_NAMESPACE
++
++ QTEST_MAIN(tst_QTextCodec)
++ #include "tst_qtextcodec.moc"