From c1af2ced2d816932e78793295595bc1612a4700c Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 12 May 2014 11:34:00 +0200 Subject: Mac OS X: Fix crash in Harfbuzz-NG CoreText does not support multithreading, so we would get a crash in tst_qglthreads. So we disable multithreading for HB-NG. Task-number: QTBUG-38762 Change-Id: I0473037c16017ff77cbba9b11fc0b396775ef789 Reviewed-by: Konstantin Ritt --- src/3rdparty/harfbuzz-ng/src/config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/3rdparty/harfbuzz-ng/src/config.h b/src/3rdparty/harfbuzz-ng/src/config.h index cb68ab0e5b..9abb5df7f1 100644 --- a/src/3rdparty/harfbuzz-ng/src/config.h +++ b/src/3rdparty/harfbuzz-ng/src/config.h @@ -4,7 +4,6 @@ #define HAVE_OT #define HAVE_ATEXIT -#define HB_NO_MT #define HB_NO_UNICODE_FUNCS #define HB_DISABLE_DEPRECATED -- cgit v1.2.3 From 650e214d3de9dbe0af1cfa1acbf1f1a9556884ab Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Mon, 12 May 2014 21:54:55 +0100 Subject: Fix the documentation on how to use -openssl-linked. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit You set the environment /before/ you run configure. Change-Id: I6954656f892214f41b5f2ec4e3f4926eb5a9e247 Reviewed-by: Thiago Macieira Reviewed-by: Topi Reiniƶ --- src/network/doc/src/ssl.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/doc/src/ssl.qdoc b/src/network/doc/src/ssl.qdoc index e1bb1b9316..77fbec9943 100644 --- a/src/network/doc/src/ssl.qdoc +++ b/src/network/doc/src/ssl.qdoc @@ -57,7 +57,7 @@ system: \code - ./configure -openssl-linked OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' + OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' ./configure -openssl-linked \endcode To disable SSL support in a Qt build, configure Qt with the \c{-no-openssl} -- cgit v1.2.3 From f2619db30046c5b6a431a5048bcedc6b1d04688f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 12 May 2014 15:20:02 +0200 Subject: fix doc references to webkit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we can't derive the doc index paths from QMAKEMODULES, as the mkspecs dir may not live at the repo's top level. instead, explicitly announce the repo's top level build dirs in QTREPOS, and use that accordingly. Task-number: QTBUG-38862 Change-Id: I643ad2bf63c8fca0ffc44ce3457dbe8a16dcab07 Reviewed-by: Jerome Pasion Reviewed-by: Topi Reiniƶ --- mkspecs/features/qt_build_config.prf | 8 ++++++-- mkspecs/features/qt_docs.prf | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index b611e782f9..0bf90cc297 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -34,8 +34,12 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR !build_pass:!isEmpty(_QMAKE_SUPER_CACHE_):force_independent { # When doing a -prefix build of top-level qt5/qt.pro, we need to announce - # this repo's module pris' location to the other repos. - isEmpty(MODULE_QMAKE_OUTDIR): MODULE_QMAKE_OUTDIR = $$shadowed($$dirname(_QMAKE_CONF_)) + # this repo's output dir to the other repos. + MODULE_BASE_OUTDIR = $$shadowed($$dirname(_QMAKE_CONF_)) + !contains(QTREPOS, $$MODULE_BASE_OUTDIR): \ + cache(QTREPOS, add super, MODULE_BASE_OUTDIR) + # This repo's module pris' location needs to be made known to qmake. + isEmpty(MODULE_QMAKE_OUTDIR): MODULE_QMAKE_OUTDIR = $$MODULE_BASE_OUTDIR modpath = $$MODULE_QMAKE_OUTDIR/mkspecs/modules !contains(QMAKEMODULES, $$modpath): \ cache(QMAKEMODULES, add super, modpath) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index be3cd5273c..8e63fa61a7 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -23,8 +23,9 @@ QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR !build_online_docs: \ QDOC += -installdir $$[QT_INSTALL_DOCS] DOC_INDEXES = -for(qmod, QMAKEMODULES): \ - DOC_INDEXES += -indexdir $$section(qmod, /, 0, -3)/doc +for(qrep, QTREPOS): \ + exists($$qrep/doc): \ + DOC_INDEXES += -indexdir $$qrep/doc qtver.name = QT_VERSION qtver.value = $$VERSION isEmpty(qtver.value): qtver.value = $$MODULE_VERSION -- cgit v1.2.3 From b23e72a772a5abfdf9784ab80db9a4d620137515 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 12 May 2014 17:05:36 -0700 Subject: Fix stateful handling of invalid UTF-8 straddling buffer borders When a UTF-8 sequences is too short, QUtf8Functions::fromUtf8 returns EndOfString. If the decoder is stateful, we must save the state and then restart it when more data is supplied. The new stateful decoder (8dd47e34b9b96ac27a99cdcf10b8aec506882fc2) mishandled the Error case by advancing the src pointer by a negative number, thus causing a buffer overflow (the issue of the task). And it also did not handle the len == 0 case properly, though neither did the older decoder. Task-number: QTBUG-38939 Change-Id: Ie03d7c55a04e51ee838ccdb3a01e5b989d8e67aa Reviewed-by: Kai Koehne Reviewed-by: Lars Knoll --- src/corelib/codecs/qutfcodec.cpp | 44 ++++++++-- .../corelib/codecs/qtextcodec/tst_qtextcodec.cpp | 96 ++++++++++++++++++++++ 2 files changed, 132 insertions(+), 8 deletions(-) diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 072cda63aa..c5f580e13d 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -237,7 +237,20 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve QString QUtf8::convertToUnicode(const char *chars, int len) { - QString result(len + 1, Qt::Uninitialized); // worst case + // UTF-8 to UTF-16 always needs the exact same number of words or less: + // UTF-8 UTF-16 + // 1 byte 1 word + // 2 bytes 1 word + // 3 bytes 1 word + // 4 bytes 2 words (one surrogate pair) + // That is, we'll use the full buffer if the input is US-ASCII (1-byte UTF-8), + // half the buffer for U+0080-U+07FF text (e.g., Greek, Cyrillic, Arabic) or + // non-BMP text, and one third of the buffer for U+0800-U+FFFF text (e.g, CJK). + // + // The table holds for invalid sequences too: we'll insert one replacement char + // per invalid byte. + QString result(len, Qt::Uninitialized); + ushort *dst = reinterpret_cast(const_cast(result.constData())); const uchar *src = reinterpret_cast(chars); const uchar *end = src + len; @@ -282,7 +295,18 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte int res; uchar ch = 0; - QString result(need + len + 1, Qt::Uninitialized); // worst case + // See above for buffer requirements for stateless decoding. However, that + // fails if the state is not empty. The following situations can add to the + // requirements: + // state contains chars starts with requirement + // 1 of 2 bytes valid continuation 0 + // 2 of 3 bytes same 0 + // 3 bytes of 4 same +1 (need to insert surrogate pair) + // 1 of 2 bytes invalid continuation +1 (need to insert replacement and restart) + // 2 of 3 bytes same +1 (same) + // 3 of 4 bytes same +1 (same) + QString result(need + len + 1, Qt::Uninitialized); + ushort *dst = reinterpret_cast(const_cast(result.constData())); const uchar *src = reinterpret_cast(chars); const uchar *end = src + len; @@ -305,15 +329,17 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte const uchar *begin = &remainingCharsData[1]; res = QUtf8Functions::fromUtf8(remainingCharsData[0], dst, begin, static_cast(remainingCharsData) + remainingCharsCount + newCharsToCopy); - if (res == QUtf8BaseTraits::EndOfString) { + if (res == QUtf8BaseTraits::Error || (res == QUtf8BaseTraits::EndOfString && len == 0)) { + // special case for len == 0: + // if we were supplied an empty string, terminate the previous, unfinished sequence with error + ++invalid; + *dst++ = replacement; + } else if (res == QUtf8BaseTraits::EndOfString) { // if we got EndOfString again, then there were too few bytes in src; // copy to our state and return state->remainingChars = remainingCharsCount + newCharsToCopy; memcpy(&state->state_data[0], remainingCharsData, state->remainingChars); return QString(); - } else if (res == QUtf8BaseTraits::Error) { - ++invalid; - *dst++ = replacement; } else if (!headerdone && res >= 0) { // eat the UTF-8 BOM headerdone = true; @@ -322,8 +348,10 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte } // adjust src now that we have maybe consumed a few chars - //Q_ASSERT(res > remainingCharsCount) - src += res - remainingCharsCount; + if (res >= 0) { + Q_ASSERT(res > remainingCharsCount); + src += res - remainingCharsCount; + } } } diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp index 12b81ee7d4..54e8f8c386 100644 --- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp @@ -80,6 +80,9 @@ private slots: void utf8bom_data(); void utf8bom(); + void utf8stateful_data(); + void utf8stateful(); + void utfHeaders_data(); void utfHeaders(); @@ -1611,6 +1614,99 @@ void tst_QTextCodec::utf8bom() QCOMPARE(codec->toUnicode(data.constData(), data.length(), &state), result); } +void tst_QTextCodec::utf8stateful_data() +{ + QTest::addColumn("buffer1"); + QTest::addColumn("buffer2"); + QTest::addColumn("result"); // null QString indicates decoder error + + // valid buffer continuations + QTest::newRow("1of2+valid") << QByteArray("\xc2") << QByteArray("\xa0") << "\xc2\xa0"; + QTest::newRow("1of3+valid") << QByteArray("\xe0") << QByteArray("\xa0\x80") << "\xe0\xa0\x80"; + QTest::newRow("2of3+valid") << QByteArray("\xe0\xa0") << QByteArray("\x80") << "\xe0\xa0\x80"; + QTest::newRow("1of4+valid") << QByteArray("\360") << QByteArray("\220\210\203") << "\360\220\210\203"; + QTest::newRow("2of4+valid") << QByteArray("\360\220") << QByteArray("\210\203") << "\360\220\210\203"; + QTest::newRow("3of4+valid") << QByteArray("\360\220\210") << QByteArray("\203") << "\360\220\210\203"; + QTest::newRow("1ofBom+valid") << QByteArray("\xef") << QByteArray("\xbb\xbf") << ""; + QTest::newRow("2ofBom+valid") << QByteArray("\xef\xbb") << QByteArray("\xbf") << ""; + + // invalid continuation + QTest::newRow("1of2+invalid") << QByteArray("\xc2") << QByteArray("a") << QString(); + QTest::newRow("1of3+invalid") << QByteArray("\xe0") << QByteArray("a") << QString(); + QTest::newRow("2of3+invalid") << QByteArray("\xe0\xa0") << QByteArray("a") << QString(); + QTest::newRow("1of4+invalid") << QByteArray("\360") << QByteArray("a") << QString(); + QTest::newRow("2of4+invalid") << QByteArray("\360\220") << QByteArray("a") << QString(); + QTest::newRow("3of4+invalid") << QByteArray("\360\220\210") << QByteArray("a") << QString(); + + // invalid: sequence too short (the empty second buffer causes a state reset) + QTest::newRow("1of2+empty") << QByteArray("\xc2") << QByteArray() << QString(); + QTest::newRow("1of3+empty") << QByteArray("\xe0") << QByteArray() << QString(); + QTest::newRow("2of3+empty") << QByteArray("\xe0\xa0") << QByteArray() << QString(); + QTest::newRow("1of4+empty") << QByteArray("\360") << QByteArray() << QString(); + QTest::newRow("2of4+empty") << QByteArray("\360\220") << QByteArray() << QString(); + QTest::newRow("3of4+empty") << QByteArray("\360\220\210") << QByteArray() << QString(); + + // overlong sequence: + QTest::newRow("overlong-1of2") << QByteArray("\xc1") << QByteArray("\x81") << QString(); + QTest::newRow("overlong-1of3") << QByteArray("\xe0") << QByteArray("\x81\x81") << QString(); + QTest::newRow("overlong-2of3") << QByteArray("\xe0\x81") << QByteArray("\x81") << QString(); + QTest::newRow("overlong-1of4") << QByteArray("\xf0") << QByteArray("\x80\x81\x81") << QString(); + QTest::newRow("overlong-2of4") << QByteArray("\xf0\x80") << QByteArray("\x81\x81") << QString(); + QTest::newRow("overlong-3of4") << QByteArray("\xf0\x80\x81") << QByteArray("\x81") << QString(); + + // out of range: + // leading byte 0xF4 can produce codepoints above U+10FFFF, which aren't valid + QTest::newRow("outofrange1-1of4") << QByteArray("\xf4") << QByteArray("\x90\x80\x80") << QString(); + QTest::newRow("outofrange1-2of4") << QByteArray("\xf4\x90") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange1-3of4") << QByteArray("\xf4\x90\x80") << QByteArray("\x80") << QString(); + QTest::newRow("outofrange2-1of4") << QByteArray("\xf5") << QByteArray("\x90\x80\x80") << QString(); + QTest::newRow("outofrange2-2of4") << QByteArray("\xf5\x90") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange2-3of4") << QByteArray("\xf5\x90\x80") << QByteArray("\x80") << QString(); + QTest::newRow("outofrange-1of5") << QByteArray("\xf8") << QByteArray("\x88\x80\x80\x80") << QString(); + QTest::newRow("outofrange-2of5") << QByteArray("\xf8\x88") << QByteArray("\x80\x80\x80") << QString(); + QTest::newRow("outofrange-3of5") << QByteArray("\xf8\x88\x80") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange-4of5") << QByteArray("\xf8\x88\x80\x80") << QByteArray("\x80") << QString(); + QTest::newRow("outofrange-1of6") << QByteArray("\xfc") << QByteArray("\x84\x80\x80\x80\x80") << QString(); + QTest::newRow("outofrange-2of6") << QByteArray("\xfc\x84") << QByteArray("\x80\x80\x80\x80") << QString(); + QTest::newRow("outofrange-3of6") << QByteArray("\xfc\x84\x80") << QByteArray("\x80\x80\x80") << QString(); + QTest::newRow("outofrange-4of6") << QByteArray("\xfc\x84\x80\x80") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange-5of6") << QByteArray("\xfc\x84\x80\x80\x80") << QByteArray("\x80") << QString(); +} + +void tst_QTextCodec::utf8stateful() +{ + QFETCH(QByteArray, buffer1); + QFETCH(QByteArray, buffer2); + QFETCH(QString, result); + + QTextCodec *utf8codec = QTextCodec::codecForName("utf-8"); + QVERIFY(utf8codec); + + QTextCodec::ConverterState state; + memset(&state, 0, sizeof state); + + QString decoded1 = utf8codec->toUnicode(buffer1, buffer1.size(), &state); + if (result.isNull()) { + // the decoder may have found an early error (invalidChars > 0): + // if it has, remainingChars == 0; + // if it hasn't, then it must have a state + QVERIFY2((state.remainingChars == 0) != (state.invalidChars == 0), + "remainingChars = " + QByteArray::number(state.remainingChars) + + "; invalidChars = " + QByteArray::number(state.invalidChars)); + } else { + QVERIFY(state.remainingChars > 0); + QCOMPARE(state.invalidChars, 0); + } + + QString decoded2 = utf8codec->toUnicode(buffer2, buffer2.size(), &state); + QCOMPARE(state.remainingChars, 0); + if (result.isNull()) { + QVERIFY(state.invalidChars > 0); + } else { + QCOMPARE(decoded1 + decoded2, result); + } +} + void tst_QTextCodec::utfHeaders_data() { QTest::addColumn("codecName"); -- cgit v1.2.3 From 7cc175c9d69102c15486ac0506031cb6d09741d3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 12 May 2014 13:48:38 +0200 Subject: Assume unlabelled mouse buttons are default buttons This patch fixes legacy wheel scrolling for XInput2 drivers that fail to label mouse buttons correctly. Task-number: QTBUG-38937 Change-Id: I659890517e749dc0039489e0b7a8c38be1065d33 Reviewed-by: Erik Verbruggen Reviewed-by: Laszlo Agocs Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index efa1691780..64cb33979b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -148,15 +148,17 @@ void QXcbConnection::initializeXInput2() } case XIButtonClass: { XIButtonClassInfo *bci = reinterpret_cast(devices[i].classes[c]); - for (int i=0; i < bci->num_buttons; ++i) { - const int buttonAtom = qatom(bci->labels[i]); - if (buttonAtom == QXcbAtom::ButtonWheelUp - || buttonAtom == QXcbAtom::ButtonWheelDown) { + if (bci->num_buttons >= 5) { + Atom label4 = bci->labels[3]; + Atom label5 = bci->labels[4]; + if ((!label4 || qatom(label4) == QXcbAtom::ButtonWheelUp) && (!label5 || qatom(label5) == QXcbAtom::ButtonWheelDown)) scrollingDevice.legacyOrientations |= Qt::Vertical; - } else if (buttonAtom == QXcbAtom::ButtonHorizWheelLeft - || buttonAtom == QXcbAtom::ButtonHorizWheelRight) { + } + if (bci->num_buttons >= 7) { + Atom label6 = bci->labels[5]; + Atom label7 = bci->labels[6]; + if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight)) scrollingDevice.legacyOrientations |= Qt::Horizontal; - } } break; } -- cgit v1.2.3 From a8877f529dffa68a8c1339cd10c32e3b783bba66 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 12 May 2014 15:45:24 +0200 Subject: Scrolling devices should not override touch or tablet devices XISelectEvents override any earlier set event mask for the same device ids. This may cause touch devices to stop reporting touch events if they export scroll buttons or axis. The patch checks for each scrolling device if they are also a touch devices and includes the necessary bitmask if they are, and skips any devices also recognized as tablet devices as they already capture all relevant events. In addition tablet event handling will no longer block handling of wheel button events for scroll devices with the same device id. Task-number: QTBUG-38935 Change-Id: Ifd4657beb0a0cebffe89d3470ef2bd605eb3552e Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 46 +++++++++++++++++------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 64cb33979b..eb7b220c43 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -248,6 +248,7 @@ void QXcbConnection::xi2Select(xcb_window_t window) } #endif // XCB_USE_XINPUT22 + QSet tabletDevices; #ifndef QT_NO_TABLETEVENT // For each tablet, select some additional event types. // Press, motion, etc. events must never be selected for _all_ devices @@ -255,15 +256,19 @@ void QXcbConnection::xi2Select(xcb_window_t window) // similar handlers useless and we have no intention to infect // all the pure xcb code with Xlib-based XI2. if (!m_tabletData.isEmpty()) { + unsigned int tabletBitMask = bitMask; + unsigned char *xiTabletBitMask = reinterpret_cast(&tabletBitMask); QVector xiEventMask(m_tabletData.count()); - bitMask |= XI_ButtonPressMask; - bitMask |= XI_ButtonReleaseMask; - bitMask |= XI_MotionMask; - bitMask |= XI_PropertyEventMask; + tabletBitMask |= XI_ButtonPressMask; + tabletBitMask |= XI_ButtonReleaseMask; + tabletBitMask |= XI_MotionMask; + tabletBitMask |= XI_PropertyEventMask; for (int i = 0; i < m_tabletData.count(); ++i) { - xiEventMask[i].deviceid = m_tabletData.at(i).deviceId; - xiEventMask[i].mask_len = sizeof(bitMask); - xiEventMask[i].mask = xiBitMask; + int deviceId = m_tabletData.at(i).deviceId; + tabletDevices.insert(deviceId); + xiEventMask[i].deviceid = deviceId; + xiEventMask[i].mask_len = sizeof(tabletBitMask); + xiEventMask[i].mask = xiTabletBitMask; } XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count()); } @@ -273,17 +278,30 @@ void QXcbConnection::xi2Select(xcb_window_t window) // Enable each scroll device if (!m_scrollingDevices.isEmpty()) { QVector xiEventMask(m_scrollingDevices.size()); - bitMask = XI_MotionMask; + unsigned int scrollBitMask = 0; + unsigned char *xiScrollBitMask = reinterpret_cast(&scrollBitMask); + scrollBitMask = XI_MotionMask; + scrollBitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; bitMask |= XI_ButtonReleaseMask; int i=0; Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) { + if (tabletDevices.contains(scrollingDevice.deviceId)) + continue; // All necessary events are already captured. xiEventMask[i].deviceid = scrollingDevice.deviceId; - xiEventMask[i].mask_len = sizeof(bitMask); - xiEventMask[i].mask = xiBitMask; + if (m_touchDevices.contains(scrollingDevice.deviceId)) { + xiEventMask[i].mask_len = sizeof(bitMask); + xiEventMask[i].mask = xiBitMask; + } else { + xiEventMask[i].mask_len = sizeof(scrollBitMask); + xiEventMask[i].mask = xiScrollBitMask; + } i++; } - XISelectEvents(xDisplay, window, xiEventMask.data(), m_scrollingDevices.size()); + XISelectEvents(xDisplay, window, xiEventMask.data(), i); } +#else + Q_UNUSED(xiBitMask); #endif } @@ -657,13 +675,15 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) if (reinterpret_cast(event)->detail == 1) { // ignore the physical buttons on the stylus tabletData->down = true; xi2ReportTabletEvent(*tabletData, xiEvent); - } + } else + handled = false; break; case XI_ButtonRelease: // stylus up if (reinterpret_cast(event)->detail == 1) { tabletData->down = false; xi2ReportTabletEvent(*tabletData, xiEvent); - } + } else + handled = false; break; case XI_Motion: // Report TabletMove only when the stylus is touching the tablet. -- cgit v1.2.3 From 9a747cb5b7866d440211aa1dc4e07dd4ff914c2c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 12 May 2014 13:52:29 -0700 Subject: Fix an off-by-4 error in qHash with CRC32 I tested only the 64-bit build. The 32-bit build was reading garbage past the end of the strings in some cases. Change-Id: If6d239754e16a17cc4e8bb71e2b7778429dfa7ba Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Lars Knoll --- src/corelib/tools/qhash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index a5d14a3535..ca645636e4 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -125,7 +125,7 @@ static uint crc32(const Char *ptr, size_t len, uint h) # else p += 4; for ( ; p <= e; p += 4) - h = _mm_crc32_u32(h, *reinterpret_cast(p)); + h = _mm_crc32_u32(h, *reinterpret_cast(p - 4)); p -= 4; len = e - p; # endif -- cgit v1.2.3