Skip to content

Commit

Permalink
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
Browse files Browse the repository at this point in the history
  • Loading branch information
liangqi committed Mar 31, 2020
2 parents 82a39f1 + 947e1f4 commit 7ed097b
Show file tree
Hide file tree
Showing 14 changed files with 386 additions and 62 deletions.
3 changes: 2 additions & 1 deletion mkspecs/features/win32/opengl.prf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ QT_FOR_CONFIG += gui
defineTest(prependOpenGlLib) {
path = $$QT.core.libs/$$QMAKE_PREFIX_STATICLIB$$1
ext = .$$QMAKE_EXTENSION_STATICLIB
!mingw|qtConfig(debug_and_release): debug_suffix = "d"
QMAKE_LIBS_OPENGL_ES2 = $${path}$${ext} $$QMAKE_LIBS_OPENGL_ES2
QMAKE_LIBS_OPENGL_ES2_DEBUG = $${path}d$${ext} $$QMAKE_LIBS_OPENGL_ES2_DEBUG
QMAKE_LIBS_OPENGL_ES2_DEBUG = $${path}$${debug_suffix}$${ext} $$QMAKE_LIBS_OPENGL_ES2_DEBUG
export(QMAKE_LIBS_OPENGL_ES2)
export(QMAKE_LIBS_OPENGL_ES2_DEBUG)
}
Expand Down
37 changes: 23 additions & 14 deletions src/3rdparty/tinycbor/tests/parser/data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ void addValidationColumns()
QTest::addColumn<CborError>("expectedError");
}

void addValidationData()
void addValidationData(size_t minInvalid = ~size_t(0))
{
// illegal numbers are future extension points
QTest::newRow("illegal-number-in-unsigned-1") << raw("\x81\x1c") << 0 << CborErrorIllegalNumber;
Expand Down Expand Up @@ -488,26 +488,35 @@ void addValidationData()
QTest::newRow("map-break-after-value-tag2") << raw("\x81\xbf\0\xd8\x20\xff") << 0 << CborErrorUnexpectedBreak;

// check for pointer additions wrapping over the limit of the address space
CborError tooLargeOn32bit = (sizeof(void *) == 4) ? CborErrorDataTooLarge : CborErrorUnexpectedEOF;
auto wraparoundError = [minInvalid](uint64_t encodedSize) {
if (encodedSize > minInvalid)
return CborErrorDataTooLarge;
return CborErrorUnexpectedEOF;
};
constexpr uint64_t FourGB = UINT32_MAX + UINT64_C(1);
// on 32-bit systems, this is a -1
QTest::newRow("bytearray-wraparound1") << raw("\x81\x5a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-wraparound1") << raw("\x81\x7a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-wraparound1") << raw("\x81\x5a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
QTest::newRow("string-wraparound1") << raw("\x81\x7a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
// on 32-bit systems, a 4GB addition could be dropped
QTest::newRow("bytearray-wraparound2") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
QTest::newRow("string-wraparound2") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
QTest::newRow("bytearray-wraparound2") << raw("\x81\x5b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
QTest::newRow("string-wraparound2") << raw("\x81\x7b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
// on 64-bit systems, this could be a -1
QTest::newRow("bytearray-wraparound3") << raw("\x81\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
QTest::newRow("string-wraparound3") << raw("\x81\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
QTest::newRow("bytearray-wraparound3") << raw("\x81\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);
QTest::newRow("string-wraparound3") << raw("\x81\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);

// ditto on chunks
QTest::newRow("bytearray-chunk-wraparound1") << raw("\x81\x5f\x5a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("string-chunk-wraparound1") << raw("\x81\x7f\x7a\xff\xff\xff\xff") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("bytearray-chunk-wraparound1") << raw("\x81\x5f\x5a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
QTest::newRow("string-chunk-wraparound1") << raw("\x81\x7f\x7a\xff\xff\xff\xff") << 0 << wraparoundError(UINT32_MAX);
// on 32-bit systems, a 4GB addition could be dropped
QTest::newRow("bytearray-chunk-wraparound2") << raw("\x81\x5f\x5b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
QTest::newRow("string-chunk-wraparound2") << raw("\x81\x7f\x7b\0\0\0\1\0\0\0\0") << 0 << tooLargeOn32bit;
QTest::newRow("bytearray-chunk-wraparound2") << raw("\x81\x5f\x5b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
QTest::newRow("string-chunk-wraparound2") << raw("\x81\x7f\x7b\0\0\0\1\0\0\0\0") << 0 << wraparoundError(FourGB);
// on 64-bit systems, this could be a -1
QTest::newRow("bytearray-chunk-wraparound3") << raw("\x81\x5f\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
QTest::newRow("string-chunk-wraparound3") << raw("\x81\x7f\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0 << tooLargeOn32bit;
QTest::newRow("bytearray-chunk-wraparound3") << raw("\x81\x5f\x5b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);
QTest::newRow("string-chunk-wraparound3") << raw("\x81\x7f\x7b\xff\xff\xff\xff\xff\xff\xff\xff") << 0
<< wraparoundError(UINT64_MAX);

QTest::newRow("eof-after-array") << raw("\x81") << 0 << CborErrorUnexpectedEOF;
QTest::newRow("eof-after-array2") << raw("\x81\x78\x20") << 0 << CborErrorUnexpectedEOF;
Expand Down
35 changes: 26 additions & 9 deletions src/corelib/serialization/qcborstreamreader.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 Intel Corporation.
** Copyright (C) 2020 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
Expand Down Expand Up @@ -42,6 +42,7 @@
#define CBOR_NO_ENCODER_API
#include <private/qcborcommon_p.h>

#include <private/qbytearray_p.h>
#include <private/qnumeric_p.h>
#include <private/qutfcodec_p.h>
#include <qdebug.h>
Expand Down Expand Up @@ -1055,6 +1056,10 @@ bool QCborStreamReader::next(int maxRecursion)
} else if (isString() || isByteArray()) {
auto r = _readByteArray_helper();
while (r.status == Ok) {
if (isString() && r.data.size() > MaxStringSize) {
d->handleError(CborErrorDataTooLarge);
break;
}
if (isString() && !QUtf8::isValidUtf8(r.data, r.data.size()).isValidUtf8) {
d->handleError(CborErrorInvalidUtf8TextString);
break;
Expand Down Expand Up @@ -1337,15 +1342,23 @@ QCborStreamReader::StringResult<QString> QCborStreamReader::_readString_helper()
result.status = r.status;

if (r.status == Ok) {
QTextCodec::ConverterState cs;
result.data = QUtf8::convertToUnicode(r.data, r.data.size(), &cs);
if (cs.invalidChars == 0 && cs.remainingChars == 0)
return result;
// See QUtf8::convertToUnicode() a detailed explanation of why this
// conversion uses the same number of words or less.
CborError err = CborNoError;
if (r.data.size() > MaxStringSize) {
err = CborErrorDataTooLarge;
} else {
QTextCodec::ConverterState cs;
result.data = QUtf8::convertToUnicode(r.data, r.data.size(), &cs);
if (cs.invalidChars != 0 || cs.remainingChars != 0)
err = CborErrorInvalidUtf8TextString;
}

d->handleError(CborErrorInvalidUtf8TextString);
result.data.clear();
result.status = Error;
return result;
if (err) {
d->handleError(err);
result.data.clear();
result.status = Error;
}
}
return result;
}
Expand Down Expand Up @@ -1373,6 +1386,10 @@ QCborStreamReader::StringResult<QByteArray> QCborStreamReader::_readByteArray_he
qsizetype len = _currentStringChunkSize();
if (len < 0)
return result;
if (len > MaxByteArraySize) {
d->handleError(CborErrorDataTooLarge);
return result;
}

result.data.resize(len);
auto r = readStringChunk(result.data.data(), len);
Expand Down
27 changes: 19 additions & 8 deletions src/corelib/serialization/qcborvalue.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 Intel Corporation.
** Copyright (C) 2020 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
Expand Down Expand Up @@ -53,6 +53,7 @@

#include <qendian.h>
#include <qlocale.h>
#include <private/qbytearray_p.h>
#include <private/qnumeric_p.h>
#include <private/qsimd_p.h>

Expand Down Expand Up @@ -1553,6 +1554,8 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
// and calculate the final size
if (add_overflow(offset, increment, &newSize))
return -1;
if (newSize > MaxByteArraySize)
return -1;

// since usedData <= data.size(), this can't overflow
usedData += increment;
Expand Down Expand Up @@ -1627,13 +1630,6 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
setErrorInReader(reader, { QCborError::DataTooLarge });
}

if (r.status == QCborStreamReader::Error) {
// There can only be errors if there was data to be read.
Q_ASSERT(e.flags & Element::HasByteData);
data.truncate(e.value);
return;
}

// update size
if (e.flags & Element::HasByteData) {
auto b = new (dataPtr() + e.value) ByteData;
Expand All @@ -1645,6 +1641,21 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
Q_ASSERT(e.type == QCborValue::String);
e.flags |= Element::StringIsAscii;
}

// check that this UTF-8 text string can be loaded onto a QString
if (e.type == QCborValue::String) {
if (Q_UNLIKELY(b->len > MaxStringSize)) {
setErrorInReader(reader, { QCborError::DataTooLarge });
r.status = QCborStreamReader::Error;
}
}
}

if (r.status == QCborStreamReader::Error) {
// There can only be errors if there was data to be read.
Q_ASSERT(e.flags & Element::HasByteData);
data.truncate(e.value);
return;
}

elements.append(e);
Expand Down
7 changes: 3 additions & 4 deletions src/corelib/text/qbytearray_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,9 @@

QT_BEGIN_NAMESPACE

enum {
// Define as enum to force inlining. Don't expose MaxAllocSize in a public header.
MaxByteArraySize = MaxAllocSize - sizeof(std::remove_pointer<QByteArray::DataPtr>::type)
};
// -1 because of the terminating NUL
constexpr qsizetype MaxByteArraySize = MaxAllocSize - sizeof(std::remove_pointer<QByteArray::DataPtr>::type) - 1;
constexpr qsizetype MaxStringSize = (MaxAllocSize - sizeof(std::remove_pointer<QByteArray::DataPtr>::type)) / 2 - 1;

QT_END_NAMESPACE

Expand Down
6 changes: 6 additions & 0 deletions src/testlib/qabstractitemmodeltester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ QAbstractItemModelTester::FailureReportingMode QAbstractItemModelTester::failure
return d->failureReportingMode;
}

bool QAbstractItemModelTester::verify(bool statement, const char *statementStr, const char *description, const char *file, int line)
{
Q_D(QAbstractItemModelTester);
return d->verify(statement, statementStr, description, file, line);
}

QAbstractItemModelTesterPrivate::QAbstractItemModelTesterPrivate(QAbstractItemModel *model, QAbstractItemModelTester::FailureReportingMode failureReportingMode)
: model(model),
failureReportingMode(failureReportingMode),
Expand Down
12 changes: 9 additions & 3 deletions src/widgets/itemviews/qabstractitemview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1844,10 +1844,16 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
|| edit(index, NoEditTriggers, event))
return;

if (d->selectionMode != SingleSelection)
topLeft = d->pressedPosition - d->offset();
else
if (d->selectionMode != SingleSelection) {
// Use the current selection start index if it is valid as this will be based on the
// start of the selection and not the last item being pressed which can be different
// when in extended selection
topLeft = d->currentSelectionStartIndex.isValid()
? visualRect(d->currentSelectionStartIndex).center()
: d->pressedPosition - d->offset();
} else {
topLeft = bottomRight;
}

d->checkMouseMove(index);

Expand Down
8 changes: 5 additions & 3 deletions src/widgets/kernel/qwidgetwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::ContextMenuOnMouseRelease).toBool() ?
QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
if (QApplicationPrivate::inPopupMode()) {
QWidget *activePopupWidget = QApplication::activePopupWidget();
QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
QPoint mapped = event->pos();
if (activePopupWidget != m_widget)
mapped = activePopupWidget->mapFromGlobal(event->globalPos());
Expand Down Expand Up @@ -565,9 +565,11 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
#endif
if ((event->type() != QEvent::MouseButtonPress)
|| !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) {

// if the widget that was pressed is gone, then deliver move events without buttons
const auto buttons = event->type() == QEvent::MouseMove && qt_button_down == nullptr
? Qt::NoButton : event->buttons();
QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers(), event->source());
event->button(), buttons, event->modifiers(), event->source());
e.setTimestamp(event->timestamp());
QApplicationPrivate::sendMouseEvent(receiver, &e, receiver, receiver->window(), &qt_button_down, qt_last_mouse_receiver);
qt_last_mouse_receiver = receiver;
Expand Down
Loading

0 comments on commit 7ed097b

Please sign in to comment.