From d583030f2ca29dacce1805ad75855353f678f9d5 Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Thu, 2 Nov 2017 13:36:38 +0200 Subject: [PATCH 1/9] Add changes file for Qt 5.9.3 Task-number: QTBUG-64203 Change-Id: I1dd9ba9e96672a1e6d81ecbbd62f837bc0e34155 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- dist/changes-5.9.3 | 144 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 dist/changes-5.9.3 diff --git a/dist/changes-5.9.3 b/dist/changes-5.9.3 new file mode 100644 index 00000000000..521833dba0b --- /dev/null +++ b/dist/changes-5.9.3 @@ -0,0 +1,144 @@ +Qt 5.9.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0 through 5.9.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.3 Changes * +**************************************************************************** + +QtCore +------ + + - QFileSystemWatcher: + * [QTBUG-64171] Fixed a bug that would cause the application to crash if + QFileSystemWatcher was created in an auxiliary thread on Windows. + + - QStorageInfo: + * [QTBUG-61420] Fixed decoding of volume labels containing certain + uncommon characters on Linux. + + - QThreadPool: + * Improved performance with large amount of QRunnable items. + +QtGui +------ + + - [QTBUG-64239] Fixed memory corruption on scaled emojis. + - [QTBUG-63846] Fixed dragging inside a modal window when a + QShapedPixmapWindow is used. + - [QTBUG-61777] Fixed painting of zero-length lines with scaling. + - [QTBUG-61244] Fixed centering of some items in layouts. + - [QTBUG-63168] Fixed a crash when reparenting QWindowContainer. + + +QtNetwork +--------- + + - QHostAddress: + * [QTBUG-63764] Fixed a problem in QHostAddress not detaching in its + setters and thus spoiling shared data. + + - QNetworkAccessManager: + * [QTBUG-63075] Added support for HTTP status 308. + * [QTBUG-61300] Fixed a problem with mixing headers from different + responses. + * [QTBUG-63471] Fixed redirects support in HTTP/2 protocol handler. + * [QTBUG-63313] Fixed cookies received during a redirect not being + applied in the redirect. + * [QTBUG-63142] Fixed HTTP method always being changed to GET when + redirected with 307 and 308. + + - QNetworkCookieJar: + * Fixed cookies with a root path ("/") not matching an empty path (""). + +QtSql +------ + + - PostgreSQL: + * Fixed handling of binary data for PostgreSQL 9.x and later + * Fixed detection of PostgreSQL 9.x and later + + - OCI: + * [QTBUG-57765] Fixed a bug that would see some cached results returned + when issuing a forward only query + +QtWidgets +--------- + + - QAction: + * [QTBUG-62006] Ensured setData() does not emit changed() if no change + happened. + + - QDockWidget: + * [QTBUG-63526] Fixed an issue in QDockWidgets where the widget would + not resize despite showing a resize cursor. + + - QHeaderView: + * [QTBUG-54601] Fixed resizing when hidden sections were involved. + * [QTBUG-64036] Ensured maximumSectionSize property is honored during + resizeSections(). + + - QListView: + * [QTBUG-45427] Fixed the laying out of a QListView in a grid layout + after the dataChanged() signal is emitted. + + - QMenuBar + * [QTBUG-34160] Fixed a problem with adding the same QAction to more than + one menu. + + - QWidget + * [QTBUG-56860] Fixed widget losing focus after showing menu second time. + + - QWizard: + * [QTBUG-46894] Fixed the shortcut for the Next button on Windows. + + +Platform-specific changes +------------------------- + + - Cocoa: + * optimize backingstore flush on 10-bit displays + * [QTBUG-57076] [QTBUG-63712] Attach menu items when updating the menubar + * [QTBUG-63444] Toggle titlebar transparency to support unified toolbar + + - iOS: + * [QTBUG-57428][QTBUG-63660] add support for adding mimetypes other than text + on the clipboard + + - Windows: + * [QTBUG-63654] Windows font database: Remove clamping of default font size + + - X11: + * [QTBUG-48034] Don't misdetect certain trackballs as tablets + * [QTBUG-62840] Fix crash on X servers with BGR888 display + +Third-Party Code +---------------- + + - Improved documentation about Freetype 2 licenses. + - Updated Sqlite to fix CVE-2017-10989. + - Updated bundled libpng to version 1.6.34. + +Tools +----- + + * qmake: + - [QTBUG-63409] Fixed a build error with MSVC when concrt.h was included + while exceptions are disabled. + - [QTBUG-62985] Fixed a bug that caused the accidental creation of files + called "NUL" when using MinGW. From 4870282117b43242d9c2cd6fbde8175b2a907b08 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 9 Nov 2017 15:49:26 -0800 Subject: [PATCH 2/9] QSemaphore: fix regression when the timeout < 0 The issue was introduced by eaee1209f0ead5be786e81db8aee604ccfea85b0, so it affected only 5.9.2. [ChangeLog][QtCore][QSemaphore] Fixed a regression that would make tryAcquire() not to wait forever if the timeout was a negative value. Note: new code is advised to only use -1 to indicate "forever", as some other functions taking timeout periods do not accept other values. Task-number: QTBUG-64413 Change-Id: I57a1bd6e0c194530b732fffd14f58fce60d5dfc9 Reviewed-by: Lars Knoll --- src/corelib/thread/qsemaphore.cpp | 8 ++- .../thread/qsemaphore/tst_qsemaphore.cpp | 63 +++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp index ce0c1c91df4..f63a08774c3 100644 --- a/src/corelib/thread/qsemaphore.cpp +++ b/src/corelib/thread/qsemaphore.cpp @@ -214,13 +214,15 @@ bool QSemaphore::tryAcquire(int n) bool QSemaphore::tryAcquire(int n, int timeout) { Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative"); - if (timeout < 0) - return tryAcquire(n); + + // We're documented to accept any negative value as "forever" + // but QDeadlineTimer only accepts -1. + timeout = qMax(timeout, -1); QDeadlineTimer timer(timeout); QMutexLocker locker(&d->mutex); qint64 remainingTime = timer.remainingTime(); - while (n > d->avail && remainingTime > 0) { + while (n > d->avail && remainingTime != 0) { if (!d->cond.wait(locker.mutex(), remainingTime)) return false; remainingTime = timer.remainingTime(); diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp index 2970b2e118d..ce093f769c6 100644 --- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp @@ -41,6 +41,8 @@ private slots: void tryAcquireWithTimeout_data(); void tryAcquireWithTimeout(); void tryAcquireWithTimeoutStarvation(); + void tryAcquireWithTimeoutForever_data(); + void tryAcquireWithTimeoutForever(); void producerConsumer(); }; @@ -155,21 +157,25 @@ void tst_QSemaphore::tryAcquire() semaphore.release(); QCOMPARE(semaphore.available(), 1); QVERIFY(!semaphore.tryAcquire(2)); + QVERIFY(!semaphore.tryAcquire(2, 0)); QCOMPARE(semaphore.available(), 1); semaphore.release(); QCOMPARE(semaphore.available(), 2); QVERIFY(!semaphore.tryAcquire(3)); + QVERIFY(!semaphore.tryAcquire(3, 0)); QCOMPARE(semaphore.available(), 2); semaphore.release(10); QCOMPARE(semaphore.available(), 12); QVERIFY(!semaphore.tryAcquire(100)); + QVERIFY(!semaphore.tryAcquire(100, 0)); QCOMPARE(semaphore.available(), 12); semaphore.release(10); QCOMPARE(semaphore.available(), 22); QVERIFY(!semaphore.tryAcquire(100)); + QVERIFY(!semaphore.tryAcquire(100, 0)); QCOMPARE(semaphore.available(), 22); QVERIFY(semaphore.tryAcquire()); @@ -178,23 +184,38 @@ void tst_QSemaphore::tryAcquire() QVERIFY(semaphore.tryAcquire()); QCOMPARE(semaphore.available(), 20); + semaphore.release(2); + QVERIFY(semaphore.tryAcquire(1, 0)); + QCOMPARE(semaphore.available(), 21); + + QVERIFY(semaphore.tryAcquire(1, 0)); + QCOMPARE(semaphore.available(), 20); + QVERIFY(semaphore.tryAcquire(10)); QCOMPARE(semaphore.available(), 10); + semaphore.release(10); + QVERIFY(semaphore.tryAcquire(10, 0)); + QCOMPARE(semaphore.available(), 10); + QVERIFY(semaphore.tryAcquire(10)); QCOMPARE(semaphore.available(), 0); // should not be able to acquire more QVERIFY(!semaphore.tryAcquire()); + QVERIFY(!semaphore.tryAcquire(1, 0)); QCOMPARE(semaphore.available(), 0); QVERIFY(!semaphore.tryAcquire()); + QVERIFY(!semaphore.tryAcquire(1, 0)); QCOMPARE(semaphore.available(), 0); QVERIFY(!semaphore.tryAcquire(10)); + QVERIFY(!semaphore.tryAcquire(10, 0)); QCOMPARE(semaphore.available(), 0); QVERIFY(!semaphore.tryAcquire(10)); + QVERIFY(!semaphore.tryAcquire(10, 0)); QCOMPARE(semaphore.available(), 0); } @@ -344,6 +365,48 @@ void tst_QSemaphore::tryAcquireWithTimeoutStarvation() QVERIFY(consumer.wait()); } +void tst_QSemaphore::tryAcquireWithTimeoutForever_data() +{ + QTest::addColumn("timeout"); + QTest::newRow("-1") << -1; + + // tryAcquire is documented to take any negative value as "forever" + QTest::newRow("INT_MIN") << INT_MIN; +} + +void tst_QSemaphore::tryAcquireWithTimeoutForever() +{ + enum { WaitTime = 1000 }; + struct Thread : public QThread { + QSemaphore sem; + + void run() override + { + QTest::qWait(WaitTime); + sem.release(2); + } + }; + + QFETCH(int, timeout); + Thread t; + + // sanity check it works if we can immediately acquire + t.sem.release(11); + QVERIFY(t.sem.tryAcquire(1, timeout)); + QVERIFY(t.sem.tryAcquire(10, timeout)); + + // verify that we do wait for at least WaitTime if we can't acquire immediately + QElapsedTimer timer; + timer.start(); + t.start(); + QVERIFY(t.sem.tryAcquire(1, timeout)); + QVERIFY(timer.elapsed() >= WaitTime); + + QVERIFY(t.wait()); + + QCOMPARE(t.sem.available(), 1); +} + const char alphabet[] = "ACGTH"; const int AlphabetSize = sizeof(alphabet) - 1; From 4d8ae444c2b15ec7da5ef133aa5ad5a548180e21 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 15 Nov 2017 19:19:12 +0200 Subject: [PATCH 3/9] No debugging and extra env & params processing on sealed packages A "sealed" package is a *release build and signed* Qt for Android package with no debugging capabilities. By default sealed packages have no debugging capabilities, but the user can force debugging capabilities also on a sealed package. This is useful in corner cases when the user really needs to debug a sealed package. Change-Id: I840526092556067f2659facf1525861bbabe0edd Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../qt5/android/QtActivityDelegate.java | 305 +++++++++--------- 1 file changed, 155 insertions(+), 150 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 32d4abf43af..0f02304f9e5 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -720,184 +720,189 @@ public class QtActivityDelegate Bundle extras = m_activity.getIntent().getExtras(); if (extras != null) { - if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 - &&*/ extras.containsKey("debug_ping") - && extras.getString("debug_ping").equals("true")) { - try { - final String dc = "--Added-by-androiddeployqt--/debugger.command"; - String debuggerCommand = - new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine(); - String packagePath = - m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(), - PackageManager.GET_CONFIGURATIONS).dataDir + "/"; + try { + final String dc = "--Added-by-androiddeployqt--/debugger.command"; + String debuggerCommand = + new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine(); + if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 + &&*/ extras.containsKey("debug_ping") + && extras.getString("debug_ping").equals("true")) { + try { + String packagePath = + m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(), + PackageManager.GET_CONFIGURATIONS).dataDir + "/"; - debugLog("extra parameters: " + extras); - String packageName = m_activity.getPackageName(); - String pingFile = extras.getString("ping_file"); - String pongFile = extras.getString("pong_file"); - String gdbserverSocket = extras.getString("gdbserver_socket"); - String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket; - String pingSocket = extras.getString("ping_socket"); - boolean usePing = pingFile != null; - boolean usePong = pongFile != null; - boolean useSocket = gdbserverSocket != null; - boolean usePingSocket = pingSocket != null; - int napTime = 200; // milliseconds between file accesses - int timeOut = 30000; // ms until we give up on ping and pong - int maxAttempts = timeOut / napTime; + debugLog("extra parameters: " + extras); + String packageName = m_activity.getPackageName(); + String pingFile = extras.getString("ping_file"); + String pongFile = extras.getString("pong_file"); + String gdbserverSocket = extras.getString("gdbserver_socket"); + String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket; + String pingSocket = extras.getString("ping_socket"); + boolean usePing = pingFile != null; + boolean usePong = pongFile != null; + boolean useSocket = gdbserverSocket != null; + boolean usePingSocket = pingSocket != null; + int napTime = 200; // milliseconds between file accesses + int timeOut = 30000; // ms until we give up on ping and pong + int maxAttempts = timeOut / napTime; - if (gdbserverSocket != null) { - debugLog("removing gdb socket " + gdbserverSocket); - new File(gdbserverSocket).delete(); - } - - if (usePing) { - debugLog("removing ping file " + pingFile); - File ping = new File(pingFile); - if (ping.exists()) { - if (!ping.delete()) - debugLog("ping file cannot be deleted"); + if (gdbserverSocket != null) { + debugLog("removing gdb socket " + gdbserverSocket); + new File(gdbserverSocket).delete(); } - } - if (usePong) { - debugLog("removing pong file " + pongFile); - File pong = new File(pongFile); - if (pong.exists()) { - if (!pong.delete()) - debugLog("pong file cannot be deleted"); - } - } - - debugLog("starting " + gdbserverCommand); - m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand); - debugLog("gdbserver started"); - - if (useSocket) { - int i; - for (i = 0; i < maxAttempts; ++i) { - debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i); - File file = new File(gdbserverSocket); - if (file.exists()) { - file.setReadable(true, false); - file.setWritable(true, false); - file.setExecutable(true, false); - break; + if (usePing) { + debugLog("removing ping file " + pingFile); + File ping = new File(pingFile); + if (ping.exists()) { + if (!ping.delete()) + debugLog("ping file cannot be deleted"); } - Thread.sleep(napTime); } - if (i == maxAttempts) { - debugLog("time out when waiting for debug socket"); - return false; + if (usePong) { + debugLog("removing pong file " + pongFile); + File pong = new File(pongFile); + if (pong.exists()) { + if (!pong.delete()) + debugLog("pong file cannot be deleted"); + } } - debugLog("socket ok"); - } else { - debugLog("socket not used"); - } + debugLog("starting " + gdbserverCommand); + m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand); + debugLog("gdbserver started"); - if (usePingSocket) { - DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket); - Thread waitThread = new Thread(runnable); - waitThread.start(); + if (useSocket) { + int i; + for (i = 0; i < maxAttempts; ++i) { + debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i); + File file = new File(gdbserverSocket); + if (file.exists()) { + file.setReadable(true, false); + file.setWritable(true, false); + file.setExecutable(true, false); + break; + } + Thread.sleep(napTime); + } - int i; - for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) { - debugLog("Waiting for debug socket connect"); - debugLog("go to sleep"); - Thread.sleep(napTime); - } + if (i == maxAttempts) { + debugLog("time out when waiting for debug socket"); + return false; + } - if (i == maxAttempts) { - debugLog("time out when waiting for ping socket"); - runnable.shutdown(); - return false; - } - - if (runnable.wasFailure) { - debugLog("Could not connect to debug client"); - return false; + debugLog("socket ok"); } else { - debugLog("Got pid acknowledgment"); + debugLog("socket not used"); } - } - if (usePing) { - // Tell we are ready. - debugLog("writing ping at " + pingFile); - FileWriter writer = new FileWriter(pingFile); - writer.write("" + android.os.Process.myPid()); - writer.close(); - File file = new File(pingFile); - file.setReadable(true, false); - file.setWritable(true, false); - file.setExecutable(true, false); - debugLog("wrote ping"); - } else { - debugLog("ping not requested"); - } + if (usePingSocket) { + DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket); + Thread waitThread = new Thread(runnable); + waitThread.start(); - // Wait until other side is ready. - if (usePong) { - int i; - for (i = 0; i < maxAttempts; ++i) { - debugLog("waiting for pong at " + pongFile + ", attempt " + i); - File file = new File(pongFile); - if (file.exists()) { - file.delete(); - break; + int i; + for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) { + debugLog("Waiting for debug socket connect"); + debugLog("go to sleep"); + Thread.sleep(napTime); } - debugLog("go to sleep"); - Thread.sleep(napTime); - } - debugLog("Removing pingFile " + pingFile); - new File(pingFile).delete(); - if (i == maxAttempts) { - debugLog("time out when waiting for pong file"); - return false; + if (i == maxAttempts) { + debugLog("time out when waiting for ping socket"); + runnable.shutdown(); + return false; + } + + if (runnable.wasFailure) { + debugLog("Could not connect to debug client"); + return false; + } else { + debugLog("Got pid acknowledgment"); + } } - debugLog("got pong " + pongFile); - } else { - debugLog("pong not requested"); + if (usePing) { + // Tell we are ready. + debugLog("writing ping at " + pingFile); + FileWriter writer = new FileWriter(pingFile); + writer.write("" + android.os.Process.myPid()); + writer.close(); + File file = new File(pingFile); + file.setReadable(true, false); + file.setWritable(true, false); + file.setExecutable(true, false); + debugLog("wrote ping"); + } else { + debugLog("ping not requested"); + } + + // Wait until other side is ready. + if (usePong) { + int i; + for (i = 0; i < maxAttempts; ++i) { + debugLog("waiting for pong at " + pongFile + ", attempt " + i); + File file = new File(pongFile); + if (file.exists()) { + file.delete(); + break; + } + debugLog("go to sleep"); + Thread.sleep(napTime); + } + debugLog("Removing pingFile " + pingFile); + new File(pingFile).delete(); + + if (i == maxAttempts) { + debugLog("time out when waiting for pong file"); + return false; + } + + debugLog("got pong " + pongFile); + } else { + debugLog("pong not requested"); + } + + } catch (IOException ioe) { + ioe.printStackTrace(); + } catch (SecurityException se) { + se.printStackTrace(); } - - } catch (IOException ioe) { - ioe.printStackTrace(); - } catch (SecurityException se) { - se.printStackTrace(); } - } - if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 - &&*/ extras.containsKey("qml_debug") - && extras.getString("qml_debug").equals("true")) { - String qmljsdebugger; - if (extras.containsKey("qmljsdebugger")) { - qmljsdebugger = extras.getString("qmljsdebugger"); - qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security - } else { - qmljsdebugger = "port:3768"; + if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 + &&*/ extras.containsKey("qml_debug") + && extras.getString("qml_debug").equals("true")) { + String qmljsdebugger; + if (extras.containsKey("qmljsdebugger")) { + qmljsdebugger = extras.getString("qmljsdebugger"); + qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security + } else { + qmljsdebugger = "port:3768"; + } + m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger; } - m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger; - } - if (extras.containsKey("extraenvvars")) { - try { - m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8"); - } catch (Exception e) { - e.printStackTrace(); + if (extras.containsKey("extraenvvars")) { + try { + m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } } - } - if (extras.containsKey("extraappparams")) { - try { - m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8"); - } catch (Exception e) { - e.printStackTrace(); + if (extras.containsKey("extraappparams")) { + try { + m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + } } + } catch (Exception e) { + // This is not an error, so keep it silent + // e.printStackTrace(); } } // extras != null From 5a235da270a4ea65b7ef1edf31a761c41dbfcc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 22 Nov 2017 14:16:42 +0100 Subject: [PATCH 4/9] tst_QTcpSocket: fix disconnectWhileLookingUp ... and unblacklist it on Windows. From what I can tell there is no particular reason why this test fails other than that it is a little too slow sometimes (these things happen). So, to fix the test I bumped the timeout, but to avoid the test running for longer on every test-run it now also ends when the socket enters the "Unconnected" state. Previously it failed 171/500 times, and after this patch it failed 0/1000 times. Change-Id: I4266bff6b91aaaf502ee66265d01c3a177706402 Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira Reviewed-by: Jesus Fernandez --- tests/auto/network/socket/qtcpsocket/BLACKLIST | 2 -- tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp | 9 ++++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/auto/network/socket/qtcpsocket/BLACKLIST b/tests/auto/network/socket/qtcpsocket/BLACKLIST index 5fc2589323c..96e59e5678d 100644 --- a/tests/auto/network/socket/qtcpsocket/BLACKLIST +++ b/tests/auto/network/socket/qtcpsocket/BLACKLIST @@ -6,8 +6,6 @@ windows windows [invalidProxy:socks5-on-http] windows -[disconnectWhileLookingUp] -windows [timeoutConnect:ip] windows ] diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 7340817ade1..f64a88cc05a 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -1447,8 +1447,15 @@ void tst_QTcpSocket::disconnectWhileLookingUp() } // let anything queued happen + QEventLoop loop; - QTimer::singleShot(50, &loop, SLOT(quit())); + // If 'doClose' is false then we called '::waitForDisconnected' earlier, meaning + // we are already 'Unconnected'. So we don't need to wait for any potentially slow host lookups. + QTimer::singleShot(doClose ? 4000 : 50, &loop, SLOT(quit())); + connect(socket, &QTcpSocket::stateChanged, [&loop](QAbstractSocket::SocketState state) { + if (state == QAbstractSocket::UnconnectedState) + loop.exit(); // we don't need to wait for the timer to expire; we're done. + }); loop.exec(); // recheck From 655cbb00a0a50588dcf527d2e7fdfeb172ba60ae Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 24 Nov 2017 10:31:34 +0100 Subject: [PATCH 5/9] Handle HostNotFoundError correctly for HTTP/2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When processing host lookup error if-statement only checks the connection type SPDY, which is not right - it could also be HTTP/2. As a bonus: QT_NO_SSL conditional inclusion is not needed - HTTP2 can be 'clear text' and SPDY enumerator is defined even in no-tls build (and is just a noop here). Also, improve our somewhat cryptic message in 'Should not happen' else branch - 'cannot dequeu' says nothing about HostNotFoundError. Task-number: QTBUG-64721 Change-Id: Ib0346b8717c2dbddaffab690298f3cae01e338ea Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/network/access/qhttpnetworkconnection.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index da055de2da5..5bc5f22feff 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1204,20 +1204,20 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info) if (dequeueRequest(channels[0].socket)) { emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError); networkLayerState = QHttpNetworkConnectionPrivate::Unknown; - } -#ifndef QT_NO_SSL - else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY) { + } else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY + || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2) { for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) { // emit error for all replies QHttpNetworkReply *currentReply = spdyPair.second; Q_ASSERT(currentReply); emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError); } - } -#endif // QT_NO_SSL - else { - // Should not happen - qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished could not de-queue request"); + } else { + // Should not happen: we start a host lookup before sending a request, + // so it's natural to have requests either in SPDY/HTTP/2 queue, + // or in low/high priority queues. + qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished" + " could not de-queue request, failed to report HostNotFoundError"); networkLayerState = QHttpNetworkConnectionPrivate::Unknown; } } From 3587a25238b5c0a53285f96383ed0af1c05b3153 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 18 Nov 2017 18:21:13 +0100 Subject: [PATCH 6/9] QFlags: support enum classes in setFlag() Unary ~ is not defined for enum classes, so we need a cast. Change-Id: I79d495ebcc24ab960da8dae3be08eb307a9de448 Reviewed-by: Thiago Macieira --- src/corelib/global/qflags.h | 2 +- tests/auto/corelib/global/qflags/tst_qflags.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h index feeb488acd1..72b0a689ff0 100644 --- a/src/corelib/global/qflags.h +++ b/src/corelib/global/qflags.h @@ -150,7 +150,7 @@ public: Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const Q_DECL_NOTHROW { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f) ); } Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum f, bool on = true) Q_DECL_NOTHROW { - return on ? (*this |= f) : (*this &= ~f); + return on ? (*this |= f) : (*this &= ~Int(f)); } private: diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 7dd1a1be01e..2f1b56629af 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -290,6 +290,18 @@ void tst_QFlags::testSetFlags() btn.setFlag(Qt::LeftButton, false); QVERIFY(!btn.testFlag(Qt::LeftButton)); QVERIFY(!btn.testFlag(Qt::MidButton)); + + MyStrictFlags flags; + flags.setFlag(MyStrictEnum::StrictOne); + flags.setFlag(MyStrictEnum::StrictTwo, true); + QVERIFY(flags.testFlag(MyStrictEnum::StrictOne)); + QVERIFY(flags.testFlag(MyStrictEnum::StrictTwo)); + QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour)); + + flags.setFlag(MyStrictEnum::StrictTwo, false); + QVERIFY(flags.testFlag(MyStrictEnum::StrictOne)); + QVERIFY(!flags.testFlag(MyStrictEnum::StrictTwo)); + QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour)); } // (statically) check QTypeInfo for QFlags instantiations: From fa2a653b3b934783065bb3ea264788e9f8bbdc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 14 Apr 2017 15:13:28 +0200 Subject: [PATCH 7/9] Initialize QLoggingRegistry rules on first use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows categorized logging before QCoreApplication has been created, which otherwise would silently fail to output anything because the category would never be enabled, despite QT_LOGGING_RULES being set. Change-Id: I1861e5366ea980dff2ffa753b137276c77278eee Reviewed-by: Kai Koehne Reviewed-by: Morten Johan Sørvig --- src/corelib/io/qloggingregistry.cpp | 3 ++- src/corelib/io/qloggingregistry_p.h | 2 +- src/corelib/kernel/qcoreapplication.cpp | 2 -- .../qloggingregistry/tst_qloggingregistry.cpp | 24 ++++++++++++++----- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index 0e7eaeea76d..1bf61017f67 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -255,6 +255,7 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line) QLoggingRegistry::QLoggingRegistry() : categoryFilter(defaultCategoryFilter) { + initalizeRules(); // Init on first use } static bool qtLoggingDebug() @@ -283,7 +284,7 @@ static QVector loadRulesFromFile(const QString &filePath) Initializes the rules database by loading $QT_LOGGING_CONF, $QT_LOGGING_RULES, and .config/QtProject/qtlogging.ini. */ -void QLoggingRegistry::init() +void QLoggingRegistry::initalizeRules() { QVector er, qr, cr; // get rules from environment diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h index a68b993cca8..a3857d35880 100644 --- a/src/corelib/io/qloggingregistry_p.h +++ b/src/corelib/io/qloggingregistry_p.h @@ -113,7 +113,7 @@ class Q_AUTOTEST_EXPORT QLoggingRegistry public: QLoggingRegistry(); - void init(); + void initalizeRules(); void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel); void unregisterCategory(QLoggingCategory *category); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index cba279c184b..bf423cef21d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -776,8 +776,6 @@ void QCoreApplicationPrivate::init() if (!coreappdata()->applicationVersionSet) coreappdata()->applicationVersion = appVersion(); - QLoggingRegistry::instance()->init(); - #if QT_CONFIG(library) // Reset the lib paths, so that they will be recomputed, taking the availability of argv[0] // into account. If necessary, recompute right away and replay the manual changes on top of the diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp index 1643eed3d2b..15c63d4acd1 100644 --- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp +++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp @@ -197,10 +197,22 @@ private slots: // Check whether QT_LOGGING_CONF is picked up from environment // - qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit()); + Q_ASSERT(!qApp); // Rules should not require an app to resolve - QLoggingRegistry registry; - registry.init(); + qputenv("QT_LOGGING_RULES", "qt.foo.bar=true"); + QLoggingCategory qtEnabledByLoggingRule("qt.foo.bar"); + QCOMPARE(qtEnabledByLoggingRule.isDebugEnabled(), true); + QLoggingCategory qtDisabledByDefault("qt.foo.baz"); + QCOMPARE(qtDisabledByDefault.isDebugEnabled(), false); + + QLoggingRegistry ®istry = *QLoggingRegistry::instance(); + QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0); + QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0); + QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 1); + + qunsetenv("QT_LOGGING_RULES"); + qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit()); + registry.initalizeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0); QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0); @@ -208,7 +220,7 @@ private slots: // check that QT_LOGGING_RULES take precedence qputenv("QT_LOGGING_RULES", "Digia.*=true"); - registry.init(); + registry.initalizeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 2); QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].at(1).enabled, true); } @@ -234,7 +246,7 @@ private slots: file.close(); QLoggingRegistry registry; - registry.init(); + registry.initalizeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 1); // remove file again @@ -300,6 +312,6 @@ private slots: } }; -QTEST_MAIN(tst_QLoggingRegistry) +QTEST_APPLESS_MAIN(tst_QLoggingRegistry) #include "tst_qloggingregistry.moc" From 6a9d076e87f0c8aa4fb49bbcc2f56eefd85af2e3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Nov 2017 14:42:54 -0800 Subject: [PATCH 8/9] QUdpSocket: Work around WSARecvMsg quirk relating to no control block WSARecvMsg does not return the sender in WSAMSG::name if WSAMSG::Control isn't set. This makes no sense, so I'm assuming it's an API quirk we need to work around. [ChangeLog][QtNetwork][QUdpSocket] Fixed a regression from Qt 5.9.3 caused by an apparent Win32 API quirk we triggered when using readDatagram(), resulting in an invalid QHostAddress sender address. receiveDatagram() was not affected. Task-number: QTBUG-64718 Change-Id: I71488efd29b645f7b228fffd14f9d84cc205c4b3 Reviewed-by: Timur Pocheptsov --- src/network/socket/qnativesocketengine_win.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 3ecfb06411d..a1f7f367001 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1215,10 +1215,8 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL msg.dwBufferCount = 1; msg.name = reinterpret_cast(&aa); msg.namelen = sizeof(aa); - if (options & (QAbstractSocketEngine::WantDatagramHopLimit | QAbstractSocketEngine::WantDatagramDestination)) { - msg.Control.buf = cbuf; - msg.Control.len = sizeof(cbuf); - } + msg.Control.buf = cbuf; + msg.Control.len = sizeof(cbuf); DWORD flags = 0; DWORD bytesRead = 0; From 5f66f871816d083da9795d71f746413d6f6118f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 26 Nov 2017 23:01:57 -0800 Subject: [PATCH 9/9] Stop depending on test.macieira.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have had test.qt-project.org for close to 3 years now. Change-Id: I71488efd29b645f7b228fffd14fadf4627288243 Reviewed-by: Jędrzej Nowacki --- .../kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp | 4 ++-- tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp b/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp index 7874221da98..e302fe8c74c 100644 --- a/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp +++ b/tests/auto/network/kernel/qdnslookup_appless/tst_qdnslookup_appless.cpp @@ -43,7 +43,7 @@ private slots: void tst_QDnsLookup_Appless::noApplication() { QTest::ignoreMessage(QtWarningMsg, "QDnsLookup requires a QCoreApplication"); - QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org"); + QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org"); dns.lookup(); } @@ -53,7 +53,7 @@ void tst_QDnsLookup_Appless::recreateApplication() char **argv = 0; for (int i = 0; i < 10; ++i) { QCoreApplication app(argc, argv); - QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org"); + QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org"); dns.lookup(); if (!dns.isFinished()) { QObject::connect(&dns, SIGNAL(finished()), diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index 2671c253cb3..14bffaf7ca0 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -76,7 +76,7 @@ #include "../../../network-settings.h" -#define TEST_DOMAIN ".test.macieira.org" +#define TEST_DOMAIN ".test.qt-project.org" class tst_QHostInfo : public QObject