From 9f0c48c6b14dc8737fe2563a7e800a7329517db5 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 22 Jul 2024 19:25:24 +0200 Subject: [PATCH] xcb: ignore bigger size window icon when size exceeds limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the absence of the BIG-REQUESTS extension, the maximum request length is only 65535, with DPR=2, a 128*128 icon size will be (128*2)^2 = 65536, which exceeds the maximum request length. See also the official doc for xcb_get_maximum_request_length. https://xcb.freedesktop.org/manual/group__XCB__Core__API.html uint32_t xcb_get_maximum_request_length(xcb_connection_t *c) In the absence of the BIG-REQUESTS extension, returns the maximum request length field from the connection setup data, which may be as much as 65535. If the server supports BIG-REQUESTS, then the maximum request length field from the reply to the BigRequestsEnable request will be returned instead. Note that this length is measured in four-byte units, making the theoretical maximum lengths roughly 256kB without BIG-REQUESTS and 16GB with. Fixes: QTBUG-127392 Pick-to: 6.7 6.5 6.2 5.15 Change-Id: Iee53f579802e8bc54ed1519bc5b5591b5e5700e1 Reviewed-by: Jøger Hansegård Reviewed-by: Liang Qi (cherry picked from commit 0ed5d4d674c241f7affa3b87feb948c26e11d5cc) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/platforms/xcb/qxcbwindow.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 2345cb0ab88..007837ebf5e 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1348,6 +1348,7 @@ void QXcbWindow::setWindowIconText(const QString &title) void QXcbWindow::setWindowIcon(const QIcon &icon) { QList icon_data; + const uint32_t sizeLimit = xcb_get_maximum_request_length(xcb_connection()); if (!icon.isNull()) { QList availableSizes = icon.availableSizes(); if (availableSizes.isEmpty()) { @@ -1363,7 +1364,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon) if (!pixmap.isNull()) { QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); int pos = icon_data.size(); - icon_data.resize(pos + 2 + image.width()*image.height()); + int newSize = pos + 2 + image.width()*image.height(); + // In the absence of the BIG-REQUESTS extension, or with too big DPR, + // the size of icon data is too big for the xcb request very easily. + if (quint64(newSize) > quint64(sizeLimit)) + break; + icon_data.resize(newSize); icon_data[pos++] = image.width(); icon_data[pos++] = image.height(); memcpy(icon_data.data() + pos, image.bits(), image.width()*image.height()*4); @@ -1373,10 +1379,10 @@ void QXcbWindow::setWindowIcon(const QIcon &icon) if (!icon_data.isEmpty()) { // Ignore icon exceeding maximum xcb request length - if (quint64(icon_data.size()) > quint64(xcb_get_maximum_request_length(xcb_connection()))) { + if (quint64(icon_data.size()) > quint64(sizeLimit)) { qWarning() << "Ignoring window icon" << icon_data.size() << "exceeds maximum xcb request length" - << xcb_get_maximum_request_length(xcb_connection()); + << sizeLimit; return; } xcb_change_property(xcb_connection(),