Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package qt6-websockets for openSUSE:Factory
checked in at 2026-10-18 19:21:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/qt6-websockets (Old)
and /work/SRC/openSUSE:Factory/.qt6-websockets.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qt6-websockets"
Sun Oct 18 19:21:46 2026 rev:37 rq:1384423 version:6.12.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/qt6-websockets/qt6-websockets.changes
2026-08-21 16:52:51.959999577 +0200
+++
/work/SRC/openSUSE:Factory/.qt6-websockets.new.3698736/qt6-websockets.changes
2026-10-18 19:22:02.949589091 +0200
@@ -1,0 +2,6 @@
+Wed Sep 30 16:15:38 UTC 2026 - Christophe Marin <[email protected]>
+
+- Update to 6.12.0
+ https://www.qt.io/blog/qt-6.12-released
+
+-------------------------------------------------------------------
Old:
----
qtwebsockets-everywhere-src-6.11.2.tar.xz
New:
----
qtwebsockets-everywhere-src-6.12.0.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ qt6-websockets.spec ++++++
--- /var/tmp/diff_new_pack.jJauIB/_old 2026-10-18 19:22:04.406649498 +0200
+++ /var/tmp/diff_new_pack.jJauIB/_new 2026-10-18 19:22:04.411649705 +0200
@@ -16,8 +16,8 @@
#
-%define real_version 6.11.2
-%define short_version 6.11
+%define real_version 6.12.0
+%define short_version 6.12
%define tar_name qtwebsockets-everywhere-src
%define tar_suffix %{nil}
#
@@ -27,7 +27,7 @@
%endif
#
Name: qt6-websockets%{?pkg_suffix}
-Version: 6.11.2
+Version: 6.12.0
Release: 0
Summary: Qt 6 WebSockets library
License: GPL-2.0-only OR GPL-3.0-or-later OR LGPL-3.0-only
++++++ qtwebsockets-everywhere-src-6.11.2.tar.xz ->
qtwebsockets-everywhere-src-6.12.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/qtwebsockets-everywhere-src-6.11.2/.cmake.conf
new/qtwebsockets-everywhere-src-6.12.0/.cmake.conf
--- old/qtwebsockets-everywhere-src-6.11.2/.cmake.conf 2026-08-12
03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/.cmake.conf 2026-09-27
10:15:31.000000000 +0200
@@ -1,4 +1,4 @@
-set(QT_REPO_MODULE_VERSION "6.11.2")
+set(QT_REPO_MODULE_VERSION "6.12.0")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
set(QT_EXTRA_INTERNAL_TARGET_DEFINES
"QT_NO_CONTEXTLESS_CONNECT=1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/qtwebsockets-everywhere-src-6.11.2/.tag
new/qtwebsockets-everywhere-src-6.12.0/.tag
--- old/qtwebsockets-everywhere-src-6.11.2/.tag 2026-08-12 03:33:36.000000000
+0200
+++ new/qtwebsockets-everywhere-src-6.12.0/.tag 2026-09-27 10:15:31.000000000
+0200
@@ -1 +1 @@
-3eab06de7076a83514e98c2403baa433d137b013
+6aedb199b5d8ee4afa4cfc956ded22bc0a2632e9
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/qtwebsockets-everywhere-src-6.11.2/CONTRIBUTING.md
new/qtwebsockets-everywhere-src-6.12.0/CONTRIBUTING.md
--- old/qtwebsockets-everywhere-src-6.11.2/CONTRIBUTING.md 1970-01-01
01:00:00.000000000 +0100
+++ new/qtwebsockets-everywhere-src-6.12.0/CONTRIBUTING.md 2026-09-27
10:15:31.000000000 +0200
@@ -0,0 +1,11 @@
+## Qt contribution guidelines
+
+We welcome contributions to Qt!
+
+Note that we cannot accept pull requests on GitHub. All contributions
+to the Qt project are exclusively handled through the
+[Gerrit code review system](https://codereview.qt-project.org).
+
+See
+[contribute.qt-project.org](https://contribute.qt-project.org/) to learn
+more.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/qtwebsockets-everywhere-src-6.11.2/REUSE.toml
new/qtwebsockets-everywhere-src-6.12.0/REUSE.toml
--- old/qtwebsockets-everywhere-src-6.11.2/REUSE.toml 2026-08-12
03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/REUSE.toml 2026-09-27
10:15:31.000000000 +0200
@@ -36,7 +36,7 @@
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
[[annotations]]
-path = ["**/doc/images/**", "**/README*", "**.qdocconf"]
+path = ["**/doc/images/**", "**/README*", "**.qdocconf", "CONTRIBUTING.md"]
comment = "documentation"
precedence = "closest"
SPDX-FileCopyrightText = "Copyright (C) The Qt Company Ltd."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/qtwebsockets-everywhere-src-6.11.2/dependencies.yaml
new/qtwebsockets-everywhere-src-6.12.0/dependencies.yaml
--- old/qtwebsockets-everywhere-src-6.11.2/dependencies.yaml 2026-08-12
03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/dependencies.yaml 2026-09-27
10:15:31.000000000 +0200
@@ -1,7 +1,7 @@
dependencies:
../qtbase:
- ref: ef55f427f2c8b410d34f8a7681020a3000cf6866
+ ref: 025bdad181de241e81bf853c8a2d7bf3d19261a9
required: true
../qtdeclarative:
- ref: 4e3399c26ec57246c08de019cfcbda8d23604cfa
+ ref: 4332fbbb4c340463dc8cee36dda0c85d932122d8
required: false
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/qtwebsockets-everywhere-src-6.11.2/licenseRule.json
new/qtwebsockets-everywhere-src-6.12.0/licenseRule.json
--- old/qtwebsockets-everywhere-src-6.11.2/licenseRule.json 2026-08-12
03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/licenseRule.json 2026-09-27
10:15:31.000000000 +0200
@@ -59,7 +59,7 @@
{
"comment": "Files with the following endings are Documentation
licensed.",
"file_pattern_ending": [".qdoc", ".qdocinc" , ".qdocconf", "README",
"qt_attribution.json",
- "README.md"],
+ "README.md", "CONTRIBUTING.md"],
"location":{
"": {
"comment": "",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qmaskgenerator.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qmaskgenerator.h
--- old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qmaskgenerator.h
2026-08-12 03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qmaskgenerator.h
2026-09-27 10:15:31.000000000 +0200
@@ -6,7 +6,7 @@
#define QMASKGENERATOR_H
#include <QtCore/QObject>
-#include "QtWebSockets/qwebsockets_global.h"
+#include <QtWebSockets/qwebsockets_global.h>
QT_BEGIN_NAMESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocket.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocket.h
--- old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocket.h
2026-08-12 03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocket.h
2026-09-27 10:15:31.000000000 +0200
@@ -15,8 +15,8 @@
#include <QtNetwork/QSslError>
#include <QtNetwork/QSslConfiguration>
#endif
-#include "QtWebSockets/qwebsockets_global.h"
-#include "QtWebSockets/qwebsocketprotocol.h"
+#include <QtWebSockets/qwebsockets_global.h>
+#include <QtWebSockets/qwebsocketprotocol.h>
#include <QtCore/qobject.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocket_p.cpp
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocket_p.cpp
--- old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocket_p.cpp
2026-08-12 03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocket_p.cpp
2026-09-27 10:15:31.000000000 +0200
@@ -389,54 +389,7 @@
*/
void QWebSocketPrivate::close(QWebSocketProtocol::CloseCode closeCode, QString
reason)
{
- if (Q_UNLIKELY(!m_pSocket))
- return;
- Q_Q(QWebSocket);
- if (!m_isClosingHandshakeSent) {
- m_closeCode = closeCode;
- // 125 is the maximum length of a control frame, and 2 bytes are used
for the close code:
- const QByteArray reasonUtf8 = reason.toUtf8().left(123);
- m_closeReason = QString::fromUtf8(reasonUtf8);
- const quint16 code = qToBigEndian<quint16>(closeCode);
- QByteArray payload;
- payload.append(static_cast<const char *>(static_cast<const void
*>(&code)), 2);
- if (!reasonUtf8.isEmpty())
- payload.append(reasonUtf8);
- quint32 maskingKey = 0;
- if (m_mustMask) {
- maskingKey = generateMaskingKey();
- QWebSocketProtocol::mask(payload.data(), quint64(payload.size()),
maskingKey);
- }
- QByteArray frame = getFrameHeader(QWebSocketProtocol::OpCodeClose,
- quint64(payload.size()), maskingKey,
true);
-
- Q_ASSERT(payload.size() <= 125);
- frame.append(payload);
- m_pSocket->write(frame);
- m_pSocket->flush();
-
- m_isClosingHandshakeSent = true;
-
- Q_EMIT q->aboutToClose();
- }
- static constexpr auto closeTimerName = "_closeTimer"_L1;
- if (!m_isClosingHandshakeReceived) {
- QTimer *closeTimer = new QTimer(q);
- closeTimer->setObjectName(closeTimerName);
- closeTimer->setInterval(3000);
- closeTimer->setSingleShot(true);
- QObject::connect(q, &QWebSocket::disconnected, closeTimer,
&QTimer::stop);
- QObject::connect(q, &QWebSocket::disconnected, closeTimer,
&QTimer::deleteLater);
- QObject::connect(closeTimer, &QTimer::timeout, m_pSocket,
&QTcpSocket::close);
- QObject::connect(closeTimer, &QTimer::timeout, closeTimer,
&QTimer::deleteLater);
- closeTimer->start();
- } else {
- m_pSocket->close();
- if (QTimer *closeTimer = q->findChild<QTimer *>(closeTimerName)) {
- closeTimer->stop();
- delete closeTimer;
- }
- }
+ doClose(closeCode, reason, false);
}
/*!
@@ -721,7 +674,7 @@
QObject::connect(m_dataProcessor,
&QWebSocketDataProcessor::textMessageReceived, q,
&QWebSocket::textMessageReceived);
QObjectPrivate::connect(m_dataProcessor,
&QWebSocketDataProcessor::errorEncountered, this,
- &QWebSocketPrivate::close);
+ &QWebSocketPrivate::processError);
QObjectPrivate::connect(m_dataProcessor,
&QWebSocketDataProcessor::pingReceived, this,
&QWebSocketPrivate::processPing);
QObjectPrivate::connect(m_dataProcessor,
&QWebSocketDataProcessor::pongReceived, this,
@@ -1348,6 +1301,71 @@
}
}
+/*!
+ \internal
+
+ Sends the Close frame and then either closes the connection or waits for
the
+ peer to do so. \a isFailed tells whether we are failing the connection as
+ described in RFC 6455 paragraph 7.1.7, in which case the transport is
closed
+ right away instead.
+ */
+void QWebSocketPrivate::doClose(QWebSocketProtocol::CloseCode closeCode,
+ QString reason, bool isFailed)
+{
+ if (Q_UNLIKELY(!m_pSocket))
+ return;
+ Q_Q(QWebSocket);
+ if (!m_isClosingHandshakeSent) {
+ m_closeCode = closeCode;
+ // 125 is the maximum length of a control frame, and 2 bytes are used
for the close code:
+ const QByteArray reasonUtf8 = reason.toUtf8().left(123);
+ m_closeReason = QString::fromUtf8(reasonUtf8);
+ const quint16 code = qToBigEndian<quint16>(closeCode);
+ QByteArray payload;
+ payload.append(static_cast<const char *>(static_cast<const void
*>(&code)), 2);
+ if (!reasonUtf8.isEmpty())
+ payload.append(reasonUtf8);
+ quint32 maskingKey = 0;
+ if (m_mustMask) {
+ maskingKey = generateMaskingKey();
+ QWebSocketProtocol::mask(payload.data(), quint64(payload.size()),
maskingKey);
+ }
+ QByteArray frame = getFrameHeader(QWebSocketProtocol::OpCodeClose,
+ quint64(payload.size()), maskingKey,
true);
+
+ Q_ASSERT(payload.size() <= 125);
+ frame.append(payload);
+ m_pSocket->write(frame);
+ m_pSocket->flush();
+
+ m_isClosingHandshakeSent = true;
+
+ Q_EMIT q->aboutToClose();
+ }
+
+ static constexpr auto closeTimerName = "_closeTimer"_L1;
+ const bool waitForPeer = !m_isClosingHandshakeReceived && !isFailed;
+ if (waitForPeer) {
+ if (q->findChild<QTimer *>(closeTimerName))
+ return;
+ QTimer *closeTimer = new QTimer(q);
+ closeTimer->setObjectName(closeTimerName);
+ closeTimer->setInterval(3000);
+ closeTimer->setSingleShot(true);
+ QObject::connect(q, &QWebSocket::disconnected, closeTimer,
&QTimer::stop);
+ QObject::connect(q, &QWebSocket::disconnected, closeTimer,
&QTimer::deleteLater);
+ QObject::connect(closeTimer, &QTimer::timeout, m_pSocket,
&QTcpSocket::close);
+ QObject::connect(closeTimer, &QTimer::timeout, closeTimer,
&QTimer::deleteLater);
+ closeTimer->start();
+ } else {
+ m_pSocket->close();
+ if (QTimer *closeTimer = q->findChild<QTimer *>(closeTimerName)) {
+ closeTimer->stop();
+ delete closeTimer;
+ }
+ }
+}
+
void QWebSocketPrivate::socketDestroyed(QObject *socket)
{
Q_ASSERT(m_pSocket);
@@ -1418,6 +1436,18 @@
}
/*!
+ \internal
+
+ Fails the connection as described in RFC 6455 paragraph 7.1.7: send a Close
+ frame, then close the connection straight away. No reply can be processed
+ afterwards, so neither endpoint has anything to wait for.
+ */
+void QWebSocketPrivate::processError(QWebSocketProtocol::CloseCode closeCode,
QString reason)
+{
+ doClose(closeCode, reason, true);
+}
+
+/*!
\internal
*/
QString QWebSocketPrivate::createHandShakeRequest(QString resourceName,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocket_p.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocket_p.h
--- old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocket_p.h
2026-08-12 03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocket_p.h
2026-09-27 10:15:31.000000000 +0200
@@ -167,9 +167,12 @@
void processPing(const QByteArray &data);
void processPong(const QByteArray &data);
void processClose(QWebSocketProtocol::CloseCode closeCode, QString
closeReason);
+ void processError(QWebSocketProtocol::CloseCode closeCode, QString reason);
void processHandshake(QTcpSocket *pSocket);
void processStateChanged(QAbstractSocket::SocketState socketState);
+ void doClose(QWebSocketProtocol::CloseCode closeCode, QString reason, bool
isFailed);
+
Q_REQUIRED_RESULT qint64 doWriteFrames(const QByteArray &data, bool
isBinary);
void makeConnections(QTcpSocket *pTcpSocket);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketcorsauthenticator.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketcorsauthenticator.h
---
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketcorsauthenticator.h
2026-08-12 03:33:36.000000000 +0200
+++
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketcorsauthenticator.h
2026-09-27 10:15:31.000000000 +0200
@@ -4,7 +4,7 @@
#ifndef QWEBSOCKETCORSAUTHENTICATOR_H
#define QWEBSOCKETCORSAUTHENTICATOR_H
-#include "QtWebSockets/qwebsockets_global.h"
+#include <QtWebSockets/qwebsockets_global.h>
#include <memory>
QT_BEGIN_NAMESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketdataprocessor.cpp
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketdataprocessor.cpp
---
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketdataprocessor.cpp
2026-08-12 03:33:36.000000000 +0200
+++
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketdataprocessor.cpp
2026-09-27 10:15:31.000000000 +0200
@@ -134,6 +134,9 @@
*/
bool QWebSocketDataProcessor::process(QIODevice *pIoDevice)
{
+ if (Q_UNLIKELY(m_hasFailed))
+ return false;
+
bool isDone = false;
while (!isDone) {
@@ -150,19 +153,17 @@
} else {
//we have a dataframe; opcode can be OC_CONTINUE, OC_TEXT or
OC_BINARY
if (Q_UNLIKELY(!m_isFragmented &&
frame.isContinuationFrame())) {
- clear();
- Q_EMIT
errorEncountered(QWebSocketProtocol::CloseCodeProtocolError,
- tr("Received Continuation frame,
while there is " \
- "nothing to continue."));
- return true;
+ reportError(QWebSocketProtocol::CloseCodeProtocolError,
+ tr("Received Continuation frame, while there
is " \
+ "nothing to continue."));
+ return false;
}
if (Q_UNLIKELY(m_isFragmented && frame.isDataFrame() &&
!frame.isContinuationFrame())) {
- clear();
- Q_EMIT
errorEncountered(QWebSocketProtocol::CloseCodeProtocolError,
- tr("All data frames after the
initial data frame " \
- "must have opcode 0
(continuation)."));
- return true;
+ reportError(QWebSocketProtocol::CloseCodeProtocolError,
+ tr("All data frames after the initial data
frame " \
+ "must have opcode 0 (continuation)."));
+ return false;
}
if (!frame.isContinuationFrame()) {
m_opCode = frame.opCode();
@@ -173,10 +174,9 @@
: quint64(m_binaryMessage.size());
if (Q_UNLIKELY((messageLength +
quint64(frame.payload().size())) >
maxAllowedMessageSize())) {
- clear();
- Q_EMIT
errorEncountered(QWebSocketProtocol::CloseCodeTooMuchData,
- tr("Received message is too
big."));
- return true;
+ reportError(QWebSocketProtocol::CloseCodeTooMuchData,
+ tr("Received message is too big."));
+ return false;
}
bool isFinalFrame = frame.isFinalFrame();
@@ -188,10 +188,9 @@
decoderHadError = r.error !=
QStringDecoder::FinalizeResult::Error::NoError;
}
if (Q_UNLIKELY(decoderHadError)) {
- clear();
- Q_EMIT
errorEncountered(QWebSocketProtocol::CloseCodeWrongDatatype,
- tr("Invalid UTF-8 code
encountered."));
- return true;
+ reportError(QWebSocketProtocol::CloseCodeWrongDatatype,
+ tr("Invalid UTF-8 code encountered."));
+ return false;
} else {
m_textMessage.append(frameTxt);
frame.clear();
@@ -218,9 +217,8 @@
}
}
} else {
- Q_EMIT errorEncountered(frame.closeCode(), frame.closeReason());
- clear();
- isDone = true;
+ reportError(frame.closeCode(), frame.closeReason());
+ return false;
}
frame.clear();
}
@@ -242,11 +240,26 @@
m_textMessage.clear();
m_payloadLength = 0;
m_decoder.resetState();
+ m_hasFailed = false;
frame.clear();
}
/*!
\internal
+
+ Reports a protocol violation and marks the connection as failed, so that no
+ further data is parsed after the error.
+ */
+void QWebSocketDataProcessor::reportError(QWebSocketProtocol::CloseCode code,
+ const QString &description)
+{
+ clear();
+ m_hasFailed = true;
+ Q_EMIT errorEncountered(code, description);
+}
+
+/*!
+ \internal
*/
bool QWebSocketDataProcessor::processControlFrame(const QWebSocketFrame &frame)
{
@@ -323,9 +336,8 @@
*/
void QWebSocketDataProcessor::timeout()
{
- clear();
- Q_EMIT errorEncountered(QWebSocketProtocol::CloseCodeGoingAway,
- tr("Timeout when reading data from socket."));
+ reportError(QWebSocketProtocol::CloseCodeGoingAway,
+ tr("Timeout when reading data from socket."));
}
QT_END_NAMESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketdataprocessor_p.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketdataprocessor_p.h
---
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketdataprocessor_p.h
2026-08-12 03:33:36.000000000 +0200
+++
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketdataprocessor_p.h
2026-09-27 10:15:31.000000000 +0200
@@ -89,8 +89,10 @@
QWebSocketFrame frame;
QChronoTimer *m_waitTimer;
quint64 m_maxAllowedMessageSize = MAX_MESSAGE_SIZE_IN_BYTES;
+ bool m_hasFailed = false;
bool processControlFrame(const QWebSocketFrame &frame);
+ void reportError(QWebSocketProtocol::CloseCode code, const QString
&description);
void timeout();
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsockethandshakeoptions.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsockethandshakeoptions.h
---
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsockethandshakeoptions.h
2026-08-12 03:33:36.000000000 +0200
+++
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsockethandshakeoptions.h
2026-09-27 10:15:31.000000000 +0200
@@ -8,7 +8,7 @@
#include <QtCore/QSharedDataPointer>
#include <QtCore/QStringList>
-#include "QtWebSockets/qwebsockets_global.h"
+#include <QtWebSockets/qwebsockets_global.h>
QT_BEGIN_NAMESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketprotocol.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketprotocol.h
--- old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketprotocol.h
2026-08-12 03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketprotocol.h
2026-09-27 10:15:31.000000000 +0200
@@ -10,7 +10,7 @@
#endif
#include <QtCore/qglobal.h>
-#include "QtWebSockets/qwebsockets_global.h"
+#include <QtWebSockets/qwebsockets_global.h>
QT_BEGIN_NAMESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketserver.h
new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketserver.h
--- old/qtwebsockets-everywhere-src-6.11.2/src/websockets/qwebsocketserver.h
2026-08-12 03:33:36.000000000 +0200
+++ new/qtwebsockets-everywhere-src-6.12.0/src/websockets/qwebsocketserver.h
2026-09-27 10:15:31.000000000 +0200
@@ -5,8 +5,8 @@
#ifndef QWEBSOCKETSERVER_H
#define QWEBSOCKETSERVER_H
-#include "QtWebSockets/qwebsockets_global.h"
-#include "QtWebSockets/qwebsocketprotocol.h"
+#include <QtWebSockets/qwebsockets_global.h>
+#include <QtWebSockets/qwebsocketprotocol.h>
#include <QtCore/QObject>
#include <QtCore/QString>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwebsockets-everywhere-src-6.11.2/tests/auto/websockets/dataprocessor/tst_dataprocessor.cpp
new/qtwebsockets-everywhere-src-6.12.0/tests/auto/websockets/dataprocessor/tst_dataprocessor.cpp
---
old/qtwebsockets-everywhere-src-6.11.2/tests/auto/websockets/dataprocessor/tst_dataprocessor.cpp
2026-08-12 03:33:36.000000000 +0200
+++
new/qtwebsockets-everywhere-src-6.12.0/tests/auto/websockets/dataprocessor/tst_dataprocessor.cpp
2026-09-27 10:15:31.000000000 +0200
@@ -13,7 +13,7 @@
const quint8 FIN = 0x80;
const quint8 RSV1 = 0x40;
-const quint8 RSV2 = 0x30;
+const quint8 RSV2 = 0x20;
const quint8 RSV3 = 0x10;
QT_USE_NAMESPACE
@@ -153,6 +153,19 @@
void clearDataBuffers(); // qtbug-55506
+ /*!
+ Tests that QWebSocketDataProcessor stops handling a connection once it
has
+ reported an error. RFC 6455 requires the connection to be failed on a
+ protocol violation (paragraphs 5.2 and 8.1) and forbids processing any
+ further data from the peer afterwards (paragraph 7.1.7), including bytes
+ already received (paragraph 7.1.1). The same handling is applied to frame
+ sequences that do not match the fragmentation rules of paragraph 5.4 and
+ to messages exceeding the configured limit.
+ */
+ void stopProcessingOnError();
+ void stopProcessingOnError_data();
+ void stopProcessingOnTimeout();
+
private:
//helper function that constructs a new row of test data for invalid UTF8
sequences
void invalidUTF8(const char *dataTag, const char *utf8Sequence, bool
isCloseFrame);
@@ -747,6 +760,7 @@
binaryFrameSpy.clear();
buffer.close();
data.clear();
+ dataProcessor.clear();
//only one byte; this is far too little;
//should get a time out as well and the error should be CloseCodeGoingAway
@@ -780,6 +794,7 @@
textFrameSpy.clear();
binaryFrameSpy.clear();
data.clear();
+ dataProcessor.clear();
{
@@ -810,6 +825,7 @@
binaryFrameSpy.clear();
buffer.close();
data.clear();
+ dataProcessor.clear();
//with nothing in the buffer,
//the dataProcessor should time out and the error should be
CloseCodeGoingAway
@@ -841,6 +857,7 @@
binaryFrameSpy.clear();
buffer.close();
data.clear();
+ dataProcessor.clear();
//text frame with final bit not set
data.append(char(QWebSocketProtocol::OpCodeText)).append(char(0x0));
@@ -860,6 +877,7 @@
buffer.close();
data.clear();
+ dataProcessor.clear();
errorSpy.clear();
closeSpy.clear();
@@ -1879,6 +1897,166 @@
QTest::qWait(2000);
}
+void tst_DataProcessor::stopProcessingOnError_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<QWebSocketProtocol::CloseCode>("expectedCloseCode");
+ // frames legitimately delivered before the violation is detected
+ QTest::addColumn<int>("expectedTextFrames");
+ // zero leaves the default limit in place
+ QTest::addColumn<quint64>("maxMessageSize");
+
+ // the well formed frame trailing most rows; it must never be delivered
+ QByteArray textFrame;
+ textFrame.append(char(FIN | QWebSocketProtocol::OpCodeText));
+ textFrame.append(char(5));
+ textFrame.append("hello");
+
+ // Ensure a continuation frame that has no message to continue is rejected,
+ // and that the text frame behind it is not delivered.
+ QByteArray strayContinuation;
+ strayContinuation.append(char(FIN | QWebSocketProtocol::OpCodeContinue));
+ strayContinuation.append(char(0));
+ QTest::newRow("stray continuation frame")
+ << strayContinuation + textFrame <<
QWebSocketProtocol::CloseCodeProtocolError
+ << 0 << quint64(0);
+
+ // Ensure a frame rejected on its header does not leak the payload it
+ // announced.
+ QByteArray rsv1Frame;
+ rsv1Frame.append(char(FIN | RSV1 | QWebSocketProtocol::OpCodeText));
+ rsv1Frame.append(char(textFrame.size()));
+ QTest::newRow("rsv1 set, announced payload is a frame")
+ << rsv1Frame + textFrame <<
QWebSocketProtocol::CloseCodeProtocolError
+ << 0 << quint64(0);
+
+ // Ensure a payload that fails UTF-8 validation stops processing.
+ QByteArray invalidUtf8Frame;
+ invalidUtf8Frame.append(char(FIN | QWebSocketProtocol::OpCodeText));
+ invalidUtf8Frame.append(char(1));
+ invalidUtf8Frame.append(char(0xFF));
+ QTest::newRow("invalid utf-8")
+ << invalidUtf8Frame + textFrame <<
QWebSocketProtocol::CloseCodeWrongDatatype
+ << 0 << quint64(0);
+
+ // Ensure a data frame arriving mid-fragmentation is rejected: once a
message
+ // is fragmented, the frames that follow must use opcode 0.
+ QByteArray firstFragment;
+ firstFragment.append(char(QWebSocketProtocol::OpCodeText));
+ firstFragment.append(char(1));
+ firstFragment.append("a");
+ QByteArray secondDataFrame;
+ secondDataFrame.append(char(FIN | QWebSocketProtocol::OpCodeText));
+ secondDataFrame.append(char(1));
+ secondDataFrame.append("b");
+ QTest::newRow("data frame during a fragmented message")
+ << firstFragment + secondDataFrame + textFrame
+ << QWebSocketProtocol::CloseCodeProtocolError << 1 << quint64(0);
+
+ // Ensure even the peer's Close frame is ignored after a failure.
+ QByteArray closeFrame;
+ closeFrame.append(char(FIN | QWebSocketProtocol::OpCodeClose));
+ closeFrame.append(char(2));
+ closeFrame.append(char(0x03));
+ closeFrame.append(char(0xE8));
+ QTest::newRow("close frame after the violation")
+ << strayContinuation + closeFrame <<
QWebSocketProtocol::CloseCodeProtocolError
+ << 0 << quint64(0);
+
+ // Ensure exceeding the configured message limit stops processing.
+ QTest::newRow("message too big")
+ << textFrame + textFrame <<
QWebSocketProtocol::CloseCodeTooMuchData
+ << 0 << quint64(4);
+}
+
+void tst_DataProcessor::stopProcessingOnError()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(QWebSocketProtocol::CloseCode, expectedCloseCode);
+ QFETCH(int, expectedTextFrames);
+ QFETCH(quint64, maxMessageSize);
+
+ QWebSocketDataProcessor dataProcessor;
+ dataProcessor.setIdleTimeout(DefaultIdleTimeout);
+ if (maxMessageSize)
+ dataProcessor.setMaxAllowedMessageSize(maxMessageSize);
+
+ QSignalSpy errorSpy(&dataProcessor,
&QWebSocketDataProcessor::errorEncountered);
+ QSignalSpy textFrameSpy(&dataProcessor,
&QWebSocketDataProcessor::textFrameReceived);
+ QSignalSpy textMessageSpy(&dataProcessor,
&QWebSocketDataProcessor::textMessageReceived);
+ QSignalSpy closeSpy(&dataProcessor,
&QWebSocketDataProcessor::closeReceived);
+
+ QBuffer buffer;
+ buffer.setData(data);
+ buffer.open(QIODevice::ReadOnly);
+
+ // the violating frame is followed by a well-formed text frame in the same
+ // buffer; processing must stop at the violation
+ QVERIFY(!dataProcessor.process(&buffer));
+ QCOMPARE(errorSpy.size(), 1);
+ QCOMPARE(errorSpy.first().at(0).value<QWebSocketProtocol::CloseCode>(),
expectedCloseCode);
+ QCOMPARE(textFrameSpy.size(), expectedTextFrames);
+ QCOMPARE(textMessageSpy.size(), 0);
+
+ // no further data is parsed for a connection that has failed
+ QVERIFY(!dataProcessor.process(&buffer));
+ QCOMPARE(errorSpy.size(), 1);
+ QCOMPARE(textFrameSpy.size(), expectedTextFrames);
+ QCOMPARE(textMessageSpy.size(), 0);
+ QCOMPARE(closeSpy.size(), 0);
+ buffer.close();
+
+ // ensure processor is usable again after clear()
+ dataProcessor.clear();
+ QByteArray goodFrame;
+ goodFrame.append(char(FIN | QWebSocketProtocol::OpCodeText));
+ goodFrame.append(char(2));
+ goodFrame.append("ok");
+ QBuffer reopened;
+ reopened.setData(goodFrame);
+ reopened.open(QIODevice::ReadOnly);
+ QVERIFY(dataProcessor.process(&reopened));
+ QCOMPARE(textMessageSpy.size(), 1);
+ QCOMPARE(textMessageSpy.first().at(0).toString(), QStringLiteral("ok"));
+}
+
+void tst_DataProcessor::stopProcessingOnTimeout()
+{
+ QWebSocketDataProcessor dataProcessor;
+ dataProcessor.setIdleTimeout(DefaultIdleTimeout);
+
+ QSignalSpy errorSpy(&dataProcessor,
&QWebSocketDataProcessor::errorEncountered);
+ QSignalSpy textMessageSpy(&dataProcessor,
&QWebSocketDataProcessor::textMessageReceived);
+
+ // a header announcing a 7 byte payload, with no payload yet
+ QByteArray header;
+ header.append(char(FIN | QWebSocketProtocol::OpCodeText));
+ header.append(char(7));
+
+ QBuffer buffer;
+ buffer.setData(header);
+ buffer.open(QIODevice::ReadOnly);
+ QVERIFY(!dataProcessor.process(&buffer));
+ buffer.close();
+
+ QTRY_VERIFY_WITH_TIMEOUT(errorSpy.size(), 7000);
+ QCOMPARE(errorSpy.size(), 1);
+ QCOMPARE(errorSpy.first().at(0).value<QWebSocketProtocol::CloseCode>(),
+ QWebSocketProtocol::CloseCodeGoingAway);
+
+ // the announced payload finally arrives; it must not be parsed as a frame
+ QByteArray payload;
+ payload.append(char(FIN | QWebSocketProtocol::OpCodeText));
+ payload.append(char(5));
+ payload.append("hello");
+
+ QBuffer resumed;
+ resumed.setData(payload);
+ resumed.open(QIODevice::ReadOnly);
+ QVERIFY(!dataProcessor.process(&resumed));
+ QCOMPARE(textMessageSpy.size(), 0);
+}
+
QTEST_MAIN(tst_DataProcessor)
#include "tst_dataprocessor.moc"