Merge remote-tracking branch 'origin/5.14' into 5.15
Conflicts: src/corelib/serialization/qcborvalue.cpp Change-Id: I539d8cae5fd413b8a6c9c5d8a6364c79c8133a0a
This commit is contained in:
commit
4752bd7718
@ -845,7 +845,7 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(const gl::Context *context,
|
||||
stateManager->setRenderTarget(mBackBufferRTView.get(), nullptr);
|
||||
|
||||
// Set the viewport
|
||||
stateManager->setSimpleViewport(mWidth, mHeight);
|
||||
stateManager->setSimpleViewport(width, height);
|
||||
|
||||
// Apply textures
|
||||
stateManager->setSimplePixelTextureAndSampler(mOffscreenSRView, mPassThroughSampler);
|
||||
|
@ -0,0 +1,27 @@
|
||||
From 029d42d1049dcde7950c11fb9adf07c07a8c4c02 Mon Sep 17 00:00:00 2001
|
||||
From: Oliver Wolff <oliver.wolff@qt.io>
|
||||
Date: Wed, 18 Mar 2020 10:56:53 +0100
|
||||
Subject: [PATCH] ANGLE: Fix resizing of windows (Take 2)
|
||||
|
||||
Task-number: QTBUG-62475
|
||||
Change-Id: I0ea17e7875906508941ae64bb396a4236928b0f9
|
||||
---
|
||||
.../angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
|
||||
index e8f13b388f..9ece77ecbc 100644
|
||||
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
|
||||
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
|
||||
@@ -845,7 +845,7 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(const gl::Context *context,
|
||||
stateManager->setRenderTarget(mBackBufferRTView.get(), nullptr);
|
||||
|
||||
// Set the viewport
|
||||
- stateManager->setSimpleViewport(mWidth, mHeight);
|
||||
+ stateManager->setSimpleViewport(width, height);
|
||||
|
||||
// Apply textures
|
||||
stateManager->setSimplePixelTextureAndSampler(mOffscreenSRView, mPassThroughSampler);
|
||||
--
|
||||
2.20.1.windows.1
|
||||
|
@ -844,11 +844,6 @@ static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d)
|
||||
return QCborValue::Tag;
|
||||
}
|
||||
|
||||
#if QT_CONFIG(cborstreamreader)
|
||||
// in qcborstream.cpp
|
||||
extern void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error);
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(cborstreamwriter)
|
||||
static void writeDoubleToCbor(QCborStreamWriter &writer, double d, QCborValue::EncodingOptions opt)
|
||||
{
|
||||
@ -1462,23 +1457,59 @@ static Element decodeBasicValueFromCbor(QCborStreamReader &reader)
|
||||
return e;
|
||||
}
|
||||
|
||||
static inline QCborContainerPrivate *createContainerFromCbor(QCborStreamReader &reader)
|
||||
static inline QCborContainerPrivate *createContainerFromCbor(QCborStreamReader &reader, int remainingRecursionDepth)
|
||||
{
|
||||
auto d = new QCborContainerPrivate;
|
||||
d->ref.storeRelaxed(1);
|
||||
d->decodeFromCbor(reader);
|
||||
if (Q_UNLIKELY(remainingRecursionDepth == 0)) {
|
||||
QCborContainerPrivate::setErrorInReader(reader, { QCborError::NestingTooDeep });
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QCborContainerPrivate *d = nullptr;
|
||||
int mapShift = reader.isMap() ? 1 : 0;
|
||||
if (reader.isLengthKnown()) {
|
||||
quint64 len = reader.length();
|
||||
|
||||
// Clamp allocation to 1M elements (avoids crashing due to corrupt
|
||||
// stream or loss of precision when converting from quint64 to
|
||||
// QVector::size_type).
|
||||
len = qMin(len, quint64(1024 * 1024 - 1));
|
||||
if (len) {
|
||||
d = new QCborContainerPrivate;
|
||||
d->ref.storeRelaxed(1);
|
||||
d->elements.reserve(qsizetype(len) << mapShift);
|
||||
}
|
||||
} else {
|
||||
d = new QCborContainerPrivate;
|
||||
d->ref.storeRelaxed(1);
|
||||
}
|
||||
|
||||
reader.enterContainer();
|
||||
if (reader.lastError() != QCborError::NoError)
|
||||
return d;
|
||||
|
||||
while (reader.hasNext() && reader.lastError() == QCborError::NoError)
|
||||
d->decodeValueFromCbor(reader, remainingRecursionDepth - 1);
|
||||
|
||||
if (reader.lastError() == QCborError::NoError)
|
||||
reader.leaveContainer();
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static QCborValue taggedValueFromCbor(QCborStreamReader &reader)
|
||||
static QCborValue taggedValueFromCbor(QCborStreamReader &reader, int remainingRecursionDepth)
|
||||
{
|
||||
if (Q_UNLIKELY(remainingRecursionDepth == 0)) {
|
||||
QCborContainerPrivate::setErrorInReader(reader, { QCborError::NestingTooDeep });
|
||||
return QCborValue::Invalid;
|
||||
}
|
||||
|
||||
auto d = new QCborContainerPrivate;
|
||||
d->append(reader.toTag());
|
||||
reader.next();
|
||||
|
||||
if (reader.lastError() == QCborError::NoError) {
|
||||
// decode tagged value
|
||||
d->decodeValueFromCbor(reader);
|
||||
d->decodeValueFromCbor(reader, remainingRecursionDepth - 1);
|
||||
}
|
||||
|
||||
QCborValue::Type type;
|
||||
@ -1494,6 +1525,13 @@ static QCborValue taggedValueFromCbor(QCborStreamReader &reader)
|
||||
return QCborContainerPrivate::makeValue(type, -1, d);
|
||||
}
|
||||
|
||||
// in qcborstream.cpp
|
||||
extern void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error);
|
||||
inline void QCborContainerPrivate::setErrorInReader(QCborStreamReader &reader, QCborError error)
|
||||
{
|
||||
qt_cbor_stream_set_error(reader.d.data(), error);
|
||||
}
|
||||
|
||||
void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
|
||||
{
|
||||
auto addByteData_local = [this](QByteArray::size_type len) -> qint64 {
|
||||
@ -1538,7 +1576,7 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
|
||||
return; // error
|
||||
if (len != rawlen) {
|
||||
// truncation
|
||||
qt_cbor_stream_set_error(reader.d.data(), { QCborError::DataTooLarge });
|
||||
setErrorInReader(reader, { QCborError::DataTooLarge });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1548,7 +1586,7 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
|
||||
e.value = addByteData_local(len);
|
||||
if (e.value < 0) {
|
||||
// overflow
|
||||
qt_cbor_stream_set_error(reader.d.data(), { QCborError::DataTooLarge });
|
||||
setErrorInReader(reader, { QCborError::DataTooLarge });
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1562,7 +1600,7 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
|
||||
auto utf8result = QUtf8::isValidUtf8(dataPtr() + data.size() - len, len);
|
||||
if (!utf8result.isValidUtf8) {
|
||||
r.status = QCborStreamReader::Error;
|
||||
qt_cbor_stream_set_error(reader.d.data(), { QCborError::InvalidUtf8String });
|
||||
setErrorInReader(reader, { QCborError::InvalidUtf8String });
|
||||
break;
|
||||
}
|
||||
isAscii = isAscii && utf8result.isValidAscii;
|
||||
@ -1586,7 +1624,7 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
|
||||
|
||||
// error
|
||||
r.status = QCborStreamReader::Error;
|
||||
qt_cbor_stream_set_error(reader.d.data(), { QCborError::DataTooLarge });
|
||||
setErrorInReader(reader, { QCborError::DataTooLarge });
|
||||
}
|
||||
|
||||
if (r.status == QCborStreamReader::Error) {
|
||||
@ -1612,9 +1650,10 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader)
|
||||
elements.append(e);
|
||||
}
|
||||
|
||||
void QCborContainerPrivate::decodeValueFromCbor(QCborStreamReader &reader)
|
||||
void QCborContainerPrivate::decodeValueFromCbor(QCborStreamReader &reader, int remainingRecursionDepth)
|
||||
{
|
||||
switch (reader.type()) {
|
||||
QCborStreamReader::Type t = reader.type();
|
||||
switch (t) {
|
||||
case QCborStreamReader::UnsignedInteger:
|
||||
case QCborStreamReader::NegativeInteger:
|
||||
case QCborStreamReader::SimpleType:
|
||||
@ -1631,37 +1670,17 @@ void QCborContainerPrivate::decodeValueFromCbor(QCborStreamReader &reader)
|
||||
|
||||
case QCborStreamReader::Array:
|
||||
case QCborStreamReader::Map:
|
||||
return append(makeValue(t == QCborStreamReader::Array ? QCborValue::Array : QCborValue::Map, -1,
|
||||
createContainerFromCbor(reader, remainingRecursionDepth),
|
||||
MoveContainer));
|
||||
|
||||
case QCborStreamReader::Tag:
|
||||
return append(QCborValue::fromCbor(reader));
|
||||
return append(taggedValueFromCbor(reader, remainingRecursionDepth));
|
||||
|
||||
case QCborStreamReader::Invalid:
|
||||
return; // probably a decode error
|
||||
}
|
||||
}
|
||||
|
||||
void QCborContainerPrivate::decodeFromCbor(QCborStreamReader &reader)
|
||||
{
|
||||
int mapShift = reader.isMap() ? 1 : 0;
|
||||
if (reader.isLengthKnown()) {
|
||||
quint64 len = reader.length();
|
||||
|
||||
// Clamp allocation to 1M elements (avoids crashing due to corrupt
|
||||
// stream or loss of precision when converting from quint64 to
|
||||
// QVector::size_type).
|
||||
len = qMin(len, quint64(1024 * 1024 - 1));
|
||||
elements.reserve(qsizetype(len) << mapShift);
|
||||
}
|
||||
|
||||
reader.enterContainer();
|
||||
if (reader.lastError() != QCborError::NoError)
|
||||
return;
|
||||
|
||||
while (reader.hasNext() && reader.lastError() == QCborError::NoError)
|
||||
decodeValueFromCbor(reader);
|
||||
|
||||
if (reader.lastError() == QCborError::NoError)
|
||||
reader.leaveContainer();
|
||||
}
|
||||
#endif // QT_CONFIG(cborstreamreader)
|
||||
|
||||
/*!
|
||||
@ -2363,6 +2382,8 @@ QCborValueRef QCborValue::operator[](qint64 key)
|
||||
}
|
||||
|
||||
#if QT_CONFIG(cborstreamreader)
|
||||
enum { MaximumRecursionDepth = 1024 };
|
||||
|
||||
/*!
|
||||
Decodes one item from the CBOR stream found in \a reader and returns the
|
||||
equivalent representation. This function is recursive: if the item is a map
|
||||
@ -2423,12 +2444,12 @@ QCborValue QCborValue::fromCbor(QCborStreamReader &reader)
|
||||
case QCborStreamReader::Map:
|
||||
result.n = -1;
|
||||
result.t = reader.isArray() ? Array : Map;
|
||||
result.container = createContainerFromCbor(reader);
|
||||
result.container = createContainerFromCbor(reader, MaximumRecursionDepth);
|
||||
break;
|
||||
|
||||
// tag
|
||||
case QCborStreamReader::Tag:
|
||||
result = taggedValueFromCbor(reader);
|
||||
result = taggedValueFromCbor(reader, MaximumRecursionDepth);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -405,9 +405,9 @@ public:
|
||||
elements.remove(idx);
|
||||
}
|
||||
|
||||
void decodeValueFromCbor(QCborStreamReader &reader);
|
||||
void decodeFromCbor(QCborStreamReader &reader);
|
||||
void decodeValueFromCbor(QCborStreamReader &reader, int remainiingStackDepth);
|
||||
void decodeStringFromCbor(QCborStreamReader &reader);
|
||||
static inline void setErrorInReader(QCborStreamReader &reader, QCborError error);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include <QScopedPointer>
|
||||
#include "qiosurfacegraphicsbuffer.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCocoaBackingStore : public QRasterBackingStore
|
||||
@ -71,8 +73,9 @@ private:
|
||||
void redrawRoundedBottomCorners(CGRect) const;
|
||||
};
|
||||
|
||||
class QCALayerBackingStore : public QCocoaBackingStore
|
||||
class QCALayerBackingStore : public QObject, public QCocoaBackingStore
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCALayerBackingStore(QWindow *window);
|
||||
~QCALayerBackingStore();
|
||||
@ -119,6 +122,11 @@ private:
|
||||
QMacNotificationObserver m_backingPropertiesObserver;
|
||||
|
||||
std::list<std::unique_ptr<GraphicsBuffer>> m_buffers;
|
||||
|
||||
void flushSubWindow(QWindow *window);
|
||||
std::unordered_map<QWindow*, std::unique_ptr<QCALayerBackingStore>> m_subWindowBackingstores;
|
||||
void windowDestroyed(QObject *object);
|
||||
bool m_clearSurfaceOnPaint = true;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -382,7 +382,7 @@ void QCALayerBackingStore::beginPaint(const QRegion ®ion)
|
||||
// Although undocumented, QBackingStore::beginPaint expects the painted region
|
||||
// to be cleared before use if the window has a surface format with an alpha.
|
||||
// Fresh IOSurfaces are already cleared, so we don't need to clear those.
|
||||
if (!bufferWasRecreated && window()->format().hasAlpha()) {
|
||||
if (m_clearSurfaceOnPaint && !bufferWasRecreated && window()->format().hasAlpha()) {
|
||||
qCDebug(lcQpaBackingStore) << "Clearing" << region << "before use";
|
||||
QPainter painter(m_buffers.back()->asImage());
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
@ -511,9 +511,13 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
if (!prepareForFlush())
|
||||
return;
|
||||
|
||||
if (flushedWindow != window()) {
|
||||
flushSubWindow(flushedWindow);
|
||||
return;
|
||||
}
|
||||
|
||||
QMacAutoReleasePool pool;
|
||||
|
||||
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
|
||||
|
||||
// If the backingstore is just flushed, without being painted to first, then we may
|
||||
@ -548,7 +552,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
// are committed as part of a display-cycle instead of on the next runloop pass. This
|
||||
// means CA won't try to throttle us if we flush too fast, and we'll coalesce our flush
|
||||
// with other pending view and layer updates.
|
||||
backingStoreView.window.viewsNeedDisplay = YES;
|
||||
flushedView.window.viewsNeedDisplay = YES;
|
||||
|
||||
if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer) {
|
||||
// The private API [CALayer reloadValueForKeyPath:@"contents"] would be preferable,
|
||||
@ -556,28 +560,10 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
flushedView.layer.contents = nil;
|
||||
}
|
||||
|
||||
if (flushedView == backingStoreView) {
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||
<< "to" << flushedView.layer << "of" << flushedView;
|
||||
flushedView.layer.contents = backBufferSurface;
|
||||
} else {
|
||||
auto subviewRect = [flushedView convertRect:flushedView.bounds toView:backingStoreView];
|
||||
auto scale = flushedView.layer.contentsScale;
|
||||
subviewRect = CGRectApplyAffineTransform(subviewRect, CGAffineTransformMakeScale(scale, scale));
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||
<< "to" << flushedView.layer << "of" << flushedView;
|
||||
|
||||
// We make a copy of the image data up front, which means we don't
|
||||
// need to mark the IOSurface as being in use. FIXME: Investigate
|
||||
// if there's a cheaper way to get sub-image data to a layer.
|
||||
m_buffers.back()->lock(QPlatformGraphicsBuffer::SWReadAccess);
|
||||
QImage subImage = m_buffers.back()->asImage()->copy(QRectF::fromCGRect(subviewRect).toRect());
|
||||
m_buffers.back()->unlock();
|
||||
|
||||
qCInfo(lcQpaBackingStore) << "Flushing" << subImage
|
||||
<< "to" << flushedView.layer << "of subview" << flushedView;
|
||||
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
|
||||
QCFType<CGImageRef>(subImage.toCGImage()), colorSpace());
|
||||
flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage);
|
||||
}
|
||||
flushedView.layer.contents = backBufferSurface;
|
||||
|
||||
// Since we may receive multiple flushes before a new frame is started, we do not
|
||||
// swap any buffers just yet. Instead we check in the next beginPaint if the layer's
|
||||
@ -589,6 +575,53 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
// the window server.
|
||||
}
|
||||
|
||||
void QCALayerBackingStore::flushSubWindow(QWindow *subWindow)
|
||||
{
|
||||
qCInfo(lcQpaBackingStore) << "Flushing sub-window" << subWindow
|
||||
<< "via its own backingstore";
|
||||
|
||||
auto &subWindowBackingStore = m_subWindowBackingstores[subWindow];
|
||||
if (!subWindowBackingStore) {
|
||||
subWindowBackingStore.reset(new QCALayerBackingStore(subWindow));
|
||||
QObject::connect(subWindow, &QObject::destroyed, this, &QCALayerBackingStore::windowDestroyed);
|
||||
subWindowBackingStore->m_clearSurfaceOnPaint = false;
|
||||
}
|
||||
|
||||
auto subWindowSize = subWindow->size();
|
||||
static const auto kNoStaticContents = QRegion();
|
||||
subWindowBackingStore->resize(subWindowSize, kNoStaticContents);
|
||||
|
||||
auto subWindowLocalRect = QRect(QPoint(), subWindowSize);
|
||||
subWindowBackingStore->beginPaint(subWindowLocalRect);
|
||||
|
||||
QPainter painter(subWindowBackingStore->m_buffers.back()->asImage());
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
|
||||
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||
NSView *flushedView = static_cast<QCocoaWindow *>(subWindow->handle())->view();
|
||||
auto subviewRect = [flushedView convertRect:flushedView.bounds toView:backingStoreView];
|
||||
auto scale = flushedView.layer.contentsScale;
|
||||
subviewRect = CGRectApplyAffineTransform(subviewRect, CGAffineTransformMakeScale(scale, scale));
|
||||
|
||||
m_buffers.back()->lock(QPlatformGraphicsBuffer::SWReadAccess);
|
||||
const QImage *backingStoreImage = m_buffers.back()->asImage();
|
||||
painter.drawImage(subWindowLocalRect, *backingStoreImage, QRectF::fromCGRect(subviewRect));
|
||||
m_buffers.back()->unlock();
|
||||
|
||||
painter.end();
|
||||
subWindowBackingStore->endPaint();
|
||||
subWindowBackingStore->flush(subWindow, subWindowLocalRect, QPoint());
|
||||
|
||||
qCInfo(lcQpaBackingStore) << "Done flushing sub-window" << subWindow;
|
||||
}
|
||||
|
||||
void QCALayerBackingStore::windowDestroyed(QObject *object)
|
||||
{
|
||||
auto *window = static_cast<QWindow*>(object);
|
||||
qCInfo(lcQpaBackingStore) << "Removing backingstore for sub-window" << window;
|
||||
m_subWindowBackingstores.erase(window);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||
QPlatformTextureList *textures, bool translucentBackground)
|
||||
@ -722,4 +755,6 @@ QImage *QCALayerBackingStore::GraphicsBuffer::asImage()
|
||||
return &m_image;
|
||||
}
|
||||
|
||||
#include "moc_qcocoabackingstore.cpp"
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -102,6 +102,8 @@ private slots:
|
||||
void fromCborStreamReaderIODevice();
|
||||
void validation_data();
|
||||
void validation();
|
||||
void recursionLimit_data();
|
||||
void recursionLimit();
|
||||
void toDiagnosticNotation_data();
|
||||
void toDiagnosticNotation();
|
||||
|
||||
@ -1720,6 +1722,58 @@ void tst_QCborValue::validation()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QCborValue::recursionLimit_data()
|
||||
{
|
||||
constexpr int RecursionAttempts = 4096;
|
||||
QTest::addColumn<QByteArray>("data");
|
||||
QByteArray arrays(RecursionAttempts, char(0x81));
|
||||
QByteArray _arrays(RecursionAttempts, char(0x9f));
|
||||
QByteArray maps(RecursionAttempts, char(0xa1));
|
||||
QByteArray _maps(RecursionAttempts, char(0xbf));
|
||||
QByteArray tags(RecursionAttempts, char(0xc0));
|
||||
|
||||
QTest::newRow("array-nesting-too-deep") << arrays;
|
||||
QTest::newRow("_array-nesting-too-deep") << _arrays;
|
||||
QTest::newRow("map-nesting-too-deep") << maps;
|
||||
QTest::newRow("_map-nesting-too-deep") << _maps;
|
||||
QTest::newRow("tag-nesting-too-deep") << tags;
|
||||
|
||||
QByteArray mixed(5 * RecursionAttempts, Qt::Uninitialized);
|
||||
char *ptr = mixed.data();
|
||||
for (int i = 0; i < RecursionAttempts; ++i) {
|
||||
quint8 type = qBound(quint8(QCborStreamReader::Array), quint8(i & 0x80), quint8(QCborStreamReader::Tag));
|
||||
quint8 additional_info = i & 0x1f;
|
||||
if (additional_info == 0x1f)
|
||||
(void)additional_info; // leave it
|
||||
else if (additional_info > 0x1a)
|
||||
additional_info = 0x1a;
|
||||
else if (additional_info < 1)
|
||||
additional_info = 1;
|
||||
|
||||
*ptr++ = type | additional_info;
|
||||
if (additional_info == 0x18) {
|
||||
*ptr++ = uchar(i);
|
||||
} else if (additional_info == 0x19) {
|
||||
qToBigEndian(ushort(i), ptr);
|
||||
ptr += 2;
|
||||
} else if (additional_info == 0x1a) {
|
||||
qToBigEndian(uint(i), ptr);
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
QTest::newRow("mixed-nesting-too-deep") << mixed;
|
||||
}
|
||||
|
||||
void tst_QCborValue::recursionLimit()
|
||||
{
|
||||
QFETCH(QByteArray, data);
|
||||
|
||||
QCborParserError error;
|
||||
QCborValue decoded = QCborValue::fromCbor(data, &error);
|
||||
QCOMPARE(error.error, QCborError::NestingTooDeep);
|
||||
}
|
||||
|
||||
void tst_QCborValue::toDiagnosticNotation_data()
|
||||
{
|
||||
QTest::addColumn<QCborValue>("v");
|
||||
|
Loading…
Reference in New Issue
Block a user