Compare commits
2 Commits
a27c5cba2a
...
649a85826e
Author | SHA1 | Date |
---|---|---|
Jan Grulich | 649a85826e | |
Jan Grulich | f21267bde2 |
|
@ -0,0 +1,2 @@
|
||||||
|
a5bbeafa6319cd3e666b12ccc722a357de7230be qtbase-everywhere-opensource-src-5.15.9.tar.xz
|
||||||
|
677b605bf6033bdfa84a676096ec6e77da6e844d kde-5.15-rollup-20230411.patch.gz
|
|
@ -0,0 +1,38 @@
|
||||||
|
From ea63c28efc1d2ecb467b83a34923d12462efa96f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marc Mutz <marc.mutz@qt.io>
|
||||||
|
Date: Tue, 12 Dec 2023 20:51:56 +0100
|
||||||
|
Subject: [PATCH] HPack: fix a Yoda Condition
|
||||||
|
|
||||||
|
Putting the variable on the LHS of a relational operation makes the
|
||||||
|
expression easier to read. In this case, we find that the whole
|
||||||
|
expression is nonsensical as an overflow protection, because if
|
||||||
|
name.size() + value.size() overflows, the result will exactly _not_
|
||||||
|
be > max() - 32, because UB will have happened.
|
||||||
|
|
||||||
|
To be fixed in a follow-up commit.
|
||||||
|
|
||||||
|
As a drive-by, add parentheses around the RHS.
|
||||||
|
|
||||||
|
Change-Id: I35ce598884c37c51b74756b3bd2734b9aad63c09
|
||||||
|
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
||||||
|
(cherry picked from commit 658607a34ead214fbacbc2cca44915655c318ea9)
|
||||||
|
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
||||||
|
(cherry picked from commit 4f7efd41740107f90960116700e3134f5e433867)
|
||||||
|
(cherry picked from commit 13c16b756900fe524f6d9534e8a07aa003c05e0c)
|
||||||
|
(cherry picked from commit 1d4788a39668fb2dc5912a8d9c4272dc40e99f92)
|
||||||
|
(cherry picked from commit 87de75b5cc946d196decaa6aef4792a6cac0b6db)
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp
|
||||||
|
index 834214f..ab166a6 100644
|
||||||
|
--- a/src/network/access/http2/hpacktable.cpp
|
||||||
|
+++ b/src/network/access/http2/hpacktable.cpp
|
||||||
|
@@ -63,7 +63,7 @@
|
||||||
|
// 32 octets of overhead."
|
||||||
|
|
||||||
|
const unsigned sum = unsigned(name.size() + value.size());
|
||||||
|
- if (std::numeric_limits<unsigned>::max() - 32 < sum)
|
||||||
|
+ if (sum > (std::numeric_limits<unsigned>::max() - 32))
|
||||||
|
return HeaderSize();
|
||||||
|
return HeaderSize(true, quint32(sum + 32));
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
From 23c3fc483e8b6e21012a61f0bea884446f727776 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Marc Mutz <marc.mutz@qt.io>
|
||||||
|
Date: Tue, 12 Dec 2023 22:08:07 +0100
|
||||||
|
Subject: [PATCH] HPack: fix incorrect integer overflow check
|
||||||
|
|
||||||
|
This code never worked:
|
||||||
|
|
||||||
|
For the comparison with max() - 32 to trigger, on 32-bit platforms (or
|
||||||
|
Qt 5) signed interger overflow would have had to happen in the
|
||||||
|
addition of the two sizes. The compiler can therefore remove the
|
||||||
|
overflow check as dead code.
|
||||||
|
|
||||||
|
On Qt 6 and 64-bit platforms, the signed integer addition would be
|
||||||
|
very unlikely to overflow, but the following truncation to uint32
|
||||||
|
would yield the correct result only in a narrow 32-value window just
|
||||||
|
below UINT_MAX, if even that.
|
||||||
|
|
||||||
|
Fix by using the proper tool, qAddOverflow.
|
||||||
|
|
||||||
|
Manual conflict resolutions:
|
||||||
|
- qAddOverflow doesn't exist in Qt 5, use private add_overflow
|
||||||
|
predecessor API instead
|
||||||
|
|
||||||
|
Change-Id: I7599f2e75ff7f488077b0c60b81022591005661c
|
||||||
|
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
||||||
|
(cherry picked from commit ee5da1f2eaf8932aeca02ffea6e4c618585e29e3)
|
||||||
|
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
||||||
|
(cherry picked from commit debeb8878da2dc706ead04b6072ecbe7e5313860)
|
||||||
|
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
|
||||||
|
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
|
||||||
|
(cherry picked from commit 811b9eef6d08d929af8708adbf2a5effb0eb62d7)
|
||||||
|
(cherry picked from commit f931facd077ce945f1e42eaa3bead208822d3e00)
|
||||||
|
(cherry picked from commit 9ef4ca5ecfed771dab890856130e93ef5ceabef5)
|
||||||
|
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
|
||||||
|
---
|
||||||
|
|
||||||
|
diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp
|
||||||
|
index ab166a6..de91fc0 100644
|
||||||
|
--- a/src/network/access/http2/hpacktable.cpp
|
||||||
|
+++ b/src/network/access/http2/hpacktable.cpp
|
||||||
|
@@ -40,6 +40,7 @@
|
||||||
|
#include "hpacktable_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
+#include <QtCore/private/qnumeric_p.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
|
@@ -62,7 +63,9 @@
|
||||||
|
// for counting the number of references to the name and value would have
|
||||||
|
// 32 octets of overhead."
|
||||||
|
|
||||||
|
- const unsigned sum = unsigned(name.size() + value.size());
|
||||||
|
+ size_t sum;
|
||||||
|
+ if (add_overflow(size_t(name.size()), size_t(value.size()), &sum))
|
||||||
|
+ return HeaderSize();
|
||||||
|
if (sum > (std::numeric_limits<unsigned>::max() - 32))
|
||||||
|
return HeaderSize();
|
||||||
|
return HeaderSize(true, quint32(sum + 32));
|
|
@ -0,0 +1,203 @@
|
||||||
|
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
|
||||||
|
index 7cd457ba3a..11d162cb79 100644
|
||||||
|
--- a/src/corelib/serialization/qxmlstream.cpp
|
||||||
|
+++ b/src/corelib/serialization/qxmlstream.cpp
|
||||||
|
@@ -1302,15 +1302,18 @@ inline int QXmlStreamReaderPrivate::fastScanContentCharList()
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
-inline int QXmlStreamReaderPrivate::fastScanName(int *prefix)
|
||||||
|
+// Fast scan an XML attribute name (e.g. "xml:lang").
|
||||||
|
+inline QXmlStreamReaderPrivate::FastScanNameResult
|
||||||
|
+QXmlStreamReaderPrivate::fastScanName(Value *val)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
uint c;
|
||||||
|
while ((c = getChar()) != StreamEOF) {
|
||||||
|
if (n >= 4096) {
|
||||||
|
// This is too long to be a sensible name, and
|
||||||
|
- // can exhaust memory
|
||||||
|
- return 0;
|
||||||
|
+ // can exhaust memory, or the range of decltype(*prefix)
|
||||||
|
+ raiseNamePrefixTooLongError();
|
||||||
|
+ return {};
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case '\n':
|
||||||
|
@@ -1339,23 +1342,23 @@ inline int QXmlStreamReaderPrivate::fastScanName(int *prefix)
|
||||||
|
case '+':
|
||||||
|
case '*':
|
||||||
|
putChar(c);
|
||||||
|
- if (prefix && *prefix == n+1) {
|
||||||
|
- *prefix = 0;
|
||||||
|
+ if (val && val->prefix == n + 1) {
|
||||||
|
+ val->prefix = 0;
|
||||||
|
putChar(':');
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
- return n;
|
||||||
|
+ return FastScanNameResult(n);
|
||||||
|
case ':':
|
||||||
|
- if (prefix) {
|
||||||
|
- if (*prefix == 0) {
|
||||||
|
- *prefix = n+2;
|
||||||
|
+ if (val) {
|
||||||
|
+ if (val->prefix == 0) {
|
||||||
|
+ val->prefix = n + 2;
|
||||||
|
} else { // only one colon allowed according to the namespace spec.
|
||||||
|
putChar(c);
|
||||||
|
- return n;
|
||||||
|
+ return FastScanNameResult(n);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
putChar(c);
|
||||||
|
- return n;
|
||||||
|
+ return FastScanNameResult(n);
|
||||||
|
}
|
||||||
|
Q_FALLTHROUGH();
|
||||||
|
default:
|
||||||
|
@@ -1364,12 +1367,12 @@ inline int QXmlStreamReaderPrivate::fastScanName(int *prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (prefix)
|
||||||
|
- *prefix = 0;
|
||||||
|
+ if (val)
|
||||||
|
+ val->prefix = 0;
|
||||||
|
int pos = textBuffer.size() - n;
|
||||||
|
putString(textBuffer, pos);
|
||||||
|
textBuffer.resize(pos);
|
||||||
|
- return 0;
|
||||||
|
+ return FastScanNameResult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NameChar { NameBeginning, NameNotBeginning, NotName };
|
||||||
|
@@ -1878,6 +1881,14 @@ void QXmlStreamReaderPrivate::raiseWellFormedError(const QString &message)
|
||||||
|
raiseError(QXmlStreamReader::NotWellFormedError, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void QXmlStreamReaderPrivate::raiseNamePrefixTooLongError()
|
||||||
|
+{
|
||||||
|
+ // TODO: add a ImplementationLimitsExceededError and use it instead
|
||||||
|
+ raiseError(QXmlStreamReader::NotWellFormedError,
|
||||||
|
+ QXmlStream::tr("Length of XML attribute name exceeds implemnetation limits (4KiB "
|
||||||
|
+ "characters)."));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void QXmlStreamReaderPrivate::parseError()
|
||||||
|
{
|
||||||
|
|
||||||
|
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
|
||||||
|
index 4321fed68a..8c6a1a5887 100644
|
||||||
|
--- a/src/corelib/serialization/qxmlstream.g
|
||||||
|
+++ b/src/corelib/serialization/qxmlstream.g
|
||||||
|
@@ -516,7 +516,16 @@ public:
|
||||||
|
int fastScanLiteralContent();
|
||||||
|
int fastScanSpace();
|
||||||
|
int fastScanContentCharList();
|
||||||
|
- int fastScanName(int *prefix = nullptr);
|
||||||
|
+
|
||||||
|
+ struct FastScanNameResult {
|
||||||
|
+ FastScanNameResult() : ok(false) {}
|
||||||
|
+ explicit FastScanNameResult(int len) : addToLen(len), ok(true) { }
|
||||||
|
+ operator bool() { return ok; }
|
||||||
|
+ int operator*() { Q_ASSERT(ok); return addToLen; }
|
||||||
|
+ int addToLen;
|
||||||
|
+ bool ok;
|
||||||
|
+ };
|
||||||
|
+ FastScanNameResult fastScanName(Value *val = nullptr);
|
||||||
|
inline int fastScanNMTOKEN();
|
||||||
|
|
||||||
|
|
||||||
|
@@ -525,6 +534,7 @@ public:
|
||||||
|
|
||||||
|
void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
|
||||||
|
void raiseWellFormedError(const QString &message);
|
||||||
|
+ void raiseNamePrefixTooLongError();
|
||||||
|
|
||||||
|
QXmlStreamEntityResolver *entityResolver;
|
||||||
|
|
||||||
|
@@ -1811,7 +1821,12 @@ space_opt ::= space;
|
||||||
|
qname ::= LETTER;
|
||||||
|
/.
|
||||||
|
case $rule_number: {
|
||||||
|
- sym(1).len += fastScanName(&sym(1).prefix);
|
||||||
|
+ Value &val = sym(1);
|
||||||
|
+ if (auto res = fastScanName(&val))
|
||||||
|
+ val.len += *res;
|
||||||
|
+ else
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
if (atEnd) {
|
||||||
|
resume($rule_number);
|
||||||
|
return false;
|
||||||
|
@@ -1822,7 +1837,11 @@ qname ::= LETTER;
|
||||||
|
name ::= LETTER;
|
||||||
|
/.
|
||||||
|
case $rule_number:
|
||||||
|
- sym(1).len += fastScanName();
|
||||||
|
+ if (auto res = fastScanName())
|
||||||
|
+ sym(1).len += *res;
|
||||||
|
+ else
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
if (atEnd) {
|
||||||
|
resume($rule_number);
|
||||||
|
return false;
|
||||||
|
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
|
||||||
|
index e5bde7b98e..b01484cac3 100644
|
||||||
|
--- a/src/corelib/serialization/qxmlstream_p.h
|
||||||
|
+++ b/src/corelib/serialization/qxmlstream_p.h
|
||||||
|
@@ -1005,7 +1005,16 @@ public:
|
||||||
|
int fastScanLiteralContent();
|
||||||
|
int fastScanSpace();
|
||||||
|
int fastScanContentCharList();
|
||||||
|
- int fastScanName(int *prefix = nullptr);
|
||||||
|
+
|
||||||
|
+ struct FastScanNameResult {
|
||||||
|
+ FastScanNameResult() : ok(false) {}
|
||||||
|
+ explicit FastScanNameResult(int len) : addToLen(len), ok(true) { }
|
||||||
|
+ operator bool() { return ok; }
|
||||||
|
+ int operator*() { Q_ASSERT(ok); return addToLen; }
|
||||||
|
+ int addToLen;
|
||||||
|
+ bool ok;
|
||||||
|
+ };
|
||||||
|
+ FastScanNameResult fastScanName(Value *val = nullptr);
|
||||||
|
inline int fastScanNMTOKEN();
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1014,6 +1023,7 @@ public:
|
||||||
|
|
||||||
|
void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
|
||||||
|
void raiseWellFormedError(const QString &message);
|
||||||
|
+ void raiseNamePrefixTooLongError();
|
||||||
|
|
||||||
|
QXmlStreamEntityResolver *entityResolver;
|
||||||
|
|
||||||
|
@@ -1939,7 +1949,12 @@ bool QXmlStreamReaderPrivate::parse()
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 262: {
|
||||||
|
- sym(1).len += fastScanName(&sym(1).prefix);
|
||||||
|
+ Value &val = sym(1);
|
||||||
|
+ if (auto res = fastScanName(&val))
|
||||||
|
+ val.len += *res;
|
||||||
|
+ else
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
if (atEnd) {
|
||||||
|
resume(262);
|
||||||
|
return false;
|
||||||
|
@@ -1947,7 +1962,11 @@ bool QXmlStreamReaderPrivate::parse()
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 263:
|
||||||
|
- sym(1).len += fastScanName();
|
||||||
|
+ if (auto res = fastScanName())
|
||||||
|
+ sym(1).len += *res;
|
||||||
|
+ else
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
if (atEnd) {
|
||||||
|
resume(263);
|
||||||
|
return false;
|
|
@ -0,0 +1,219 @@
|
||||||
|
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
|
||||||
|
index bf8a2a9..6ab5d49 100644
|
||||||
|
--- a/src/corelib/serialization/qxmlstream.cpp
|
||||||
|
+++ b/src/corelib/serialization/qxmlstream.cpp
|
||||||
|
@@ -160,7 +160,7 @@
|
||||||
|
addData() or by waiting for it to arrive on the device().
|
||||||
|
|
||||||
|
\value UnexpectedElementError The parser encountered an element
|
||||||
|
- that was different to those it expected.
|
||||||
|
+ or token that was different to those it expected.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
@@ -295,13 +295,34 @@
|
||||||
|
|
||||||
|
QXmlStreamReader is a well-formed XML 1.0 parser that does \e not
|
||||||
|
include external parsed entities. As long as no error occurs, the
|
||||||
|
- application code can thus be assured that the data provided by the
|
||||||
|
- stream reader satisfies the W3C's criteria for well-formed XML. For
|
||||||
|
- example, you can be certain that all tags are indeed nested and
|
||||||
|
- closed properly, that references to internal entities have been
|
||||||
|
- replaced with the correct replacement text, and that attributes have
|
||||||
|
- been normalized or added according to the internal subset of the
|
||||||
|
- DTD.
|
||||||
|
+ application code can thus be assured, that
|
||||||
|
+ \list
|
||||||
|
+ \li the data provided by the stream reader satisfies the W3C's
|
||||||
|
+ criteria for well-formed XML,
|
||||||
|
+ \li tokens are provided in a valid order.
|
||||||
|
+ \endlist
|
||||||
|
+
|
||||||
|
+ Unless QXmlStreamReader raises an error, it guarantees the following:
|
||||||
|
+ \list
|
||||||
|
+ \li All tags are nested and closed properly.
|
||||||
|
+ \li References to internal entities have been replaced with the
|
||||||
|
+ correct replacement text.
|
||||||
|
+ \li Attributes have been normalized or added according to the
|
||||||
|
+ internal subset of the \l DTD.
|
||||||
|
+ \li Tokens of type \l StartDocument happen before all others,
|
||||||
|
+ aside from comments and processing instructions.
|
||||||
|
+ \li At most one DOCTYPE element (a token of type \l DTD) is present.
|
||||||
|
+ \li If present, the DOCTYPE appears before all other elements,
|
||||||
|
+ aside from StartDocument, comments and processing instructions.
|
||||||
|
+ \endlist
|
||||||
|
+
|
||||||
|
+ In particular, once any token of type \l StartElement, \l EndElement,
|
||||||
|
+ \l Characters, \l EntityReference or \l EndDocument is seen, no
|
||||||
|
+ tokens of type StartDocument or DTD will be seen. If one is present in
|
||||||
|
+ the input stream, out of order, an error is raised.
|
||||||
|
+
|
||||||
|
+ \note The token types \l Comment and \l ProcessingInstruction may appear
|
||||||
|
+ anywhere in the stream.
|
||||||
|
|
||||||
|
If an error occurs while parsing, atEnd() and hasError() return
|
||||||
|
true, and error() returns the error that occurred. The functions
|
||||||
|
@@ -620,6 +641,7 @@
|
||||||
|
d->token = -1;
|
||||||
|
return readNext();
|
||||||
|
}
|
||||||
|
+ d->checkToken();
|
||||||
|
return d->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -740,6 +762,14 @@
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
+static const char QXmlStreamReader_XmlContextString[] =
|
||||||
|
+ "Prolog\0"
|
||||||
|
+ "Body\0";
|
||||||
|
+
|
||||||
|
+static const short QXmlStreamReader_XmlContextString_indices[] = {
|
||||||
|
+ 0, 7
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/*!
|
||||||
|
\property QXmlStreamReader::namespaceProcessing
|
||||||
|
The namespace-processing flag of the stream reader
|
||||||
|
@@ -775,6 +805,16 @@
|
||||||
|
QXmlStreamReader_tokenTypeString_indices[d->type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*!
|
||||||
|
+ \internal
|
||||||
|
+ \return \param ctxt (Prolog/Body) as a string.
|
||||||
|
+ */
|
||||||
|
+QString contextString(QXmlStreamReaderPrivate::XmlContext ctxt)
|
||||||
|
+{
|
||||||
|
+ return QLatin1String(QXmlStreamReader_XmlContextString +
|
||||||
|
+ QXmlStreamReader_XmlContextString_indices[static_cast<int>(ctxt)]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#endif // QT_NO_XMLSTREAMREADER
|
||||||
|
|
||||||
|
QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack()
|
||||||
|
@@ -866,6 +906,8 @@
|
||||||
|
|
||||||
|
type = QXmlStreamReader::NoToken;
|
||||||
|
error = QXmlStreamReader::NoError;
|
||||||
|
+ currentContext = XmlContext::Prolog;
|
||||||
|
+ foundDTD = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -4061,6 +4103,92 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool isTokenAllowedInContext(QXmlStreamReader::TokenType type,
|
||||||
|
+ QXmlStreamReaderPrivate::XmlContext loc)
|
||||||
|
+{
|
||||||
|
+ switch (type) {
|
||||||
|
+ case QXmlStreamReader::StartDocument:
|
||||||
|
+ case QXmlStreamReader::DTD:
|
||||||
|
+ return loc == QXmlStreamReaderPrivate::XmlContext::Prolog;
|
||||||
|
+
|
||||||
|
+ case QXmlStreamReader::StartElement:
|
||||||
|
+ case QXmlStreamReader::EndElement:
|
||||||
|
+ case QXmlStreamReader::Characters:
|
||||||
|
+ case QXmlStreamReader::EntityReference:
|
||||||
|
+ case QXmlStreamReader::EndDocument:
|
||||||
|
+ return loc == QXmlStreamReaderPrivate::XmlContext::Body;
|
||||||
|
+
|
||||||
|
+ case QXmlStreamReader::Comment:
|
||||||
|
+ case QXmlStreamReader::ProcessingInstruction:
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ case QXmlStreamReader::NoToken:
|
||||||
|
+ case QXmlStreamReader::Invalid:
|
||||||
|
+ return false;
|
||||||
|
+ default:
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \internal
|
||||||
|
+ \brief QXmlStreamReader::isValidToken
|
||||||
|
+ \return \c true if \param type is a valid token type.
|
||||||
|
+ \return \c false if \param type is an unexpected token,
|
||||||
|
+ which indicates a non-well-formed or invalid XML stream.
|
||||||
|
+ */
|
||||||
|
+bool QXmlStreamReaderPrivate::isValidToken(QXmlStreamReader::TokenType type)
|
||||||
|
+{
|
||||||
|
+ // Don't change currentContext, if Invalid or NoToken occur in the prolog
|
||||||
|
+ if (type == QXmlStreamReader::Invalid || type == QXmlStreamReader::NoToken)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ // If a token type gets rejected in the body, there is no recovery
|
||||||
|
+ const bool result = isTokenAllowedInContext(type, currentContext);
|
||||||
|
+ if (result || currentContext == XmlContext::Body)
|
||||||
|
+ return result;
|
||||||
|
+
|
||||||
|
+ // First non-Prolog token observed => switch context to body and check again.
|
||||||
|
+ currentContext = XmlContext::Body;
|
||||||
|
+ return isTokenAllowedInContext(type, currentContext);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ \internal
|
||||||
|
+ Checks token type and raises an error, if it is invalid
|
||||||
|
+ in the current context (prolog/body).
|
||||||
|
+ */
|
||||||
|
+void QXmlStreamReaderPrivate::checkToken()
|
||||||
|
+{
|
||||||
|
+ Q_Q(QXmlStreamReader);
|
||||||
|
+
|
||||||
|
+ // The token type must be consumed, to keep track if the body has been reached.
|
||||||
|
+ const XmlContext context = currentContext;
|
||||||
|
+ const bool ok = isValidToken(type);
|
||||||
|
+
|
||||||
|
+ // Do nothing if an error has been raised already (going along with an unexpected token)
|
||||||
|
+ if (error != QXmlStreamReader::Error::NoError)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (!ok) {
|
||||||
|
+ raiseError(QXmlStreamReader::UnexpectedElementError,
|
||||||
|
+ QLatin1String("Unexpected token type %1 in %2.")
|
||||||
|
+ .arg(q->tokenString(), contextString(context)));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (type != QXmlStreamReader::DTD)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ // Raise error on multiple DTD tokens
|
||||||
|
+ if (foundDTD) {
|
||||||
|
+ raiseError(QXmlStreamReader::UnexpectedElementError,
|
||||||
|
+ QLatin1String("Found second DTD token in %1.").arg(contextString(context)));
|
||||||
|
+ } else {
|
||||||
|
+ foundDTD = true;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*!
|
||||||
|
\fn bool QXmlStreamAttributes::hasAttribute(const QString &qualifiedName) const
|
||||||
|
\since 4.5
|
||||||
|
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
|
||||||
|
index 8f7c9e0..708059b 100644
|
||||||
|
--- a/src/corelib/serialization/qxmlstream_p.h
|
||||||
|
+++ b/src/corelib/serialization/qxmlstream_p.h
|
||||||
|
@@ -804,6 +804,17 @@
|
||||||
|
#endif
|
||||||
|
bool atEnd;
|
||||||
|
|
||||||
|
+ enum class XmlContext
|
||||||
|
+ {
|
||||||
|
+ Prolog,
|
||||||
|
+ Body,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ XmlContext currentContext = XmlContext::Prolog;
|
||||||
|
+ bool foundDTD = false;
|
||||||
|
+ bool isValidToken(QXmlStreamReader::TokenType type);
|
||||||
|
+ void checkToken();
|
||||||
|
+
|
||||||
|
/*!
|
||||||
|
\sa setType()
|
||||||
|
*/
|
|
@ -57,7 +57,7 @@ BuildRequires: pkgconfig(libsystemd)
|
||||||
Name: qt5-qtbase
|
Name: qt5-qtbase
|
||||||
Summary: Qt5 - QtBase components
|
Summary: Qt5 - QtBase components
|
||||||
Version: 5.15.9
|
Version: 5.15.9
|
||||||
Release: 6%{?dist}
|
Release: 8%{?dist}
|
||||||
|
|
||||||
|
|
||||||
# See LGPL_EXCEPTIONS.txt, for exception details
|
# See LGPL_EXCEPTIONS.txt, for exception details
|
||||||
|
@ -147,6 +147,10 @@ Patch110: CVE-2023-32762-qtbase-5.15.patch
|
||||||
Patch111: CVE-2023-32763-qtbase-5.15.patch
|
Patch111: CVE-2023-32763-qtbase-5.15.patch
|
||||||
Patch112: CVE-2023-33285-qtbase-5.15.patch
|
Patch112: CVE-2023-33285-qtbase-5.15.patch
|
||||||
Patch113: CVE-2023-34410-qtbase-5.15.patch
|
Patch113: CVE-2023-34410-qtbase-5.15.patch
|
||||||
|
Patch114: CVE-2023-37369-qtbase-5.15.patch
|
||||||
|
Patch115: CVE-2023-38197-qtbase-5.15.patch
|
||||||
|
Patch116: 0001-CVE-2023-51714-qtbase-5.15.patch
|
||||||
|
Patch117: 0002-CVE-2023-51714-qtbase-5.15.patch
|
||||||
|
|
||||||
# gating related patches
|
# gating related patches
|
||||||
Patch200: qtbase-disable-tests-not-working-in-gating.patch
|
Patch200: qtbase-disable-tests-not-working-in-gating.patch
|
||||||
|
@ -434,6 +438,10 @@ Qt5 libraries used for drawing widgets and OpenGL items.
|
||||||
%patch -P111 -p1
|
%patch -P111 -p1
|
||||||
%patch -P112 -p1
|
%patch -P112 -p1
|
||||||
%patch -P113 -p1
|
%patch -P113 -p1
|
||||||
|
%patch -P114 -p1
|
||||||
|
%patch -P115 -p1
|
||||||
|
%patch -P116 -p1
|
||||||
|
%patch -P117 -p1
|
||||||
|
|
||||||
## gating related patches
|
## gating related patches
|
||||||
%patch -P200 -p1 -b .disable-tests-not-working-in-gating
|
%patch -P200 -p1 -b .disable-tests-not-working-in-gating
|
||||||
|
@ -1134,6 +1142,14 @@ fi
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jan 04 2024 Jan Grulich <jgrulich@redhat.com> - 5.15.9-8
|
||||||
|
- Fix incorrect integer overflow check in HTTP2 implementation
|
||||||
|
Resolves: RHEL-20239
|
||||||
|
|
||||||
|
* Fri Jul 21 2023 Jan Grulich <jgrulich@redhat.com> - 5.15.9-7
|
||||||
|
- Fix infinite loops in QXmlStreamReader (CVE-2023-38197)
|
||||||
|
Resolves: bz#2222771
|
||||||
|
|
||||||
* Fri Jun 09 2023 Jan Grulich <jgrulich@redhat.com> - 5.15.9-6
|
* Fri Jun 09 2023 Jan Grulich <jgrulich@redhat.com> - 5.15.9-6
|
||||||
- Don't allow remote attacker to bypass security restrictions caused by
|
- Don't allow remote attacker to bypass security restrictions caused by
|
||||||
flaw in certificate validation (CVE-2023-34410) (version #2)
|
flaw in certificate validation (CVE-2023-34410) (version #2)
|
||||||
|
|
Loading…
Reference in New Issue