From de40f24706d0f3c4cc13900380aacc90d6879356 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 15 Apr 2018 14:36:53 -0700 Subject: [PATCH 01/12] Fix the enabling of AES with ICC and MSVC on some low-end processors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC and Clang assume that all Sandybridge (2nd generation) and newer Intel Coreâ„¢ processors have AES, which I used as a source of information for this code. However, there are a few low-end parts that miss this feature, like Intel Coreâ„¢ i3-2350M, i3-3130M, i3-4000M. [1] https://ark.intel.com/products/series/75025/4th-Generation-Intel-Core-i3-Processors Task-number: QTBUG-67705 Change-Id: If90a92b041d3442fa0a4fffd1525b9afbcb6e524 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd_p.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index eb56b313489..18684caefbd 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -219,9 +219,8 @@ // AVX intrinsics # if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC)) // AES, PCLMULQDQ instructions: -// All processors that support AVX support AES, PCLMULQDQ -// (but neither MSVC nor the Intel compiler define these macros) -# define __AES__ 1 +// All processors that support AVX support PCLMULQDQ +// (but neither MSVC nor the Intel compiler define this macro) # define __PCLMUL__ 1 # endif From d3935cbd71171e1d8f3742cc3235ca0c38313ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Thu, 3 May 2018 13:25:06 +0200 Subject: [PATCH 02/12] QJsonDocument::fromRawData: Fix out-of-bounds access This method takes a pointer+size pair, but begins reading through the pointer without first checking the size parameter. Fixed by checking the size parameter. A new test case is added with an empty binary json file. Although the test does not fail under normal conditions, the problem can be detected using valgrind or AddressSanitizer. Task-number: QTBUG-61969 Change-Id: Ie91cc9a56dbc3c676472c614d4e633d7721b8481 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/serialization/qjson_p.h | 2 +- src/corelib/serialization/qjsondocument.cpp | 3 +++ .../auto/corelib/serialization/json/invalidBinaryData/38.bjson | 0 tests/auto/corelib/serialization/json/tst_qtjson.cpp | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 tests/auto/corelib/serialization/json/invalidBinaryData/38.bjson diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index 77433828062..dc56a490845 100644 --- a/src/corelib/serialization/qjson_p.h +++ b/src/corelib/serialization/qjson_p.h @@ -450,7 +450,7 @@ static inline void copyString(char *dest, const QString &str, bool compress) /* - Base is the base class for both Object and Array. Both classe work more or less the same way. + Base is the base class for both Object and Array. Both classes work more or less the same way. The class starts with a header (defined by the struct below), then followed by data (the data for values in the Array case and Entry's (see below) for objects. diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp index 9794bca60d7..ab27b45fda7 100644 --- a/src/corelib/serialization/qjsondocument.cpp +++ b/src/corelib/serialization/qjsondocument.cpp @@ -210,6 +210,9 @@ QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidat return QJsonDocument(); } + if (size < (int)(sizeof(QJsonPrivate::Header) + sizeof(QJsonPrivate::Base))) + return QJsonDocument(); + QJsonPrivate::Data *d = new QJsonPrivate::Data((char *)data, size); d->ownsData = false; diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/38.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/38.bjson new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 99bdd8deb02..41c8f760dc2 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -1863,6 +1863,7 @@ void tst_QtJson::invalidBinaryData() QFile file(files.at(i).filePath()); file.open(QIODevice::ReadOnly); QByteArray bytes = file.readAll(); + bytes.squeeze(); QJsonDocument document = QJsonDocument::fromRawData(bytes.constData(), bytes.size()); QVERIFY(document.isNull()); } From 1aee60eb331d2e11352f27ecd220cc3e65b61249 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 30 Apr 2018 15:39:29 +0200 Subject: [PATCH 03/12] Fix encoding of freetype/LICENSE.txt to utf-8 The previous encoding was ISO-8859-1. Change-Id: Id13bf1936120fb8b3630ba671ca92f285fa80dec Reviewed-by: Friedemann Kleint --- src/3rdparty/freetype/LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/freetype/LICENSE.txt b/src/3rdparty/freetype/LICENSE.txt index 382225f105a..1119880c095 100644 --- a/src/3rdparty/freetype/LICENSE.txt +++ b/src/3rdparty/freetype/LICENSE.txt @@ -85,7 +85,7 @@ Introduction encourage you to use the following text: """ - Portions of this software are copyright © The FreeType + Portions of this software are copyright © The FreeType Project (www.freetype.org). All rights reserved. """ From 3fc5500b4f2a8431ac013520e9faf606e893b39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Thu, 3 May 2018 13:39:36 +0200 Subject: [PATCH 04/12] QJsonDocument: Reject objects containing themselves in binary JSON The added test case is a binary JSON file describing an array which contains itself. This file passes validation even though attempting to convert it to plain JSON leads to an infinite loop. Fixed by rejecting it in validation. Task-number: QTBUG-61969 Change-Id: Ib4472e9777d09840c30c384b24294e4744b02045 Reviewed-by: Lars Knoll --- src/corelib/serialization/qjson.cpp | 6 +++--- .../serialization/json/invalidBinaryData/39.bjson | Bin 0 -> 24 bytes 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 tests/auto/corelib/serialization/json/invalidBinaryData/39.bjson diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp index e4bca3bcd06..c5e9eb70e13 100644 --- a/src/corelib/serialization/qjson.cpp +++ b/src/corelib/serialization/qjson.cpp @@ -328,7 +328,7 @@ int Value::usedStorage(const Base *b) const bool Value::isValid(const Base *b) const { - int offset = 0; + int offset = -1; switch (type) { case QJsonValue::Double: if (latinOrIntValue) @@ -345,9 +345,9 @@ bool Value::isValid(const Base *b) const break; } - if (!offset) + if (offset == -1) return true; - if (offset + sizeof(uint) > b->tableOffset) + if (offset + sizeof(uint) > b->tableOffset || offset < (int)sizeof(Base)) return false; int s = usedStorage(b); diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/39.bjson b/tests/auto/corelib/serialization/json/invalidBinaryData/39.bjson new file mode 100644 index 0000000000000000000000000000000000000000..c6025aa9eb022f6582951aa4178e937fa8754705 GIT binary patch literal 24 ZcmXR+$|`1LU| Date: Thu, 3 May 2018 16:39:32 +0200 Subject: [PATCH 05/12] QJsonDocument: Validate also zero-length objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The added test case is the binary JSON equivalent of {"a":{"Å¡":null}} with two modifications. First, the length of the string "Å¡" has been corrupted to 0xFFFFFF00. Second and more import, the Base::size field of the inner object has been reset to 0. On its own the first modification would normally trigger a validation error. However, due to the second modification the Value::usedStorage for the inner object evaluates to 0, completely disabling all further validation of the object's contents. Attempting to convert this binary JSON into standard JSON will lead to the JSON writer trying to construct a QString of length 0xFFFFFF00. Fixed by validating also objects with usedStorage == 0. Task-number: QTBUG-61969 Change-Id: I5e59383674dec9be89361759572c0d91d4e16e01 Reviewed-by: Thiago Macieira --- src/corelib/serialization/qjson.cpp | 2 -- .../serialization/json/invalidBinaryData/40.json | Bin 0 -> 60 bytes 2 files changed, 2 deletions(-) create mode 100644 tests/auto/corelib/serialization/json/invalidBinaryData/40.json diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp index c5e9eb70e13..592f6168dc3 100644 --- a/src/corelib/serialization/qjson.cpp +++ b/src/corelib/serialization/qjson.cpp @@ -351,8 +351,6 @@ bool Value::isValid(const Base *b) const return false; int s = usedStorage(b); - if (!s) - return true; if (s < 0 || s > (int)b->tableOffset - offset) return false; if (type == QJsonValue::Array) diff --git a/tests/auto/corelib/serialization/json/invalidBinaryData/40.json b/tests/auto/corelib/serialization/json/invalidBinaryData/40.json new file mode 100644 index 0000000000000000000000000000000000000000..277096f8cba211643c1ec8b7a478b9e41aadd8ae GIT binary patch literal 60 xcmXR+$|`1LU|=u-VrC#V0OF}k3=E76i9i-aOajbeVEF(4KSLr=F%OUr!T`^&2BZK0 literal 0 HcmV?d00001 From 28071ad25333e3c44245e45b483eb9e5818b077a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 3 May 2018 14:22:49 +0200 Subject: [PATCH 06/12] Fix crash in qsslsocket_openssl We were using the wrong free function in a path which was hit in an edge case (PKCS#12 certificate without a private key attached). Change-Id: I5335b5dea7a926b242bed0fd9b989b681a5828d8 Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_openssl.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 1fc7817fe82..cecb4fb7535 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1517,7 +1517,7 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, if (!key->d->fromEVP_PKEY(pkey)) { qCWarning(lcSsl, "Unable to convert private key"); q_OPENSSL_sk_pop_free(reinterpret_cast(ca), - reinterpret_cast(q_OPENSSL_sk_free)); + reinterpret_cast(q_X509_free)); q_X509_free(x509); q_EVP_PKEY_free(pkey); q_PKCS12_free(p12); @@ -1532,8 +1532,6 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, *caCertificates = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(ca); // Clean up - // TODO: verify ASAP, in the past we had sk_pop_free with q_OPENSSL_sk_free - // which seems to be blatantly wrong and even crashes with 1.1. q_OPENSSL_sk_pop_free(reinterpret_cast(ca), reinterpret_cast(q_X509_free)); From ef242e0b34df0111a6f1306550acef9fde0ec1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 2 May 2018 15:44:40 +0200 Subject: [PATCH 07/12] OpenSSL 1.1.1: Fix tst_QSslCertificate::toText The formatting of the output from QSslCertificate::toText has changed slightly from before, so it no longer matches the test's data. From what I can tell we just do a manual sanity check and create a new file with the new output and then augment the test. Task-number: QTBUG-67463 Change-Id: I751e5a3f9a28015f97c895cea47384704fd68e38 Reviewed-by: Timur Pocheptsov --- .../cert-large-expiration-date.txt.1.1.1 | 42 +++++++++++++++++++ .../qsslcertificate/tst_qsslcertificate.cpp | 7 +++- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/auto/network/ssl/qsslcertificate/more-certificates/cert-large-expiration-date.txt.1.1.1 diff --git a/tests/auto/network/ssl/qsslcertificate/more-certificates/cert-large-expiration-date.txt.1.1.1 b/tests/auto/network/ssl/qsslcertificate/more-certificates/cert-large-expiration-date.txt.1.1.1 new file mode 100644 index 00000000000..0ad263587f6 --- /dev/null +++ b/tests/auto/network/ssl/qsslcertificate/more-certificates/cert-large-expiration-date.txt.1.1.1 @@ -0,0 +1,42 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + ce:db:31:28:45:c4:05:40 + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd + Validity + Not Before: Aug 4 09:53:41 2010 GMT + Not After : Aug 29 09:53:41 2051 GMT + Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (1024 bit) + Modulus: + 00:cd:aa:db:6f:d6:34:c9:a7:f1:c0:be:e4:41:18: + 19:e2:02:c9:22:e6:a7:d5:ba:03:2e:9e:28:7a:f4: + 5f:1a:77:5f:77:a9:11:3b:8f:7e:f0:2e:c6:9e:eb: + 3a:d9:12:d7:c1:0c:51:e8:24:52:3f:23:c3:42:0c: + 11:c6:f2:1c:a1:42:fe:b4:c2:69:83:ad:f7:70:b1: + 18:15:cc:20:28:62:30:f0:2c:15:e6:33:19:af:c3: + eb:1c:c0:91:f7:11:68:94:50:f8:49:37:08:32:d7: + 3e:75:df:a3:bc:69:00:15:de:cd:87:0f:5c:02:6b: + 82:c8:01:7d:6a:f0:1d:dc:73 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 8A:6E:19:E7:97:9B:8F:D9:7F:B3:BB:01:4F:E8:6A:2F:52:95:0D:D9 + X509v3 Authority Key Identifier: + keyid:8A:6E:19:E7:97:9B:8F:D9:7F:B3:BB:01:4F:E8:6A:2F:52:95:0D:D9 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha1WithRSAEncryption + a1:74:8e:5d:36:96:2c:05:7e:ea:66:cc:2e:68:c7:3d:93:dc: + 8c:a3:11:ad:b5:7e:6e:d0:04:c4:09:bd:0a:f9:39:3b:97:d7: + f0:bb:0c:09:7b:83:fe:bf:87:b0:47:e8:94:b7:aa:9c:79:ad: + 71:9e:b7:c4:99:98:6f:1d:38:32:f8:a3:75:38:c4:e5:e7:37: + 37:21:ec:7b:50:8b:15:b0:97:1e:17:9c:50:17:3c:c1:df:94: + 55:fb:60:2e:50:40:d1:ea:23:c6:3c:21:6f:97:8c:06:16:a5: + 82:72:c1:63:14:64:86:eb:d7:ff:72:f6:09:f5:6d:e6:04:13: + 7a:6a diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp index 1477fd212ec..7f8580ddd65 100644 --- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp @@ -922,6 +922,10 @@ void tst_QSslCertificate::toText() QVERIFY(f101c.open(QIODevice::ReadOnly | QFile::Text)); QByteArray txt101c = f101c.readAll(); + QFile f111(testDataDir + "more-certificates/cert-large-expiration-date.txt.1.1.1"); + QVERIFY(f111.open(QIODevice::ReadOnly | QFile::Text)); + QByteArray txt111 = f111.readAll(); + QString txtcert = cert.toText(); #ifdef QT_NO_OPENSSL @@ -930,7 +934,8 @@ void tst_QSslCertificate::toText() QVERIFY(QString::fromLatin1(txt098) == txtcert || QString::fromLatin1(txt100) == txtcert || QString::fromLatin1(txt101) == txtcert || - QString::fromLatin1(txt101c) == txtcert ); + QString::fromLatin1(txt101c) == txtcert || + QString::fromLatin1(txt111) == txtcert ); } void tst_QSslCertificate::multipleCommonNames() From 5269f6d55e4cb804e0316f2239916f83001a7379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Fri, 2 Mar 2018 22:01:22 +0100 Subject: [PATCH 08/12] Avoid to fail to close stream on exception Move .close() to finally block. Found by spotbugs. Change-Id: I1d11f52c79e805082f05801e4ef0ec94c6dc4e6e Reviewed-by: BogDan Vatra --- .../qt5/android/bindings/QtLoader.java | 58 ++++++++++++++----- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java index 424bf45c530..531802959cf 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java @@ -355,12 +355,21 @@ public abstract class QtLoader { destinationFile.createNewFile(); AssetManager assetsManager = m_context.getAssets(); - InputStream inputStream = assetsManager.open(source); - OutputStream outputStream = new FileOutputStream(destinationFile); - copyFile(inputStream, outputStream); + InputStream inputStream = null; + OutputStream outputStream = null; + try { + inputStream = assetsManager.open(source); + outputStream = new FileOutputStream(destinationFile); + copyFile(inputStream, outputStream); + catch (Exception e) { + e.printStackTrace(); + } finally { + if (inputStream != null) + inputStream.close(); - inputStream.close(); - outputStream.close(); + if (outputStream != null) + outputStream.close(); + } } private static void createBundledBinary(String source, String destination) @@ -377,12 +386,21 @@ public abstract class QtLoader { destinationFile.createNewFile(); - InputStream inputStream = new FileInputStream(source); - OutputStream outputStream = new FileOutputStream(destinationFile); - copyFile(inputStream, outputStream); + InputStream inputStream = null; + OutputStream outputStream = null; + try { + inputStream = new FileInputStream(source); + outputStream = new FileOutputStream(destinationFile); + copyFile(inputStream, outputStream); + catch (Exception e) { + e.printStackTrace(); + } finally { + if (inputStream != null) + inputStream.close(); - inputStream.close(); - outputStream.close(); + if (outputStream != null) + outputStream.close(); + } } private boolean cleanCacheIfNecessary(String pluginsPrefix, long packageVersion) @@ -391,12 +409,15 @@ public abstract class QtLoader { long cacheVersion = 0; if (versionFile.exists() && versionFile.canRead()) { + DataInputStream inputStream = null; try { - DataInputStream inputStream = new DataInputStream(new FileInputStream(versionFile)); + inputStream = new DataInputStream(new FileInputStream(versionFile)); cacheVersion = inputStream.readLong(); - inputStream.close(); } catch (Exception e) { e.printStackTrace(); + } finally { + if (inputStream != null) + inputStream.close(); } } @@ -431,9 +452,16 @@ public abstract class QtLoader { versionFile.createNewFile(); - DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(versionFile)); - outputStream.writeLong(packageVersion); - outputStream.close(); + DataOutputStream outputStream = null; + try { + outputStream = new DataOutputStream(new FileOutputStream(versionFile)); + outputStream.writeLong(packageVersion); + catch (Exception e) { + e.printStackTrace(); + } finally { + if (outputStream != null) + outputStream.close(); + } } { From e67671d7cb236944c6cd6fd72b353dad6b6d93bf Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Fri, 23 Mar 2018 16:40:45 -0400 Subject: [PATCH 09/12] Generate more Windows/Linux-like Qt keyboard events The QKeyEvent::key values were significantly different on QNX and some QKeyEvent::text values were also different/missing. Also makes it possible to enter numbers via the numeric keypad. Change-Id: Ifcf6284b99a893a87974d37ec6d6976f88241e61 Reviewed-by: Rafael Roquetto Reviewed-by: Dan Cape --- src/plugins/platforms/qnx/qqnxkeytranslator.h | 245 ++++++------------ .../platforms/qnx/qqnxscreeneventhandler.cpp | 75 ++++-- 2 files changed, 122 insertions(+), 198 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxkeytranslator.h b/src/plugins/platforms/qnx/qqnxkeytranslator.h index 043e38fec9b..9400b88dbbe 100644 --- a/src/plugins/platforms/qnx/qqnxkeytranslator.h +++ b/src/plugins/platforms/qnx/qqnxkeytranslator.h @@ -48,179 +48,68 @@ QT_BEGIN_NAMESPACE -Qt::Key keyTranslator( int key ) +int qtKeyForPrivateUseQnxKey( int key ) { switch (key) { - case KEYCODE_PAUSE: - return Qt::Key_Pause; - - case KEYCODE_SCROLL_LOCK: - return Qt::Key_ScrollLock; - - case KEYCODE_PRINT: - return Qt::Key_Print; - - case KEYCODE_SYSREQ: - return Qt::Key_SysReq; - + case KEYCODE_PAUSE: return Qt::Key_Pause; + case KEYCODE_SCROLL_LOCK: return Qt::Key_ScrollLock; + case KEYCODE_PRINT: return Qt::Key_Print; + case KEYCODE_SYSREQ: return Qt::Key_SysReq; // case KEYCODE_BREAK: - - case KEYCODE_ESCAPE: - return Qt::Key_Escape; - - case KEYCODE_BACKSPACE: - return Qt::Key_Backspace; - - case KEYCODE_TAB: - return Qt::Key_Tab; - - case KEYCODE_BACK_TAB: - return Qt::Key_Backtab; - - case KEYCODE_RETURN: - return Qt::Key_Return; - - case KEYCODE_CAPS_LOCK: - return Qt::Key_CapsLock; - - case KEYCODE_LEFT_SHIFT: - case KEYCODE_RIGHT_SHIFT: - return Qt::Key_Shift; - - case KEYCODE_LEFT_CTRL: - case KEYCODE_RIGHT_CTRL: - return Qt::Key_Control; - - case KEYCODE_LEFT_ALT: - case KEYCODE_RIGHT_ALT: - return Qt::Key_Alt; - - case KEYCODE_MENU: - return Qt::Key_Menu; - - case KEYCODE_LEFT_HYPER: - return Qt::Key_Hyper_L; - - case KEYCODE_RIGHT_HYPER: - return Qt::Key_Hyper_R; - - case KEYCODE_INSERT: - return Qt::Key_Insert; - - case KEYCODE_HOME: - return Qt::Key_Home; - - case KEYCODE_PG_UP: - return Qt::Key_PageUp; - - case KEYCODE_DELETE: - return Qt::Key_Delete; - - case KEYCODE_END: - return Qt::Key_End; - - case KEYCODE_PG_DOWN: - return Qt::Key_PageDown; - - case KEYCODE_LEFT: - return Qt::Key_Left; - - case KEYCODE_RIGHT: - return Qt::Key_Right; - - case KEYCODE_UP: - return Qt::Key_Up; - - case KEYCODE_DOWN: - return Qt::Key_Down; - - case KEYCODE_NUM_LOCK: - return Qt::Key_NumLock; - - case KEYCODE_KP_PLUS: - return Qt::Key_Plus; - - case KEYCODE_KP_MINUS: - return Qt::Key_Minus; - - case KEYCODE_KP_MULTIPLY: - return Qt::Key_Asterisk; - - case KEYCODE_KP_DIVIDE: - return Qt::Key_Slash; - - case KEYCODE_KP_ENTER: - return Qt::Key_Enter; - - case KEYCODE_KP_HOME: - return Qt::Key_Home; - - case KEYCODE_KP_UP: - return Qt::Key_Up; - - case KEYCODE_KP_PG_UP: - return Qt::Key_PageUp; - - case KEYCODE_KP_LEFT: - return Qt::Key_Left; - - // Is this right? - case KEYCODE_KP_FIVE: - return Qt::Key_5; - - case KEYCODE_KP_RIGHT: - return Qt::Key_Right; - - case KEYCODE_KP_END: - return Qt::Key_End; - - case KEYCODE_KP_DOWN: - return Qt::Key_Down; - - case KEYCODE_KP_PG_DOWN: - return Qt::Key_PageDown; - - case KEYCODE_KP_INSERT: - return Qt::Key_Insert; - - case KEYCODE_KP_DELETE: - return Qt::Key_Delete; - - case KEYCODE_F1: - return Qt::Key_F1; - - case KEYCODE_F2: - return Qt::Key_F2; - - case KEYCODE_F3: - return Qt::Key_F3; - - case KEYCODE_F4: - return Qt::Key_F4; - - case KEYCODE_F5: - return Qt::Key_F5; - - case KEYCODE_F6: - return Qt::Key_F6; - - case KEYCODE_F7: - return Qt::Key_F7; - - case KEYCODE_F8: - return Qt::Key_F8; - - case KEYCODE_F9: - return Qt::Key_F9; - - case KEYCODE_F10: - return Qt::Key_F10; - - case KEYCODE_F11: - return Qt::Key_F11; - - case KEYCODE_F12: - return Qt::Key_F12; + case KEYCODE_ESCAPE: return Qt::Key_Escape; + case KEYCODE_BACKSPACE: return Qt::Key_Backspace; + case KEYCODE_TAB: return Qt::Key_Tab; + case KEYCODE_BACK_TAB: return Qt::Key_Backtab; + case KEYCODE_RETURN: return Qt::Key_Return; + case KEYCODE_CAPS_LOCK: return Qt::Key_CapsLock; + case KEYCODE_LEFT_SHIFT: return Qt::Key_Shift; + case KEYCODE_RIGHT_SHIFT: return Qt::Key_Shift; + case KEYCODE_LEFT_CTRL: return Qt::Key_Control; + case KEYCODE_RIGHT_CTRL: return Qt::Key_Control; + case KEYCODE_LEFT_ALT: return Qt::Key_Alt; + case KEYCODE_RIGHT_ALT: return Qt::Key_Alt; + case KEYCODE_MENU: return Qt::Key_Menu; + case KEYCODE_LEFT_HYPER: return Qt::Key_Hyper_L; + case KEYCODE_RIGHT_HYPER: return Qt::Key_Hyper_R; + case KEYCODE_INSERT: return Qt::Key_Insert; + case KEYCODE_HOME: return Qt::Key_Home; + case KEYCODE_PG_UP: return Qt::Key_PageUp; + case KEYCODE_DELETE: return Qt::Key_Delete; + case KEYCODE_END: return Qt::Key_End; + case KEYCODE_PG_DOWN: return Qt::Key_PageDown; + case KEYCODE_LEFT: return Qt::Key_Left; + case KEYCODE_RIGHT: return Qt::Key_Right; + case KEYCODE_UP: return Qt::Key_Up; + case KEYCODE_DOWN: return Qt::Key_Down; + case KEYCODE_NUM_LOCK: return Qt::Key_NumLock; + case KEYCODE_KP_PLUS: return Qt::Key_Plus; + case KEYCODE_KP_MINUS: return Qt::Key_Minus; + case KEYCODE_KP_MULTIPLY: return Qt::Key_Asterisk; + case KEYCODE_KP_DIVIDE: return Qt::Key_Slash; + case KEYCODE_KP_ENTER: return Qt::Key_Enter; + case KEYCODE_KP_HOME: return Qt::Key_Home; + case KEYCODE_KP_UP: return Qt::Key_Up; + case KEYCODE_KP_PG_UP: return Qt::Key_PageUp; + case KEYCODE_KP_LEFT: return Qt::Key_Left; + case KEYCODE_KP_FIVE: return Qt::Key_5; + case KEYCODE_KP_RIGHT: return Qt::Key_Right; + case KEYCODE_KP_END: return Qt::Key_End; + case KEYCODE_KP_DOWN: return Qt::Key_Down; + case KEYCODE_KP_PG_DOWN: return Qt::Key_PageDown; + case KEYCODE_KP_INSERT: return Qt::Key_Insert; + case KEYCODE_KP_DELETE: return Qt::Key_Delete; + case KEYCODE_F1: return Qt::Key_F1; + case KEYCODE_F2: return Qt::Key_F2; + case KEYCODE_F3: return Qt::Key_F3; + case KEYCODE_F4: return Qt::Key_F4; + case KEYCODE_F5: return Qt::Key_F5; + case KEYCODE_F6: return Qt::Key_F6; + case KEYCODE_F7: return Qt::Key_F7; + case KEYCODE_F8: return Qt::Key_F8; + case KEYCODE_F9: return Qt::Key_F9; + case KEYCODE_F10: return Qt::Key_F10; + case KEYCODE_F11: return Qt::Key_F11; + case KEYCODE_F12: return Qt::Key_F12; // See keycodes.h for more, but these are all the basics. And printables are already included. @@ -231,7 +120,21 @@ Qt::Key keyTranslator( int key ) break; } - return Qt::Key_Escape; + return Qt::Key_unknown; +} + +QString keyStringForPrivateUseQnxKey( int key ) +{ + switch (key) { + case KEYCODE_ESCAPE: return QStringLiteral("\x1B"); + case KEYCODE_BACKSPACE: return QStringLiteral("\b"); + case KEYCODE_TAB: return QStringLiteral("\t"); + case KEYCODE_RETURN: return QStringLiteral("\r"); + case KEYCODE_DELETE: return QStringLiteral("\x7F"); + case KEYCODE_KP_ENTER: return QStringLiteral("\r"); + } + + return QString(); } bool isKeypadKey( int key ) diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index f211883e4ff..ff1133aaa78 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -58,6 +58,37 @@ #define qScreenEventDebug QT_NO_QDEBUG_MACRO #endif +static int qtKey(int virtualKey, QChar::Category category) +{ + if (Q_UNLIKELY(category == QChar::Other_NotAssigned)) + return virtualKey; + else if (category == QChar::Other_PrivateUse) + return qtKeyForPrivateUseQnxKey(virtualKey); + else + return QChar::toUpper(virtualKey); +} + +static QString keyString(int sym, QChar::Category category) +{ + if (Q_UNLIKELY(category == QChar::Other_NotAssigned)) { + return QString(); + } else if (category == QChar::Other_PrivateUse) { + return keyStringForPrivateUseQnxKey(sym); + } else { + uint ucs4_sym = sym; + return QString::fromUcs4(&ucs4_sym, 1); + } +} + +static QString capKeyString(int cap, int modifiers, int key) +{ + if (cap >= 0x20 && cap <= 0x0ff) { + if (modifiers & KEYMOD_CTRL) + return QChar((int)(key & 0x3f)); + } + return QString(); +} + QT_BEGIN_NAMESPACE QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration) @@ -154,6 +185,13 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie { Q_UNUSED(scan); + if (!(flags & KEY_CAP_VALID)) + return; + + // Correct erroneous information. + if ((flags & KEY_SYM_VALID) && sym == static_cast(0xFFFFFFFF)) + flags &= ~(KEY_SYM_VALID); + Qt::KeyboardModifiers qtMod = Qt::NoModifier; if (modifiers & KEYMOD_SHIFT) qtMod |= Qt::ShiftModifier; @@ -161,37 +199,20 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie qtMod |= Qt::ControlModifier; if (modifiers & KEYMOD_ALT) qtMod |= Qt::AltModifier; + if (isKeypadKey(cap)) + qtMod |= Qt::KeypadModifier; - // determine event type QEvent::Type type = (flags & KEY_DOWN) ? QEvent::KeyPress : QEvent::KeyRelease; - // Check if the key cap is valid - if (flags & KEY_CAP_VALID) { - Qt::Key key; - QString keyStr; + int virtualKey = (flags & KEY_SYM_VALID) ? sym : cap; + QChar::Category category = QChar::category(virtualKey); + int key = qtKey(virtualKey, category); + QString keyStr = (flags & KEY_SYM_VALID) ? keyString(sym, category) : + capKeyString(cap, modifiers, key); - if (cap >= 0x20 && cap <= 0x0ff) { - key = Qt::Key(std::toupper(cap)); // Qt expects the CAP to be upper case. - - if ( qtMod & Qt::ControlModifier ) { - keyStr = QChar((int)(key & 0x3f)); - } else { - if (flags & KEY_SYM_VALID) - keyStr = QChar(sym); - } - } else if ((cap > 0x0ff && cap < UNICODE_PRIVATE_USE_AREA_FIRST) || cap > UNICODE_PRIVATE_USE_AREA_LAST) { - key = (Qt::Key)cap; - keyStr = QChar(sym); - } else { - if (isKeypadKey(cap)) - qtMod |= Qt::KeypadModifier; // Is this right? - key = keyTranslator(cap); - } - - QWindowSystemInterface::handleExtendedKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, - scan, sym, modifiers, keyStr); - qScreenEventDebug() << "Qt key t=" << type << ", k=" << key << ", s=" << keyStr; - } + QWindowSystemInterface::handleExtendedKeyEvent(QGuiApplication::focusWindow(), type, key, qtMod, + scan, virtualKey, modifiers, keyStr); + qScreenEventDebug() << "Qt key t=" << type << ", k=" << key << ", s=" << keyStr; } void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread) From 70f51cccaf56b4239dbe05e2131462333fbbe588 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Apr 2018 22:51:12 -0700 Subject: [PATCH 10/12] Fix Clang 6 warning about comparing different enums MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qdialogbuttonbox.cpp:862:14: error: comparison of two values with different enumeration types in switch statement ('QDialogButtonBox::ButtonRole' and 'QPlatformDialogHelper::ButtonRole') [-Wenum-compare-switch] Change-Id: I3840d727dee443318644fffd1529350b81678712 Reviewed-by: André Hartmann Reviewed-by: Thiago Macieira --- src/widgets/widgets/qdialogbuttonbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 9f5b7392300..d93e71e32fb 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -858,7 +858,7 @@ void QDialogButtonBoxPrivate::_q_handleButtonClicked() if (!guard) return; - switch (buttonRole) { + switch (QPlatformDialogHelper::ButtonRole(buttonRole)) { case QPlatformDialogHelper::AcceptRole: case QPlatformDialogHelper::YesRole: emit q->accepted(); From a25ba47c2b820117bdc60ba6bc772d6ea4093a4c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Mar 2018 17:51:09 +0800 Subject: [PATCH 11/12] QAbstractEventDispatcher: add a note about the timer range for Qt 6 Task-number: QTBUG-67383 Change-Id: I00ccecb71c774bb9b86cfffd15205b4f38088764 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qabstracteventdispatcher.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h index 4775d3d47ac..bd8da5c35d0 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.h +++ b/src/corelib/kernel/qabstracteventdispatcher.h @@ -87,6 +87,7 @@ public: QT_DEPRECATED inline void registerTimer(int timerId, int interval, QObject *object) { registerTimer(timerId, interval, Qt::CoarseTimer, object); } #endif + // ### Qt6: change interval range to qint64 (or use QDeadlineTimer) int registerTimer(int interval, Qt::TimerType timerType, QObject *object); virtual void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) = 0; virtual bool unregisterTimer(int timerId) = 0; From 43ea15d01cd491639d8cb5eb85da066f5d0a8571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 3 May 2018 18:40:29 +0200 Subject: [PATCH 12/12] macOS + FreeType: Properly distinguish memory fonts from file fonts In recent macOS versions the descriptor created from the function CTFontManagerCreateFontDescriptorFromData() will contain the NSCTFontFileURLAttribute with a value such as: file://iNmEmOrYcGfOnT_0x101d3c3a0#postscript-name=New Which means we can't use the presence of the kCTFontURLAttribute to determine that we're dealing with a file font. Instead we check for our custom kQtFontDataAttribute first, which is only set for memory fonts. Task-number: QTBUG-68044 Change-Id: Ie87d06b5a9e0e251305200b717f18ef68ccc6abc Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index f31f58945b5..91c2dc8cf08 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -451,16 +451,15 @@ QFontEngine *QCoreTextFontDatabaseEngineFactory::fontEngine(const { CTFontDescriptorRef descriptor = static_cast(usrPtr); - if (NSURL *url = descriptorAttribute(descriptor, kCTFontURLAttribute)) { + if (NSValue *fontDataValue = descriptorAttribute(descriptor, (CFStringRef)kQtFontDataAttribute)) { + QByteArray *fontData = static_cast(fontDataValue.pointerValue); + return QFontEngineFT::create(*fontData, fontDef.pixelSize, + static_cast(fontDef.hintingPreference)); + } else if (NSURL *url = descriptorAttribute(descriptor, kCTFontURLAttribute)) { Q_ASSERT(url.fileURL); QFontEngine::FaceId faceId; faceId.filename = QString::fromNSString(url.path).toUtf8(); return QFontEngineFT::create(fontDef, faceId); - - } else if (NSValue *fontDataValue = descriptorAttribute(descriptor, (CFStringRef)kQtFontDataAttribute)) { - QByteArray *fontData = static_cast(fontDataValue.pointerValue); - return QFontEngineFT::create(*fontData, fontDef.pixelSize, - static_cast(fontDef.hintingPreference)); } Q_UNREACHABLE(); }