View | Details | Raw Unified | Return to bug 1214327
Collapse All | Expand All

(-)a/src/corelib/serialization/qxmlstream.cpp (-6 / +17 lines)
Lines 1296-1302 inline qsizetype QXmlStreamReaderPrivate::fastScanContentCharList() Link Here
1296
    return n;
1296
    return n;
1297
}
1297
}
1298
1298
1299
inline qsizetype QXmlStreamReaderPrivate::fastScanName(Value *val)
1299
// Fast scan an XML attribute name (e.g. "xml:lang").
1300
inline QXmlStreamReaderPrivate::FastScanNameResult
1301
QXmlStreamReaderPrivate::fastScanName(Value *val)
1300
{
1302
{
1301
    qsizetype n = 0;
1303
    qsizetype n = 0;
1302
    uint c;
1304
    uint c;
Lines 1304-1310 inline qsizetype QXmlStreamReaderPrivate::fastScanName(Value *val) Link Here
1304
        if (n >= 4096) {
1306
        if (n >= 4096) {
1305
            // This is too long to be a sensible name, and
1307
            // This is too long to be a sensible name, and
1306
            // can exhaust memory, or the range of decltype(*prefix)
1308
            // can exhaust memory, or the range of decltype(*prefix)
1307
            return 0;
1309
            raiseNamePrefixTooLongError();
1310
            return {};
1308
        }
1311
        }
1309
        switch (c) {
1312
        switch (c) {
1310
        case '\n':
1313
        case '\n':
Lines 1338-1355 inline qsizetype QXmlStreamReaderPrivate::fastScanName(Value *val) Link Here
1338
                putChar(':');
1341
                putChar(':');
1339
                --n;
1342
                --n;
1340
            }
1343
            }
1341
            return n;
1344
            return FastScanNameResult(n);
1342
        case ':':
1345
        case ':':
1343
            if (val) {
1346
            if (val) {
1344
                if (val->prefix == 0) {
1347
                if (val->prefix == 0) {
1345
                    val->prefix = qint16(n + 2);
1348
                    val->prefix = qint16(n + 2);
1346
                } else { // only one colon allowed according to the namespace spec.
1349
                } else { // only one colon allowed according to the namespace spec.
1347
                    putChar(c);
1350
                    putChar(c);
1348
                    return n;
1351
                    return FastScanNameResult(n);
1349
                }
1352
                }
1350
            } else {
1353
            } else {
1351
                putChar(c);
1354
                putChar(c);
1352
                return n;
1355
                return FastScanNameResult(n);
1353
            }
1356
            }
1354
            Q_FALLTHROUGH();
1357
            Q_FALLTHROUGH();
1355
        default:
1358
        default:
Lines 1363-1369 inline qsizetype QXmlStreamReaderPrivate::fastScanName(Value *val) Link Here
1363
    qsizetype pos = textBuffer.size() - n;
1366
    qsizetype pos = textBuffer.size() - n;
1364
    putString(textBuffer, pos);
1367
    putString(textBuffer, pos);
1365
    textBuffer.resize(pos);
1368
    textBuffer.resize(pos);
1366
    return 0;
1369
    return FastScanNameResult(0);
1367
}
1370
}
1368
1371
1369
enum NameChar { NameBeginning, NameNotBeginning, NotName };
1372
enum NameChar { NameBeginning, NameNotBeginning, NotName };
Lines 1841-1846 void QXmlStreamReaderPrivate::raiseWellFormedError(const QString &message) Link Here
1841
    raiseError(QXmlStreamReader::NotWellFormedError, message);
1844
    raiseError(QXmlStreamReader::NotWellFormedError, message);
1842
}
1845
}
1843
1846
1847
void QXmlStreamReaderPrivate::raiseNamePrefixTooLongError()
1848
{
1849
    // TODO: add a ImplementationLimitsExceededError and use it instead
1850
    raiseError(QXmlStreamReader::NotWellFormedError,
1851
               QXmlStream::tr("Length of XML attribute name exceeds implemnetation limits (4KiB "
1852
                              "characters)."));
1853
}
1854
1844
void QXmlStreamReaderPrivate::parseError()
1855
void QXmlStreamReaderPrivate::parseError()
1845
{
1856
{
1846
1857
(-)a/src/corelib/serialization/qxmlstream.g (-2 / +10 lines)
Lines 1420-1426 qname ::= LETTER; Link Here
1420
/.
1420
/.
1421
        case $rule_number: {
1421
        case $rule_number: {
1422
            Value &val = sym(1);
1422
            Value &val = sym(1);
1423
            val.len += fastScanName(&val);
1423
            if (auto res = fastScanName(&val))
1424
                val.len += *res;
1425
            else
1426
                return false;
1427
1424
            if (atEnd) {
1428
            if (atEnd) {
1425
                resume($rule_number);
1429
                resume($rule_number);
1426
                return false;
1430
                return false;
Lines 1431-1437 qname ::= LETTER; Link Here
1431
name ::= LETTER;
1435
name ::= LETTER;
1432
/.
1436
/.
1433
        case $rule_number:
1437
        case $rule_number:
1434
            sym(1).len += fastScanName();
1438
            if (auto res = fastScanName())
1439
                sym(1).len += *res;
1440
            else
1441
                return false;
1442
1435
            if (atEnd) {
1443
            if (atEnd) {
1436
                resume($rule_number);
1444
                resume($rule_number);
1437
                return false;
1445
                return false;
(-)a/src/corelib/serialization/qxmlstream_p.h (-2 / +12 lines)
Lines 38-44 public: Link Here
38
38
39
    constexpr XmlStringRef() = default;
39
    constexpr XmlStringRef() = default;
40
    constexpr inline XmlStringRef(const QString *string, qsizetype pos, qsizetype length)
40
    constexpr inline XmlStringRef(const QString *string, qsizetype pos, qsizetype length)
41
        : m_string(string), m_pos(pos), m_size(length)
41
        : m_string(string), m_pos(pos), m_size((Q_ASSERT(length >= 0), length))
42
    {
42
    {
43
    }
43
    }
44
    XmlStringRef(const QString *string)
44
    XmlStringRef(const QString *string)
Lines 498-504 public: Link Here
498
    qsizetype fastScanLiteralContent();
498
    qsizetype fastScanLiteralContent();
499
    qsizetype fastScanSpace();
499
    qsizetype fastScanSpace();
500
    qsizetype fastScanContentCharList();
500
    qsizetype fastScanContentCharList();
501
    qsizetype fastScanName(Value *val = nullptr);
501
502
    struct FastScanNameResult {
503
        FastScanNameResult() : ok(false) {}
504
        explicit FastScanNameResult(qsizetype len) : addToLen(len), ok(true) { }
505
        operator bool() { return ok; }
506
        qsizetype operator*() { Q_ASSERT(ok); return addToLen; }
507
        qsizetype addToLen;
508
        bool ok;
509
    };
510
    FastScanNameResult fastScanName(Value *val = nullptr);
502
    inline qsizetype fastScanNMTOKEN();
511
    inline qsizetype fastScanNMTOKEN();
503
512
504
513
Lines 507-512 public: Link Here
507
516
508
    void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
517
    void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
509
    void raiseWellFormedError(const QString &message);
518
    void raiseWellFormedError(const QString &message);
519
    void raiseNamePrefixTooLongError();
510
520
511
    QXmlStreamEntityResolver *entityResolver;
521
    QXmlStreamEntityResolver *entityResolver;
512
522
(-)a/src/corelib/serialization/qxmlstreamparser_p.h (-2 / +10 lines)
Lines 948-954 bool QXmlStreamReaderPrivate::parse() Link Here
948
948
949
        case 262: {
949
        case 262: {
950
            Value &val = sym(1);
950
            Value &val = sym(1);
951
            val.len += fastScanName(&val);
951
            if (auto res = fastScanName(&val))
952
                val.len += *res;
953
            else
954
                return false;
955
952
            if (atEnd) {
956
            if (atEnd) {
953
                resume(262);
957
                resume(262);
954
                return false;
958
                return false;
Lines 956-962 bool QXmlStreamReaderPrivate::parse() Link Here
956
        } break;
960
        } break;
957
961
958
        case 263:
962
        case 263:
959
            sym(1).len += fastScanName();
963
            if (auto res = fastScanName())
964
                sym(1).len += *res;
965
            else
966
                return false;
967
960
            if (atEnd) {
968
            if (atEnd) {
961
                resume(263);
969
                resume(263);
962
                return false;
970
                return false;

Return to bug 1214327