Compare commits
No commits in common. "c8" and "c10s" have entirely different histories.
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
SOURCES/kde-5.15-rollup-20220324.patch.gz
|
||||
SOURCES/qtbase-everywhere-opensource-src-5.15.3.tar.xz
|
@ -1,2 +0,0 @@
|
||||
981f5fbeb315c2e4adc122cee944368598466b67 SOURCES/kde-5.15-rollup-20220324.patch.gz
|
||||
d7383126e1f412ef26096692b9e50a1887eb11f7 SOURCES/qtbase-everywhere-opensource-src-5.15.3.tar.xz
|
@ -1,38 +0,0 @@
|
||||
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));
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
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));
|
@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z "$QT_XCB_FORCE_SOFTWARE_OPENGL" ]; then
|
||||
|
||||
QT5_CHECK_OPENGL_VERSION=`LANG=C glxinfo 2> /dev/null | grep '^OpenGL version string: ' | head -n 1 | sed -e 's/^OpenGL version string: \([0-9]\).*$/\1/g'` ||:
|
||||
|
||||
if [ "$QT5_CHECK_OPENGL_VERSION" == "1" ]; then
|
||||
QT_XCB_FORCE_SOFTWARE_OPENGL=1
|
||||
export QT_XCB_FORCE_SOFTWARE_OPENGL
|
||||
fi
|
||||
|
||||
unset QT5_CHECK_OPENGL_VERSION
|
||||
|
||||
fi
|
@ -1,13 +0,0 @@
|
||||
--- a/src/network/access/qhsts.cpp
|
||||
+++ b/src/network/access/qhsts.cpp
|
||||
@@ -364,8 +364,8 @@ quoted-pair = "\" CHAR
|
||||
bool QHstsHeaderParser::parse(const QList<QPair<QByteArray, QByteArray>> &headers)
|
||||
{
|
||||
for (const auto &h : headers) {
|
||||
- // We use '==' since header name was already 'trimmed' for us:
|
||||
- if (h.first == "Strict-Transport-Security") {
|
||||
+ // We compare directly because header name was already 'trimmed' for us:
|
||||
+ if (h.first.compare("Strict-Transport-Security", Qt::CaseInsensitive) == 0) {
|
||||
header = h.second;
|
||||
// RFC6797, 8.1:
|
||||
//
|
@ -1,49 +0,0 @@
|
||||
diff --git a/src/gui/painting/qfixed_p.h b/src/gui/painting/qfixed_p.h
|
||||
index 84659288..57d750a4 100644
|
||||
--- a/src/gui/painting/qfixed_p.h
|
||||
+++ b/src/gui/painting/qfixed_p.h
|
||||
@@ -54,6 +54,7 @@
|
||||
#include <QtGui/private/qtguiglobal_p.h>
|
||||
#include "QtCore/qdebug.h"
|
||||
#include "QtCore/qpoint.h"
|
||||
+#include <QtCore/private/qnumeric_p.h>
|
||||
#include "QtCore/qsize.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -182,6 +183,14 @@ Q_DECL_CONSTEXPR inline bool operator<(int i, const QFixed &f) { return i * 64 <
|
||||
Q_DECL_CONSTEXPR inline bool operator>(const QFixed &f, int i) { return f.value() > i * 64; }
|
||||
Q_DECL_CONSTEXPR inline bool operator>(int i, const QFixed &f) { return i * 64 > f.value(); }
|
||||
|
||||
+inline bool qAddOverflow(QFixed v1, QFixed v2, QFixed *r)
|
||||
+{
|
||||
+ int val;
|
||||
+ bool result = add_overflow(v1.value(), v2.value(), &val);
|
||||
+ r->setValue(val);
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
inline QDebug &operator<<(QDebug &dbg, const QFixed &f)
|
||||
{ return dbg << f.toReal(); }
|
||||
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
|
||||
index 26ac37b0..f6c69ff4 100644
|
||||
--- a/src/gui/text/qtextlayout.cpp
|
||||
+++ b/src/gui/text/qtextlayout.cpp
|
||||
@@ -2150,11 +2150,14 @@ found:
|
||||
eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
|
||||
} else {
|
||||
eng->minWidth = qMax(eng->minWidth, lbh.minw);
|
||||
- eng->maxWidth += line.textWidth;
|
||||
+ if (qAddOverflow(eng->maxWidth, line.textWidth, &eng->maxWidth))
|
||||
+ eng->maxWidth = QFIXED_MAX;
|
||||
}
|
||||
|
||||
- if (line.textWidth > 0 && item < eng->layoutData->items.size())
|
||||
- eng->maxWidth += lbh.spaceData.textWidth;
|
||||
+ if (line.textWidth > 0 && item < eng->layoutData->items.size()) {
|
||||
+ if (qAddOverflow(eng->maxWidth, lbh.spaceData.textWidth, &eng->maxWidth))
|
||||
+ eng->maxWidth = QFIXED_MAX;
|
||||
+ }
|
||||
|
||||
line.textWidth += trailingSpace;
|
||||
if (lbh.spaceData.length) {
|
@ -1,97 +0,0 @@
|
||||
From 2103f2487f709dd9546c503820d9ad509e9a63b3 Mon Sep 17 00:00:00 2001
|
||||
From: Thiago Macieira <thiago.macieira@intel.com>
|
||||
Date: Thu, 11 May 2023 21:40:15 -0700
|
||||
Subject: QDnsLookup/Unix: make sure we don't overflow the buffer
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The DNS Records are variable length and encode their size in 16 bits
|
||||
before the Record Data (RDATA). Ensure that both the RDATA and the
|
||||
Record header fields before it fall inside the buffer we have.
|
||||
|
||||
Additionally reject any replies containing more than one query records.
|
||||
|
||||
[ChangeLog][QtNetwork][QDnsLookup] Fixed a bug that could cause a buffer
|
||||
overflow in Unix systems while parsing corrupt, malicious, or truncated
|
||||
replies.
|
||||
|
||||
Pick-to: 5.15 6.2 6.5 6.5.1
|
||||
Change-Id: I3e3bfef633af4130a03afffd175e4b9547654b95
|
||||
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
|
||||
Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io>
|
||||
(cherry picked from commit 7dba2c87619d558a61a30eb30cc1d9c3fe6df94c)
|
||||
|
||||
* asturmlechner 2023-05-18: Resolve conflict with dev branch commit
|
||||
68b625901f9eb7c34e3d7aa302e1c0a454d3190b
|
||||
|
||||
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
|
||||
index 12b40fc35d..99e999d436 100644
|
||||
--- a/src/network/kernel/qdnslookup_unix.cpp
|
||||
+++ b/src/network/kernel/qdnslookup_unix.cpp
|
||||
@@ -227,7 +227,6 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
|
||||
// responseLength in case of error, we still can extract the
|
||||
// exact error code from the response.
|
||||
HEADER *header = (HEADER*)response;
|
||||
- const int answerCount = ntohs(header->ancount);
|
||||
switch (header->rcode) {
|
||||
case NOERROR:
|
||||
break;
|
||||
@@ -260,18 +259,31 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
|
||||
return;
|
||||
}
|
||||
|
||||
- // Skip the query host, type (2 bytes) and class (2 bytes).
|
||||
char host[PACKETSZ], answer[PACKETSZ];
|
||||
unsigned char *p = response + sizeof(HEADER);
|
||||
- int status = local_dn_expand(response, response + responseLength, p, host, sizeof(host));
|
||||
- if (status < 0) {
|
||||
+ int status;
|
||||
+
|
||||
+ if (ntohs(header->qdcount) == 1) {
|
||||
+ // Skip the query host, type (2 bytes) and class (2 bytes).
|
||||
+ status = local_dn_expand(response, response + responseLength, p, host, sizeof(host));
|
||||
+ if (status < 0) {
|
||||
+ reply->error = QDnsLookup::InvalidReplyError;
|
||||
+ reply->errorString = tr("Could not expand domain name");
|
||||
+ return;
|
||||
+ }
|
||||
+ if ((p - response) + status + 4 >= responseLength)
|
||||
+ header->qdcount = 0xffff; // invalid reply below
|
||||
+ else
|
||||
+ p += status + 4;
|
||||
+ }
|
||||
+ if (ntohs(header->qdcount) > 1) {
|
||||
reply->error = QDnsLookup::InvalidReplyError;
|
||||
- reply->errorString = tr("Could not expand domain name");
|
||||
+ reply->errorString = tr("Invalid reply received");
|
||||
return;
|
||||
}
|
||||
- p += status + 4;
|
||||
|
||||
// Extract results.
|
||||
+ const int answerCount = ntohs(header->ancount);
|
||||
int answerIndex = 0;
|
||||
while ((p < response + responseLength) && (answerIndex < answerCount)) {
|
||||
status = local_dn_expand(response, response + responseLength, p, host, sizeof(host));
|
||||
@@ -283,6 +295,11 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
|
||||
const QString name = QUrl::fromAce(host);
|
||||
|
||||
p += status;
|
||||
+
|
||||
+ if ((p - response) + 10 > responseLength) {
|
||||
+ // probably just a truncated reply, return what we have
|
||||
+ return;
|
||||
+ }
|
||||
const quint16 type = (p[0] << 8) | p[1];
|
||||
p += 2; // RR type
|
||||
p += 2; // RR class
|
||||
@@ -290,6 +307,8 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
|
||||
p += 4;
|
||||
const quint16 size = (p[0] << 8) | p[1];
|
||||
p += 2;
|
||||
+ if ((p - response) + size > responseLength)
|
||||
+ return; // truncated
|
||||
|
||||
if (type == QDnsLookup::A) {
|
||||
if (size != 4) {
|
@ -1,54 +0,0 @@
|
||||
--- a/src/network/ssl/qsslsocket_schannel.cpp
|
||||
+++ b/src/network/ssl/qsslsocket_schannel.cpp
|
||||
@@ -1880,6 +1880,28 @@ bool QSslSocketBackendPrivate::verifyCertContext(CERT_CONTEXT *certContext)
|
||||
if (configuration.peerVerifyDepth > 0 && DWORD(configuration.peerVerifyDepth) < verifyDepth)
|
||||
verifyDepth = DWORD(configuration.peerVerifyDepth);
|
||||
|
||||
+ const auto &caCertificates = q->sslConfiguration().caCertificates();
|
||||
+
|
||||
+ if (!rootCertOnDemandLoadingAllowed()
|
||||
+ && !(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_PARTIAL_CHAIN)
|
||||
+ && (q->peerVerifyMode() == QSslSocket::VerifyPeer
|
||||
+ || (isClient && q->peerVerifyMode() == QSslSocket::AutoVerifyPeer))) {
|
||||
+ // When verifying a peer Windows "helpfully" builds a chain that
|
||||
+ // may include roots from the system store. But we don't want that if
|
||||
+ // the user has set their own CA certificates.
|
||||
+ // Since Windows claims this is not a partial chain the root is included
|
||||
+ // and we have to check that it is one of our configured CAs.
|
||||
+ CERT_CHAIN_ELEMENT *element = chain->rgpElement[chain->cElement - 1];
|
||||
+ QSslCertificate certificate = getCertificateFromChainElement(element);
|
||||
+ if (!caCertificates.contains(certificate)) {
|
||||
+ auto error = QSslError(QSslError::CertificateUntrusted, certificate);
|
||||
+ sslErrors += error;
|
||||
+ emit q->peerVerifyError(error);
|
||||
+ if (q->state() != QAbstractSocket::ConnectedState)
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
for (DWORD i = 0; i < verifyDepth; i++) {
|
||||
CERT_CHAIN_ELEMENT *element = chain->rgpElement[i];
|
||||
QSslCertificate certificate = getCertificateFromChainElement(element);
|
||||
|
||||
|
||||
--- a/src/network/ssl/qsslsocket.cpp
|
||||
+++ b/src/network/ssl/qsslsocket.cpp
|
||||
@@ -2221,6 +2221,10 @@ QSslSocketPrivate::QSslSocketPrivate()
|
||||
, flushTriggered(false)
|
||||
{
|
||||
QSslConfigurationPrivate::deepCopyDefaultConfiguration(&configuration);
|
||||
+ // If the global configuration doesn't allow root certificates to be loaded
|
||||
+ // on demand then we have to disable it for this socket as well.
|
||||
+ if (!configuration.allowRootCertOnDemandLoading)
|
||||
+ allowRootCertOnDemandLoading = false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2470,6 +2474,7 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri
|
||||
ptr->sessionProtocol = global->sessionProtocol;
|
||||
ptr->ciphers = global->ciphers;
|
||||
ptr->caCertificates = global->caCertificates;
|
||||
+ ptr->allowRootCertOnDemandLoading = global->allowRootCertOnDemandLoading;
|
||||
ptr->protocol = global->protocol;
|
||||
ptr->peerVerifyMode = global->peerVerifyMode;
|
||||
ptr->peerVerifyDepth = global->peerVerifyDepth;
|
@ -1,202 +0,0 @@
|
||||
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
|
||||
index 4f282f19..6c98e7c0 100644
|
||||
--- a/src/corelib/serialization/qxmlstream.cpp
|
||||
+++ b/src/corelib/serialization/qxmlstream.cpp
|
||||
@@ -1302,11 +1302,19 @@ 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, or the range of decltype(*prefix)
|
||||
+ raiseNamePrefixTooLongError();
|
||||
+ return {};
|
||||
+ }
|
||||
switch (c) {
|
||||
case '\n':
|
||||
case ' ':
|
||||
@@ -1334,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:
|
||||
@@ -1359,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 };
|
||||
@@ -1873,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 b623de95..e4310285 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;
|
||||
|
||||
@@ -1809,7 +1819,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;
|
||||
@@ -1820,7 +1835,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 103b123b..80e7f740 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;
|
||||
|
||||
@@ -1937,7 +1947,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;
|
||||
@@ -1945,7 +1960,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;
|
@ -1,219 +0,0 @@
|
||||
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()
|
||||
*/
|
@ -1,197 +0,0 @@
|
||||
diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp
|
||||
index 0d98e97453..6a79e55109 100644
|
||||
--- a/src/gui/util/qktxhandler.cpp
|
||||
+++ b/src/gui/util/qktxhandler.cpp
|
||||
@@ -73,7 +73,7 @@ struct KTXHeader {
|
||||
quint32 bytesOfKeyValueData;
|
||||
};
|
||||
|
||||
-static const quint32 headerSize = sizeof(KTXHeader);
|
||||
+static constexpr quint32 qktxh_headerSize = sizeof(KTXHeader);
|
||||
|
||||
// Currently unused, declared for future reference
|
||||
struct KTXKeyValuePairItem {
|
||||
@@ -103,11 +103,36 @@ struct KTXMipmapLevel {
|
||||
*/
|
||||
};
|
||||
|
||||
-bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
|
||||
+static bool qAddOverflow(quint32 v1, quint32 v2, quint32 *r) {
|
||||
+ // unsigned additions are well-defined
|
||||
+ *r = v1 + v2;
|
||||
+ return v1 > quint32(v1 + v2);
|
||||
+}
|
||||
+
|
||||
+// Returns the nearest multiple of 4 greater than or equal to 'value'
|
||||
+static bool nearestMultipleOf4(quint32 value, quint32 *result)
|
||||
+{
|
||||
+ constexpr quint32 rounding = 4;
|
||||
+ *result = 0;
|
||||
+ if (qAddOverflow(value, rounding - 1, result))
|
||||
+ return true;
|
||||
+ *result &= ~(rounding - 1);
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+// Returns a slice with prechecked bounds
|
||||
+static QByteArray safeSlice(const QByteArray& array, quint32 start, quint32 length)
|
||||
{
|
||||
- Q_UNUSED(suffix)
|
||||
+ quint32 end = 0;
|
||||
+ if (qAddOverflow(start, length, &end) || end > quint32(array.length()))
|
||||
+ return {};
|
||||
+ return QByteArray(array.data() + start, length);
|
||||
+}
|
||||
|
||||
- return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0);
|
||||
+bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
|
||||
+{
|
||||
+ Q_UNUSED(suffix);
|
||||
+ return block.startsWith(QByteArray::fromRawData(ktxIdentifier, KTX_IDENTIFIER_LENGTH));
|
||||
}
|
||||
|
||||
QTextureFileData QKtxHandler::read()
|
||||
@@ -115,42 +140,97 @@ QTextureFileData QKtxHandler::read()
|
||||
if (!device())
|
||||
return QTextureFileData();
|
||||
|
||||
- QByteArray buf = device()->readAll();
|
||||
- const quint32 dataSize = quint32(buf.size());
|
||||
- if (dataSize < headerSize || !canRead(QByteArray(), buf)) {
|
||||
- qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
|
||||
+ const QByteArray buf = device()->readAll();
|
||||
+ if (size_t(buf.size()) > std::numeric_limits<quint32>::max()) {
|
||||
+ qWarning(lcQtGuiTextureIO, "Too big KTX file %s", logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ if (!canRead(QByteArray(), buf)) {
|
||||
+ qWarning(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ if (buf.size() < qsizetype(qktxh_headerSize)) {
|
||||
+ qWarning(lcQtGuiTextureIO, "Invalid KTX header size in %s", logName().constData());
|
||||
return QTextureFileData();
|
||||
}
|
||||
|
||||
- const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.constData());
|
||||
- if (!checkHeader(*header)) {
|
||||
- qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
|
||||
+ KTXHeader header;
|
||||
+ memcpy(&header, buf.data(), qktxh_headerSize);
|
||||
+ if (!checkHeader(header)) {
|
||||
+ qWarning(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
|
||||
return QTextureFileData();
|
||||
}
|
||||
|
||||
QTextureFileData texData;
|
||||
texData.setData(buf);
|
||||
|
||||
- texData.setSize(QSize(decode(header->pixelWidth), decode(header->pixelHeight)));
|
||||
- texData.setGLFormat(decode(header->glFormat));
|
||||
- texData.setGLInternalFormat(decode(header->glInternalFormat));
|
||||
- texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat));
|
||||
-
|
||||
- texData.setNumLevels(decode(header->numberOfMipmapLevels));
|
||||
- quint32 offset = headerSize + decode(header->bytesOfKeyValueData);
|
||||
- const int maxLevels = qMin(texData.numLevels(), 32); // Cap iterations in case of corrupt file.
|
||||
- for (int i = 0; i < maxLevels; i++) {
|
||||
- if (offset + sizeof(KTXMipmapLevel) > dataSize) // Corrupt file; avoid oob read
|
||||
- break;
|
||||
- const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + offset);
|
||||
- quint32 levelLen = decode(level->imageSize);
|
||||
- texData.setDataOffset(offset + sizeof(KTXMipmapLevel::imageSize), i);
|
||||
- texData.setDataLength(levelLen, i);
|
||||
- offset += sizeof(KTXMipmapLevel::imageSize) + levelLen + (3 - ((levelLen + 3) % 4));
|
||||
+ texData.setSize(QSize(decode(header.pixelWidth), decode(header.pixelHeight)));
|
||||
+ texData.setGLFormat(decode(header.glFormat));
|
||||
+ texData.setGLInternalFormat(decode(header.glInternalFormat));
|
||||
+ texData.setGLBaseInternalFormat(decode(header.glBaseInternalFormat));
|
||||
+
|
||||
+ texData.setNumLevels(decode(header.numberOfMipmapLevels));
|
||||
+
|
||||
+ const quint32 bytesOfKeyValueData = decode(header.bytesOfKeyValueData);
|
||||
+ quint32 headerKeyValueSize;
|
||||
+ if (qAddOverflow(qktxh_headerSize, bytesOfKeyValueData, &headerKeyValueSize)) {
|
||||
+ qWarning(lcQtGuiTextureIO, "Overflow in size of key value data in header of KTX file %s",
|
||||
+ logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ if (headerKeyValueSize >= quint32(buf.size())) {
|
||||
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ // Technically, any number of levels is allowed but if the value is bigger than
|
||||
+ // what is possible in KTX V2 (and what makes sense) we return an error.
|
||||
+ // maxLevels = log2(max(width, height, depth))
|
||||
+ const int maxLevels = (sizeof(quint32) * 8)
|
||||
+ - qCountLeadingZeroBits(std::max(
|
||||
+ { header.pixelWidth, header.pixelHeight, header.pixelDepth }));
|
||||
+
|
||||
+ if (texData.numLevels() > maxLevels) {
|
||||
+ qWarning(lcQtGuiTextureIO, "Too many levels in KTX file %s", logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ quint32 offset = headerKeyValueSize;
|
||||
+ for (int level = 0; level < texData.numLevels(); level++) {
|
||||
+ const auto imageSizeSlice = safeSlice(buf, offset, sizeof(quint32));
|
||||
+ if (imageSizeSlice.isEmpty()) {
|
||||
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ const quint32 imageSize = decode(qFromUnaligned<quint32>(imageSizeSlice.data()));
|
||||
+ offset += sizeof(quint32); // overflow checked indirectly above
|
||||
+
|
||||
+ texData.setDataOffset(offset, level);
|
||||
+ texData.setDataLength(imageSize, level);
|
||||
+
|
||||
+ // Add image data and padding to offset
|
||||
+ quint32 padded = 0;
|
||||
+ if (nearestMultipleOf4(imageSize, &padded)) {
|
||||
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX file %s", logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ quint32 offsetNext;
|
||||
+ if (qAddOverflow(offset, padded, &offsetNext)) {
|
||||
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
|
||||
+ return QTextureFileData();
|
||||
+ }
|
||||
+
|
||||
+ offset = offsetNext;
|
||||
}
|
||||
|
||||
if (!texData.isValid()) {
|
||||
- qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", logName().constData());
|
||||
+ qWarning(lcQtGuiTextureIO, "Invalid values in header of KTX file %s",
|
||||
+ logName().constData());
|
||||
return QTextureFileData();
|
||||
}
|
||||
|
||||
@@ -191,7 +271,7 @@ bool QKtxHandler::checkHeader(const KTXHeader &header)
|
||||
(decode(header.numberOfFaces) == 1));
|
||||
}
|
||||
|
||||
-quint32 QKtxHandler::decode(quint32 val)
|
||||
+quint32 QKtxHandler::decode(quint32 val) const
|
||||
{
|
||||
return inverseEndian ? qbswap<quint32>(val) : val;
|
||||
}
|
||||
diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h
|
||||
index f831e59d95..cdf1b2eaf8 100644
|
||||
--- a/src/gui/util/qktxhandler_p.h
|
||||
+++ b/src/gui/util/qktxhandler_p.h
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
private:
|
||||
bool checkHeader(const KTXHeader &header);
|
||||
- quint32 decode(quint32 val);
|
||||
+ quint32 decode(quint32 val) const;
|
||||
|
||||
bool inverseEndian = false;
|
||||
};
|
@ -1,168 +0,0 @@
|
||||
From b1e75376cc3adfc7da5502a277dfe9711f3e0536 Mon Sep 17 00:00:00 2001
|
||||
From: Mårten Nordheim <marten.nordheim@qt.io>
|
||||
Date: Tue, 25 Jun 2024 17:09:35 +0200
|
||||
Subject: [PATCH] HTTP2: Delay any communication until encrypted() can be responded to
|
||||
|
||||
We have the encrypted() signal that lets users do extra checks on the
|
||||
established connection. It is emitted as BlockingQueued, so the HTTP
|
||||
thread stalls until it is done emitting. Users can potentially call
|
||||
abort() on the QNetworkReply at that point, which is passed as a Queued
|
||||
call back to the HTTP thread. That means that any currently queued
|
||||
signal emission will be processed before the abort() call is processed.
|
||||
|
||||
In the case of HTTP2 it is a little special since it is multiplexed and
|
||||
the code is built to start requests as they are available. This means
|
||||
that, while the code worked fine for HTTP1, since one connection only
|
||||
has one request, it is not working for HTTP2, since we try to send more
|
||||
requests in-between the encrypted() signal and the abort() call.
|
||||
|
||||
This patch changes the code to delay any communication until the
|
||||
encrypted() signal has been emitted and processed, for HTTP2 only.
|
||||
It's done by adding a few booleans, both to know that we have to return
|
||||
early and so we can keep track of what events arose and what we need to
|
||||
resume once enough time has passed that any abort() call must have been
|
||||
processed.
|
||||
|
||||
Fixes: QTBUG-126610
|
||||
Pick-to: 6.8 6.7 6.5 6.2 5.15 5.12
|
||||
Change-Id: Ic25a600c278203256e35f541026f34a8783235ae
|
||||
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
|
||||
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
|
||||
---
|
||||
|
||||
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
|
||||
index 91c41d82..562dfd66 100644
|
||||
--- a/src/network/access/qhttp2protocolhandler.cpp
|
||||
+++ b/src/network/access/qhttp2protocolhandler.cpp
|
||||
@@ -371,12 +371,12 @@ bool QHttp2ProtocolHandler::sendRequest()
|
||||
}
|
||||
}
|
||||
|
||||
- if (!prefaceSent && !sendClientPreface())
|
||||
- return false;
|
||||
-
|
||||
if (!requests.size())
|
||||
return true;
|
||||
|
||||
+ if (!prefaceSent && !sendClientPreface())
|
||||
+ return false;
|
||||
+
|
||||
m_channel->state = QHttpNetworkConnectionChannel::WritingState;
|
||||
// Check what was promised/pushed, maybe we do not have to send a request
|
||||
// and have a response already?
|
||||
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
|
||||
index 647ef431..608e7914 100644
|
||||
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
|
||||
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
|
||||
@@ -255,6 +255,10 @@ void QHttpNetworkConnectionChannel::abort()
|
||||
bool QHttpNetworkConnectionChannel::sendRequest()
|
||||
{
|
||||
Q_ASSERT(!protocolHandler.isNull());
|
||||
+ if (waitingForPotentialAbort) {
|
||||
+ needInvokeSendRequest = true;
|
||||
+ return false; // this return value is unused
|
||||
+ }
|
||||
return protocolHandler->sendRequest();
|
||||
}
|
||||
|
||||
@@ -267,21 +271,28 @@ bool QHttpNetworkConnectionChannel::sendRequest()
|
||||
void QHttpNetworkConnectionChannel::sendRequestDelayed()
|
||||
{
|
||||
QMetaObject::invokeMethod(this, [this] {
|
||||
- Q_ASSERT(!protocolHandler.isNull());
|
||||
if (reply)
|
||||
- protocolHandler->sendRequest();
|
||||
+ sendRequest();
|
||||
}, Qt::ConnectionType::QueuedConnection);
|
||||
}
|
||||
|
||||
void QHttpNetworkConnectionChannel::_q_receiveReply()
|
||||
{
|
||||
Q_ASSERT(!protocolHandler.isNull());
|
||||
+ if (waitingForPotentialAbort) {
|
||||
+ needInvokeReceiveReply = true;
|
||||
+ return;
|
||||
+ }
|
||||
protocolHandler->_q_receiveReply();
|
||||
}
|
||||
|
||||
void QHttpNetworkConnectionChannel::_q_readyRead()
|
||||
{
|
||||
Q_ASSERT(!protocolHandler.isNull());
|
||||
+ if (waitingForPotentialAbort) {
|
||||
+ needInvokeReadyRead = true;
|
||||
+ return;
|
||||
+ }
|
||||
protocolHandler->_q_readyRead();
|
||||
}
|
||||
|
||||
@@ -1287,7 +1298,18 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
|
||||
// Similar to HTTP/1.1 counterpart below:
|
||||
const auto &pairs = spdyRequestsToSend.values(); // (request, reply)
|
||||
const auto &pair = pairs.first();
|
||||
+ waitingForPotentialAbort = true;
|
||||
emit pair.second->encrypted();
|
||||
+
|
||||
+ // We don't send or handle any received data until any effects from
|
||||
+ // emitting encrypted() have been processed. This is necessary
|
||||
+ // because the user may have called abort(). We may also abort the
|
||||
+ // whole connection if the request has been aborted and there is
|
||||
+ // no more requests to send.
|
||||
+ QMetaObject::invokeMethod(this,
|
||||
+ &QHttpNetworkConnectionChannel::checkAndResumeCommunication,
|
||||
+ Qt::QueuedConnection);
|
||||
+
|
||||
// In case our peer has sent us its settings (window size, max concurrent streams etc.)
|
||||
// let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
|
||||
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
||||
@@ -1305,6 +1327,26 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
|
||||
}
|
||||
}
|
||||
|
||||
+void QHttpNetworkConnectionChannel::checkAndResumeCommunication()
|
||||
+{
|
||||
+ Q_ASSERT(connection->connectionType() > QHttpNetworkConnection::ConnectionTypeHTTP);
|
||||
+
|
||||
+ // Because HTTP/2 requires that we send a SETTINGS frame as the first thing we do, and respond
|
||||
+ // to a SETTINGS frame with an ACK, we need to delay any handling until we can ensure that any
|
||||
+ // effects from emitting encrypted() have been processed.
|
||||
+ // This function is called after encrypted() was emitted, so check for changes.
|
||||
+
|
||||
+ if (!reply && spdyRequestsToSend.isEmpty())
|
||||
+ abort();
|
||||
+ waitingForPotentialAbort = false;
|
||||
+ if (needInvokeReadyRead)
|
||||
+ _q_readyRead();
|
||||
+ if (needInvokeReceiveReply)
|
||||
+ _q_receiveReply();
|
||||
+ if (needInvokeSendRequest)
|
||||
+ sendRequest();
|
||||
+}
|
||||
+
|
||||
void QHttpNetworkConnectionChannel::requeueSpdyRequests()
|
||||
{
|
||||
QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
|
||||
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
|
||||
index d8ac3979..eac44464 100644
|
||||
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
|
||||
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
|
||||
@@ -107,6 +107,10 @@ public:
|
||||
QAbstractSocket *socket;
|
||||
bool ssl;
|
||||
bool isInitialized;
|
||||
+ bool waitingForPotentialAbort = false;
|
||||
+ bool needInvokeReceiveReply = false;
|
||||
+ bool needInvokeReadyRead = false;
|
||||
+ bool needInvokeSendRequest = false;
|
||||
ChannelState state;
|
||||
QHttpNetworkRequest request; // current request, only used for HTTP
|
||||
QHttpNetworkReply *reply; // current reply for this request, only used for HTTP
|
||||
@@ -187,6 +191,8 @@ public:
|
||||
void closeAndResendCurrentRequest();
|
||||
void resendCurrentRequest();
|
||||
|
||||
+ void checkAndResumeCommunication();
|
||||
+
|
||||
bool isSocketBusy() const;
|
||||
bool isSocketWriting() const;
|
||||
bool isSocketWaiting() const;
|
@ -1,4 +0,0 @@
|
||||
%_qt5 @@NAME@@
|
||||
%_qt5_epoch @@EPOCH@@
|
||||
%_qt5_version @@VERSION@@
|
||||
%_qt5_evr @@EVR@@
|
@ -1,23 +0,0 @@
|
||||
/* qconfig.h */
|
||||
/* This file is here to prevent a file conflict on multiarch systems. A
|
||||
* conflict will occur because qconfig.h has arch-specific definitions.
|
||||
*
|
||||
* DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */
|
||||
|
||||
#ifndef QCONFIG_MULTILIB_H
|
||||
#define QCONFIG_MULTILIB_H
|
||||
|
||||
#ifndef __WORDSIZE
|
||||
#include <bits/wordsize.h>
|
||||
#endif
|
||||
|
||||
#if __WORDSIZE == 32
|
||||
#include "QtCore/qconfig-32.h"
|
||||
#elif __WORDSIZE == 64
|
||||
#include "QtCore/qconfig-64.h"
|
||||
#else
|
||||
#error "unexpected value for __WORDSIZE macro"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,17 +0,0 @@
|
||||
diff -up qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json.firebird qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json
|
||||
--- qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json.firebird 2019-01-28 11:11:52.000000000 -0600
|
||||
+++ qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json 2019-02-03 13:41:27.392305128 -0600
|
||||
@@ -49,10 +49,11 @@
|
||||
"ibase": {
|
||||
"label": "InterBase",
|
||||
"test": {},
|
||||
- "headers": "ibase.h",
|
||||
+ "headers": "ibase.h",
|
||||
"sources": [
|
||||
{ "libs": "-lgds32_ms", "condition": "config.win32" },
|
||||
- { "libs": "-lgds", "condition": "!config.win32" }
|
||||
+ { "libs": "-lgds", "condition": "!config.win32" },
|
||||
+ { "libs": "-lfbclient", "condition": "!config.win32" }
|
||||
]
|
||||
},
|
||||
"mysql": {
|
@ -1,29 +0,0 @@
|
||||
diff -up qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json.firebird qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json
|
||||
--- qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json.firebird 2019-01-28 11:11:52.000000000 -0600
|
||||
+++ qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json 2019-02-03 13:41:27.392305128 -0600
|
||||
@@ -49,10 +49,11 @@
|
||||
"ibase": {
|
||||
"label": "InterBase",
|
||||
"test": {},
|
||||
- "headers": "ibase.h",
|
||||
+ "headers": "firebird/ibase.h",
|
||||
"sources": [
|
||||
{ "libs": "-lgds32_ms", "condition": "config.win32" },
|
||||
- { "libs": "-lgds", "condition": "!config.win32" }
|
||||
+ { "libs": "-lgds", "condition": "!config.win32" },
|
||||
+ { "libs": "-lfbclient", "condition": "!config.win32" }
|
||||
]
|
||||
},
|
||||
"mysql": {
|
||||
diff -up qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/ibase/qsql_ibase_p.h.firebird qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/ibase/qsql_ibase_p.h
|
||||
--- qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/ibase/qsql_ibase_p.h.firebird 2019-01-28 11:11:52.000000000 -0600
|
||||
+++ qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/ibase/qsql_ibase_p.h 2019-02-03 13:27:30.683142996 -0600
|
||||
@@ -52,7 +52,7 @@
|
||||
//
|
||||
|
||||
#include <QtSql/qsqldriver.h>
|
||||
-#include <ibase.h>
|
||||
+#include <firebird/ibase.h>
|
||||
|
||||
#ifdef QT_PLUGIN
|
||||
#define Q_EXPORT_SQLDRIVER_IBASE
|
@ -1,13 +0,0 @@
|
||||
diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf
|
||||
index e7e6ee1..ff2a939 100644
|
||||
--- a/mkspecs/common/gcc-base.conf
|
||||
+++ b/mkspecs/common/gcc-base.conf
|
||||
@@ -32,7 +32,7 @@
|
||||
#
|
||||
|
||||
QMAKE_CFLAGS_OPTIMIZE = -O2
|
||||
-QMAKE_CFLAGS_OPTIMIZE_FULL = -O3
|
||||
+QMAKE_CFLAGS_OPTIMIZE_FULL = -O2
|
||||
QMAKE_CFLAGS_OPTIMIZE_DEBUG = -Og
|
||||
QMAKE_CFLAGS_OPTIMIZE_SIZE = -Os
|
||||
|
@ -1,171 +0,0 @@
|
||||
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
|
||||
index 06fd88da..dbff3239 100644
|
||||
--- a/src/corelib/codecs/qtextcodec.cpp
|
||||
+++ b/src/corelib/codecs/qtextcodec.cpp
|
||||
@@ -38,6 +38,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qplatformdefs.h"
|
||||
|
||||
#include "qtextcodec.h"
|
||||
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
|
||||
index 8561f908..8128d3cf 100644
|
||||
--- a/src/corelib/codecs/qutfcodec.cpp
|
||||
+++ b/src/corelib/codecs/qutfcodec.cpp
|
||||
@@ -38,6 +38,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
+
|
||||
#include "qutfcodec_p.h"
|
||||
#include "qlist.h"
|
||||
#include "qendian.h"
|
||||
diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp
|
||||
index eb08b2f8..6b41b3dd 100644
|
||||
--- a/src/corelib/global/qendian.cpp
|
||||
+++ b/src/corelib/global/qendian.cpp
|
||||
@@ -38,6 +38,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qendian.h"
|
||||
|
||||
#include "qalgorithms.h"
|
||||
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
|
||||
index c9733174..c62a1972 100644
|
||||
--- a/src/corelib/global/qfloat16.cpp
|
||||
+++ b/src/corelib/global/qfloat16.cpp
|
||||
@@ -38,6 +38,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qfloat16.h"
|
||||
#include "private/qsimd_p.h"
|
||||
#include <cmath> // for fpclassify()'s return values
|
||||
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
|
||||
index 10672c1f..6d5fd63e 100644
|
||||
--- a/src/corelib/global/qrandom.cpp
|
||||
+++ b/src/corelib/global/qrandom.cpp
|
||||
@@ -40,6 +40,7 @@
|
||||
// for rand_s
|
||||
#define _CRT_RAND_S
|
||||
|
||||
+#include <limits>
|
||||
#include "qrandom.h"
|
||||
#include "qrandom_p.h"
|
||||
#include <qobjectdefs.h>
|
||||
diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp
|
||||
index 13eee353..9e7a7a41 100644
|
||||
--- a/src/corelib/plugin/qelfparser_p.cpp
|
||||
+++ b/src/corelib/plugin/qelfparser_p.cpp
|
||||
@@ -37,6 +37,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qelfparser_p.h"
|
||||
|
||||
#if defined (Q_OF_ELF) && defined(Q_CC_GNU)
|
||||
diff --git a/src/corelib/plugin/qmachparser.cpp b/src/corelib/plugin/qmachparser.cpp
|
||||
index 11670caf..39f5596b 100644
|
||||
--- a/src/corelib/plugin/qmachparser.cpp
|
||||
+++ b/src/corelib/plugin/qmachparser.cpp
|
||||
@@ -37,6 +37,8 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
+
|
||||
#include "qmachparser_p.h"
|
||||
|
||||
#if defined(Q_OF_MACH_O)
|
||||
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
|
||||
index 83873edf..5aafb4e5 100644
|
||||
--- a/src/corelib/plugin/quuid.cpp
|
||||
+++ b/src/corelib/plugin/quuid.cpp
|
||||
@@ -38,6 +38,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "quuid.h"
|
||||
|
||||
#include "qcryptographichash.h"
|
||||
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
|
||||
index 5082a8cb..7eecfcca 100644
|
||||
--- a/src/corelib/serialization/qdatastream.cpp
|
||||
+++ b/src/corelib/serialization/qdatastream.cpp
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "qdatastream.h"
|
||||
#include "qdatastream_p.h"
|
||||
|
||||
+#include <limits>
|
||||
+
|
||||
#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
|
||||
#include "qbuffer.h"
|
||||
#include "qfloat16.h"
|
||||
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
|
||||
index 9a72df58..6651ee98 100644
|
||||
--- a/src/corelib/text/qbytearray.cpp
|
||||
+++ b/src/corelib/text/qbytearray.cpp
|
||||
@@ -39,6 +39,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qbytearray.h"
|
||||
#include "qbytearraymatcher.h"
|
||||
#include "private/qtools_p.h"
|
||||
diff --git a/src/corelib/text/qbytearraymatcher.cpp b/src/corelib/text/qbytearraymatcher.cpp
|
||||
index 72e09226..80511cb5 100644
|
||||
--- a/src/corelib/text/qbytearraymatcher.cpp
|
||||
+++ b/src/corelib/text/qbytearraymatcher.cpp
|
||||
@@ -37,6 +37,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qbytearraymatcher.h"
|
||||
|
||||
#include <limits.h>
|
||||
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
|
||||
index ab3054d5..22efb3a0 100644
|
||||
--- a/src/corelib/tools/qbitarray.cpp
|
||||
+++ b/src/corelib/tools/qbitarray.cpp
|
||||
@@ -38,6 +38,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qbitarray.h"
|
||||
#include <qalgorithms.h>
|
||||
#include <qdatastream.h>
|
||||
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
|
||||
index fa8d21e0..cd85956d 100644
|
||||
--- a/src/corelib/tools/qcryptographichash.cpp
|
||||
+++ b/src/corelib/tools/qcryptographichash.cpp
|
||||
@@ -38,6 +38,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include <qcryptographichash.h>
|
||||
#include <qiodevice.h>
|
||||
|
||||
diff --git a/src/gui/text/qfontengine_qpf2.cpp b/src/gui/text/qfontengine_qpf2.cpp
|
||||
index e00f9d05..917ab5f9 100644
|
||||
--- a/src/gui/text/qfontengine_qpf2.cpp
|
||||
+++ b/src/gui/text/qfontengine_qpf2.cpp
|
||||
@@ -37,6 +37,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
+#include <limits>
|
||||
#include "qfontengine_qpf2_p.h"
|
||||
|
||||
#include <QtCore/QFile>
|
@ -1,30 +0,0 @@
|
||||
diff --git a/mkspecs/features/uikit/devices.py b/mkspecs/features/uikit/devices.py
|
||||
index 8cdcb370..b0c927ea 100755
|
||||
--- a/mkspecs/features/uikit/devices.py
|
||||
+++ b/mkspecs/features/uikit/devices.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
|
||||
#############################################################################
|
||||
##
|
||||
diff --git a/tests/manual/xembed-raster/gtk-embedder.py b/tests/manual/xembed-raster/gtk-embedder.py
|
||||
index 5c37fd44..86ffa9fd 100755
|
||||
--- a/tests/manual/xembed-raster/gtk-embedder.py
|
||||
+++ b/tests/manual/xembed-raster/gtk-embedder.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2013 Canonical Ltd.
|
||||
diff --git a/tests/manual/xembed-widgets/gtk-embedder.py b/tests/manual/xembed-widgets/gtk-embedder.py
|
||||
index 2a7c92db..93135b14 100755
|
||||
--- a/tests/manual/xembed-widgets/gtk-embedder.py
|
||||
+++ b/tests/manual/xembed-widgets/gtk-embedder.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2013 Canonical Ltd.
|
@ -1,14 +0,0 @@
|
||||
diff -up qtbase-everywhere-src-5.12.1/src/gui/Qt5GuiConfigExtras.cmake.in.foo qtbase-everywhere-src-5.12.1/src/gui/Qt5GuiConfigExtras.cmake.in
|
||||
--- qtbase-everywhere-src-5.12.1/src/gui/Qt5GuiConfigExtras.cmake.in.foo 2019-04-30 15:18:24.886346423 -0500
|
||||
+++ qtbase-everywhere-src-5.12.1/src/gui/Qt5GuiConfigExtras.cmake.in 2019-04-30 15:19:48.303873296 -0500
|
||||
@@ -66,8 +66,10 @@ unset(_GL_INCDIRS)
|
||||
# Don\'t check for existence of the "_qt5gui_OPENGL_INCLUDE_DIR" because it is
|
||||
# optional.
|
||||
|
||||
+if (NOT ${_qt5gui_OPENGL_INCLUDE_DIR} STREQUAL "/usr/include")
|
||||
list(APPEND Qt5Gui_INCLUDE_DIRS ${_qt5gui_OPENGL_INCLUDE_DIR})
|
||||
set_property(TARGET Qt5::Gui APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${_qt5gui_OPENGL_INCLUDE_DIR})
|
||||
+endif()
|
||||
|
||||
unset(_qt5gui_OPENGL_INCLUDE_DIR CACHE)
|
||||
|
@ -1,16 +0,0 @@
|
||||
diff -up qtbase-everywhere-src-5.14.2/src/corelib/global/qlibraryinfo.cpp.no_relocatable qtbase-everywhere-src-5.14.2/src/corelib/global/qlibraryinfo.cpp
|
||||
--- qtbase-everywhere-src-5.14.2/src/corelib/global/qlibraryinfo.cpp.no_relocatable 2020-03-27 04:49:31.000000000 -0500
|
||||
+++ qtbase-everywhere-src-5.14.2/src/corelib/global/qlibraryinfo.cpp 2020-04-13 15:13:44.075705226 -0500
|
||||
@@ -671,8 +671,11 @@ static QString getPrefix(
|
||||
# if QT_CONFIGURE_CROSSBUILD
|
||||
if (group == QLibraryInfo::DevicePaths)
|
||||
return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH);
|
||||
-# endif
|
||||
+# elif 0 //QT_CONFIG(relocatable)
|
||||
return getExtPrefixFromHostBinDir();
|
||||
+# else
|
||||
+ return QString::fromLocal8Bit(QT_CONFIGURE_PREFIX_PATH);
|
||||
+# endif
|
||||
#elif QT_CONFIG(relocatable)
|
||||
return getRelocatablePrefix();
|
||||
#else
|
@ -1,15 +0,0 @@
|
||||
diff -up qtbase-everywhere-src-5.15.2/src/gui/configure.json.libglvnd qtbase-everywhere-src-5.15.2/src/gui/configure.json
|
||||
--- qtbase-everywhere-src-5.15.2/src/gui/configure.json.libglvnd 2020-10-27 03:02:11.000000000 -0500
|
||||
+++ qtbase-everywhere-src-5.15.2/src/gui/configure.json 2021-09-10 10:05:53.610312223 -0500
|
||||
@@ -847,9 +847,9 @@
|
||||
],
|
||||
"include": [ "EGL/egl.h", "X11/Xlib.h" ],
|
||||
"main": [
|
||||
- "Display *dpy = EGL_DEFAULT_DISPLAY;",
|
||||
+ "Display *dpy = reinterpret_cast<Display *>(EGL_DEFAULT_DISPLAY);",
|
||||
"EGLNativeDisplayType egldpy = XOpenDisplay(\"\");",
|
||||
- "dpy = egldpy;",
|
||||
+ "dpy = reinterpret_cast<Display *>(egldpy);",
|
||||
"EGLNativeWindowType w = XCreateWindow(dpy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);",
|
||||
"XDestroyWindow(dpy, w);",
|
||||
"XCloseDisplay(dpy);"
|
@ -1,60 +0,0 @@
|
||||
From 95064c35826793c5d6a4edff9fa08ad308b047bb Mon Sep 17 00:00:00 2001
|
||||
From: Timur Pocheptsov <timur.pocheptsov@qt.io>
|
||||
Date: Tue, 20 Jul 2021 08:16:28 +0200
|
||||
Subject: [PATCH] H2: emit encrypted for at least the first reply, similar to
|
||||
H1
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fixes: QTBUG-95277
|
||||
Change-Id: I1fe01503376c0d6278e366d7bd31b412b7cc3a69
|
||||
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
|
||||
(cherry picked from commit c23b7886348dc313ccec1a131850a7cce1b429de)
|
||||
---
|
||||
src/network/access/qhttpnetworkconnectionchannel.cpp | 4 ++++
|
||||
tests/auto/network/access/http2/tst_http2.cpp | 9 +++++++++
|
||||
2 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
|
||||
index f1db2744..647ef431 100644
|
||||
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
|
||||
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
|
||||
@@ -1284,6 +1284,10 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
|
||||
connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
|
||||
// we call setSpdyWasUsed(true) on the replies in the SPDY handler when the request is sent
|
||||
if (spdyRequestsToSend.count() > 0) {
|
||||
+ // Similar to HTTP/1.1 counterpart below:
|
||||
+ const auto &pairs = spdyRequestsToSend.values(); // (request, reply)
|
||||
+ const auto &pair = pairs.first();
|
||||
+ emit pair.second->encrypted();
|
||||
// In case our peer has sent us its settings (window size, max concurrent streams etc.)
|
||||
// let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection).
|
||||
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
||||
diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp
|
||||
index 6702f25b..95a97902 100644
|
||||
--- a/tests/auto/network/access/http2/tst_http2.cpp
|
||||
+++ b/tests/auto/network/access/http2/tst_http2.cpp
|
||||
@@ -267,6 +267,10 @@ void tst_Http2::singleRequest()
|
||||
request.setAttribute(h2Attribute, QVariant(true));
|
||||
|
||||
auto reply = manager->get(request);
|
||||
+#if QT_CONFIG(ssl)
|
||||
+ QSignalSpy encSpy(reply, &QNetworkReply::encrypted);
|
||||
+#endif // QT_CONFIG(ssl)
|
||||
+
|
||||
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
||||
// Since we're using self-signed certificates,
|
||||
// ignore SSL errors:
|
||||
@@ -281,6 +285,11 @@ void tst_Http2::singleRequest()
|
||||
|
||||
QCOMPARE(reply->error(), QNetworkReply::NoError);
|
||||
QVERIFY(reply->isFinished());
|
||||
+
|
||||
+#if QT_CONFIG(ssl)
|
||||
+ if (connectionType == H2Type::h2Alpn || connectionType == H2Type::h2Direct)
|
||||
+ QCOMPARE(encSpy.count(), 1);
|
||||
+#endif // QT_CONFIG(ssl)
|
||||
}
|
||||
|
||||
void tst_Http2::multipleRequests()
|
@ -1,12 +0,0 @@
|
||||
diff -up qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp.hidpi_scale_at_192 qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp
|
||||
--- qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp.hidpi_scale_at_192 2019-02-03 13:21:27.866906481 -0600
|
||||
+++ qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp 2019-02-03 13:23:47.554767565 -0600
|
||||
@@ -744,7 +744,7 @@ void QXcbScreen::updateGeometry(const QR
|
||||
// Use 128 as a reference DPI on small screens. This favors "small UI" over "large UI".
|
||||
qreal referenceDpi = physicalSize().width() <= 320 ? 128 : 96;
|
||||
|
||||
- m_pixelDensity = qMax(1, qRound(dpi/referenceDpi));
|
||||
+ m_pixelDensity = qMax(1, (int) (dpi/referenceDpi)); //instead of rounding at 1.5, round at 2.0 (same as GNOME)
|
||||
m_geometry = geometry;
|
||||
m_availableGeometry = geometry & m_virtualDesktop->workArea();
|
||||
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
|
@ -1,33 +0,0 @@
|
||||
diff -r -u a/mkspecs/linux-g++/qmake.conf b/mkspecs/linux-g++/qmake.conf
|
||||
--- a/mkspecs/linux-g++/qmake.conf 2015-10-30 06:20:01.000000000 -0200
|
||||
+++ b/mkspecs/linux-g++/qmake.conf 2015-11-05 11:23:23.230741601 -0200
|
||||
@@ -5,6 +5,7 @@
|
||||
MAKEFILE_GENERATOR = UNIX
|
||||
CONFIG += incremental
|
||||
QMAKE_INCREMENTAL_STYLE = sublib
|
||||
+QMAKE_CFLAGS_RELEASE += -O2
|
||||
|
||||
include(../common/linux.conf)
|
||||
include(../common/gcc-base-unix.conf)
|
||||
diff -r -u a/mkspecs/linux-g++-32/qmake.conf b/mkspecs/linux-g++-32/qmake.conf
|
||||
--- a/mkspecs/linux-g++-32/qmake.conf 2015-10-30 06:20:01.000000000 -0200
|
||||
+++ b/mkspecs/linux-g++-32/qmake.conf 2015-11-05 11:22:19.761494470 -0200
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
QMAKE_CFLAGS = -m32
|
||||
QMAKE_LFLAGS = -m32
|
||||
+QMAKE_CFLAGS_RELEASE += -O2
|
||||
|
||||
include(../common/gcc-base-unix.conf)
|
||||
include(../common/g++-unix.conf)
|
||||
diff -r -u a/mkspecs/linux-g++-64/qmake.conf b/mkspecs/linux-g++-64/qmake.conf
|
||||
--- a/mkspecs/linux-g++-64/qmake.conf 2015-10-30 06:20:01.000000000 -0200
|
||||
+++ b/mkspecs/linux-g++-64/qmake.conf 2015-11-05 11:22:49.497610248 -0200
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
QMAKE_CFLAGS = -m64
|
||||
QMAKE_LFLAGS = -m64
|
||||
+QMAKE_CFLAGS_RELEASE += -O2
|
||||
|
||||
include(../common/gcc-base-unix.conf)
|
||||
include(../common/g++-unix.conf)
|
@ -1,15 +0,0 @@
|
||||
diff -up qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp.moc_WORDSIZE qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp
|
||||
--- qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp.moc_WORDSIZE 2016-12-01 02:17:04.000000000 -0600
|
||||
+++ qtbase-opensource-src-5.7.1/src/tools/moc/main.cpp 2016-12-08 12:37:28.931589338 -0600
|
||||
@@ -179,6 +179,11 @@ int runMoc(int argc, char **argv)
|
||||
Moc moc;
|
||||
pp.macros["Q_MOC_RUN"];
|
||||
pp.macros["__cplusplus"];
|
||||
+ pp.macros["_SYS_SYSMACROS_H_OUTER"];
|
||||
+ Macro macro;
|
||||
+ macro.symbols = Preprocessor::tokenize(QByteArray::number(Q_PROCESSOR_WORDSIZE*8), 1, Preprocessor::TokenizeDefine);
|
||||
+ macro.symbols.removeLast(); // remove the EOF symbol
|
||||
+ pp.macros.insert("__WORDSIZE", macro);
|
||||
|
||||
// Don't stumble over GCC extensions
|
||||
Macro dummyVariadicFunctionMacro;
|
@ -1,11 +0,0 @@
|
||||
--- qtbase-opensource-src-5.8.0/src/corelib/global/qglobal.h.orig 2017-01-26 10:45:40.905010896 +0100
|
||||
+++ qtbase-opensource-src-5.8.0/src/corelib/global/qglobal.h 2017-01-26 10:46:50.299858887 +0100
|
||||
@@ -55,7 +55,7 @@
|
||||
/*
|
||||
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
|
||||
*/
|
||||
-#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
|
||||
+#define QT_VERSION_CHECK(qt_version_check_major, qt_version_check_minor, qt_version_check_patch) ((qt_version_check_major<<16)|(qt_version_check_minor<<8)|(qt_version_check_patch))
|
||||
|
||||
#ifdef QT_BOOTSTRAPPED
|
||||
#include <QtCore/qconfig-bootstrapped.h>
|
@ -1,12 +0,0 @@
|
||||
diff -up qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql.cpp.than qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
|
||||
diff -up qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h.than qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h
|
||||
--- qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h.than 2017-07-14 13:43:50.831203768 +0200
|
||||
+++ qtbase-opensource-src-5.9.0/src/plugins/sqldrivers/mysql/qsql_mysql_p.h 2017-07-14 13:44:24.364948006 +0200
|
||||
@@ -58,6 +58,7 @@
|
||||
#endif
|
||||
|
||||
#include <mysql.h>
|
||||
+#include <mysql_version.h>
|
||||
|
||||
#ifdef QT_PLUGIN
|
||||
#define Q_EXPORT_SQLDRIVER_MYSQL
|
@ -1,12 +0,0 @@
|
||||
diff -up qtbase-everywhere-src-5.10.1/qmake/Makefile.unix.qmake_LFLAGS qtbase-everywhere-src-5.10.1/qmake/Makefile.unix
|
||||
--- qtbase-everywhere-src-5.10.1/qmake/Makefile.unix.qmake_LFLAGS 2018-02-08 12:24:48.000000000 -0600
|
||||
+++ qtbase-everywhere-src-5.10.1/qmake/Makefile.unix 2018-02-15 10:25:07.077763061 -0600
|
||||
@@ -142,7 +142,7 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \
|
||||
-DQT_NO_FOREACH
|
||||
|
||||
CXXFLAGS = $(EXTRA_CXXFLAGS) $(CONFIG_CXXFLAGS) $(CPPFLAGS)
|
||||
-LFLAGS = $(EXTRA_LFLAGS) $(CONFIG_LFLAGS)
|
||||
+LFLAGS = $(EXTRA_LFLAGS) $(CONFIG_LFLAGS) $(QMAKE_LFLAGS_RELEASE)
|
||||
|
||||
first all: $(BUILD_PATH)/bin/qmake$(EXEEXT)
|
||||
qmake: $(BUILD_PATH)/bin/qmake$(EXEEXT)
|
@ -1,3 +0,0 @@
|
||||
[Rules]
|
||||
*.debug=false
|
||||
qt.qpa.xcb.xcberror.warning=false
|
@ -1,16 +0,0 @@
|
||||
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
|
||||
index e6a0d97..cf93041 100644
|
||||
--- a/mkspecs/features/qt_module.prf
|
||||
+++ b/mkspecs/features/qt_module.prf
|
||||
@@ -216,9 +216,9 @@ android: CONFIG += qt_android_deps no_linker_version_script
|
||||
QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript
|
||||
|
||||
internal_module {
|
||||
- verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API { *; };"
|
||||
+ verscript_content = "Qt_$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}_PRIVATE_API { *; };"
|
||||
} else {
|
||||
- verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API {" \
|
||||
+ verscript_content = "Qt_$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}_PRIVATE_API {" \
|
||||
" qt_private_api_tag*;"
|
||||
|
||||
private_api_headers = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.QPA_HEADER_FILES
|
File diff suppressed because it is too large
Load Diff
1
dead.package
Normal file
1
dead.package
Normal file
@ -0,0 +1 @@
|
||||
qt5-qtbase was removed due to minimization efforts prior to public launch
|
Loading…
Reference in New Issue
Block a user