summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-04-14 12:27:02 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-04-14 12:27:22 +0200
commit7d7afe1d2b1d85ea5221d1d2883c8bf80aa0e927 (patch)
tree583ea5c5b9b81d28e7155e7167589b9ba4eae610
parentedf5c7a3466b7e8082c90473183e5da9afa80504 (diff)
parent6bd24577658c1e2fde21b14147b4ba964890afe1 (diff)
Merge "Merge remote-tracking branch 'origin/5.12.8' into 5.12"
-rwxr-xr-xconfigure5
-rw-r--r--dist/changes-5.12.870
-rw-r--r--mkspecs/features/mac/default_post.prf4
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java128
-rw-r--r--src/corelib/serialization/qxmlstream.g14
-rw-r--r--src/corelib/serialization/qxmlstream_p.h14
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h10
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm83
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm7
-rw-r--r--tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp23
10 files changed, 268 insertions, 90 deletions
diff --git a/configure b/configure
index ef7bad1bfc..f9407ef587 100755
--- a/configure
+++ b/configure
@@ -271,12 +271,9 @@ macSDKify()
val=$(echo $sdk_val $(echo $val | cut -s -d ' ' -f 2-))
echo "$var=$val"
;;
- QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*)
+ QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*|QMAKE_LFLAGS=*)
echo "$line -isysroot $sysroot $version_min_flag"
;;
- QMAKE_LFLAGS=*)
- echo "$line -Wl,-syslibroot,$sysroot $version_min_flag"
- ;;
*)
echo "$line"
;;
diff --git a/dist/changes-5.12.8 b/dist/changes-5.12.8
new file mode 100644
index 0000000000..0f75d167cf
--- /dev/null
+++ b/dist/changes-5.12.8
@@ -0,0 +1,70 @@
+Qt 5.12.8 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.12.0 through 5.12.7.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+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.
+
+****************************************************************************
+* QtCore *
+****************************************************************************
+
+ - QLockFile:
+ * Suppressed the warning on QNX that said 'setNativeLocks failed:
+ "Function not implemented"'. There is no difference in behavior: Qt
+ will continue not to be able to apply an OS- level file lock, which
+ means the lock could be accidentally stolen by buggy software. Correct
+ software using QLockFile should not be affected.
+
+ - QXmlStream:
+ * QTBUG-47417: QXmlStreamReader does now limit the expansion of
+ entities to 4096 characters. Documents where a single entity
+ expands to more characters than the limit are not considered well
+ formed. The limit is there to avoid DoS attacks through
+ recursively expanding entities when loading untrusted content. Qt
+ 5.15 will add methods that allow changing that limit.
+
+****************************************************************************
+* QtSQL *
+****************************************************************************
+
+ - sqlite:
+ * Updated to v3.31.1
+ * [QTBUG-82533] Fixed CVE-2020-9327
+
+****************************************************************************
+* QtNetwork *
+****************************************************************************
+
+ - QSslCertificate:
+ * Fix a potential heap buffer overflow when parsing certificates
+ - QTBUG-81762: Fix SSL symbol resolving for OPENSSL_NO_NEXPROTONEG
+
+****************************************************************************
+* Platform specific changes *
+****************************************************************************
+
+ - macOS:
+ * QTBUG-82986: Improve performance when flushing sublayers
+ * QTBUG-79139: Avoid repainting OpenGL layers when resizing the window
+
+ - xcb/X11:
+ * QTBUG-76147, QTBUG-76354, QTBUG-68864: Fix handling of minimized state
+
+ - QNX:
+ * QTBUG-81701: QLockFile: Disable flock() on QNX
+
+
+
diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf
index 993f4d56a9..d052808c14 100644
--- a/mkspecs/features/mac/default_post.prf
+++ b/mkspecs/features/mac/default_post.prf
@@ -197,7 +197,7 @@ macx-xcode {
-isysroot$$xcodeSDKInfo(Path, $$sdk)
QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \
-Xarch_$${arch} \
- -Wl,-syslibroot,$$xcodeSDKInfo(Path, $$sdk)
+ -isysroot$$xcodeSDKInfo(Path, $$sdk)
QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch})
QMAKE_XARCH_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS_$${arch})
@@ -218,7 +218,7 @@ macx-xcode {
version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
QMAKE_CXXFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
- QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_MAC_SDK_PATH $$version_min_flag
+ QMAKE_LFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
}
# Enable precompiled headers for multiple architectures
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 1d2b70ab5f..a13c233712 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -724,54 +724,66 @@ public class QtNative
public static boolean hasClipboardText()
{
- if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
- ClipData primaryClip = m_clipboardManager.getPrimaryClip();
- for (int i = 0; i < primaryClip.getItemCount(); ++i)
- if (primaryClip.getItemAt(i).getText() != null)
- return true;
+ try {
+ if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
+ ClipData primaryClip = m_clipboardManager.getPrimaryClip();
+ for (int i = 0; i < primaryClip.getItemCount(); ++i)
+ if (primaryClip.getItemAt(i).getText() != null)
+ return true;
+ }
+ } catch (Exception e) {
+ Log.e(QtTAG, "Failed to get clipboard data", e);
}
return false;
}
private static String getClipboardText()
{
- if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
- ClipData primaryClip = m_clipboardManager.getPrimaryClip();
- for (int i = 0; i < primaryClip.getItemCount(); ++i)
- if (primaryClip.getItemAt(i).getText() != null)
- return primaryClip.getItemAt(i).getText().toString();
+ try {
+ if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
+ ClipData primaryClip = m_clipboardManager.getPrimaryClip();
+ for (int i = 0; i < primaryClip.getItemCount(); ++i)
+ if (primaryClip.getItemAt(i).getText() != null)
+ return primaryClip.getItemAt(i).getText().toString();
+ }
+ } catch (Exception e) {
+ Log.e(QtTAG, "Failed to get clipboard data", e);
}
return "";
}
private static void updatePrimaryClip(ClipData clipData)
{
- if (m_usePrimaryClip) {
- ClipData clip = m_clipboardManager.getPrimaryClip();
- if (Build.VERSION.SDK_INT >= 26) {
- if (m_addItemMethod == null) {
- Class[] cArg = new Class[2];
- cArg[0] = ContentResolver.class;
- cArg[1] = ClipData.Item.class;
+ try {
+ if (m_usePrimaryClip) {
+ ClipData clip = m_clipboardManager.getPrimaryClip();
+ if (Build.VERSION.SDK_INT >= 26) {
+ if (m_addItemMethod == null) {
+ Class[] cArg = new Class[2];
+ cArg[0] = ContentResolver.class;
+ cArg[1] = ClipData.Item.class;
+ try {
+ m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg);
+ } catch (Exception e) {
+ }
+ }
+ }
+ if (m_addItemMethod != null) {
try {
- m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg);
+ m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0));
} catch (Exception e) {
+ e.printStackTrace();
}
+ } else {
+ clip.addItem(clipData.getItemAt(0));
}
- }
- if (m_addItemMethod != null) {
- try {
- m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0));
- } catch (Exception e) {
- e.printStackTrace();
- }
+ m_clipboardManager.setPrimaryClip(clip);
} else {
- clip.addItem(clipData.getItemAt(0));
+ m_clipboardManager.setPrimaryClip(clipData);
+ m_usePrimaryClip = true;
}
- m_clipboardManager.setPrimaryClip(clip);
- } else {
- m_clipboardManager.setPrimaryClip(clipData);
- m_usePrimaryClip = true;
+ } catch (Exception e) {
+ Log.e(QtTAG, "Failed to set clipboard data", e);
}
}
@@ -785,22 +797,30 @@ public class QtNative
public static boolean hasClipboardHtml()
{
- if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
- ClipData primaryClip = m_clipboardManager.getPrimaryClip();
- for (int i = 0; i < primaryClip.getItemCount(); ++i)
- if (primaryClip.getItemAt(i).getHtmlText() != null)
- return true;
+ try {
+ if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
+ ClipData primaryClip = m_clipboardManager.getPrimaryClip();
+ for (int i = 0; i < primaryClip.getItemCount(); ++i)
+ if (primaryClip.getItemAt(i).getHtmlText() != null)
+ return true;
+ }
+ } catch (Exception e) {
+ Log.e(QtTAG, "Failed to get clipboard data", e);
}
return false;
}
private static String getClipboardHtml()
{
- if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
- ClipData primaryClip = m_clipboardManager.getPrimaryClip();
- for (int i = 0; i < primaryClip.getItemCount(); ++i)
- if (primaryClip.getItemAt(i).getHtmlText() != null)
- return primaryClip.getItemAt(i).getHtmlText().toString();
+ try {
+ if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
+ ClipData primaryClip = m_clipboardManager.getPrimaryClip();
+ for (int i = 0; i < primaryClip.getItemCount(); ++i)
+ if (primaryClip.getItemAt(i).getHtmlText() != null)
+ return primaryClip.getItemAt(i).getHtmlText().toString();
+ }
+ } catch (Exception e) {
+ Log.e(QtTAG, "Failed to get clipboard data", e);
}
return "";
}
@@ -816,11 +836,15 @@ public class QtNative
public static boolean hasClipboardUri()
{
- if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
- ClipData primaryClip = m_clipboardManager.getPrimaryClip();
- for (int i = 0; i < primaryClip.getItemCount(); ++i)
- if (primaryClip.getItemAt(i).getUri() != null)
- return true;
+ try {
+ if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
+ ClipData primaryClip = m_clipboardManager.getPrimaryClip();
+ for (int i = 0; i < primaryClip.getItemCount(); ++i)
+ if (primaryClip.getItemAt(i).getUri() != null)
+ return true;
+ }
+ } catch (Exception e) {
+ Log.e(QtTAG, "Failed to get clipboard data", e);
}
return false;
}
@@ -828,11 +852,15 @@ public class QtNative
private static String[] getClipboardUris()
{
ArrayList<String> uris = new ArrayList<String>();
- if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
- ClipData primaryClip = m_clipboardManager.getPrimaryClip();
- for (int i = 0; i < primaryClip.getItemCount(); ++i)
- if (primaryClip.getItemAt(i).getUri() != null)
- uris.add(primaryClip.getItemAt(i).getUri().toString());
+ try {
+ if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
+ ClipData primaryClip = m_clipboardManager.getPrimaryClip();
+ for (int i = 0; i < primaryClip.getItemCount(); ++i)
+ if (primaryClip.getItemAt(i).getUri() != null)
+ uris.add(primaryClip.getItemAt(i).getUri().toString());
+ }
+ } catch (Exception e) {
+ Log.e(QtTAG, "Failed to get clipboard data", e);
}
String[] strings = new String[uris.size()];
strings = uris.toArray(strings);
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g
index 10bfcd491c..5726bafb26 100644
--- a/src/corelib/serialization/qxmlstream.g
+++ b/src/corelib/serialization/qxmlstream.g
@@ -277,9 +277,19 @@ public:
QHash<QStringView, Entity> entityHash;
QHash<QStringView, Entity> parameterEntityHash;
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+ int entityExpansionLimit = 4096;
+ int entityLength = 0;
inline bool referenceEntity(Entity &entity) {
if (entity.isCurrentlyReferenced) {
- raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+ raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected."));
+ return false;
+ }
+ // entityLength represents the amount of additional characters the
+ // entity expands into (can be negative for e.g. &amp;). It's used to
+ // avoid DoS attacks through recursive entity expansions
+ entityLength += entity.value.size() - entity.name.size() - 2;
+ if (entityLength > entityExpansionLimit) {
+ raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit."));
return false;
}
entity.isCurrentlyReferenced = true;
@@ -830,6 +840,8 @@ entity_done ::= ENTITY_DONE;
/.
case $rule_number:
entityReferenceStack.pop()->isCurrentlyReferenced = false;
+ if (entityReferenceStack.isEmpty())
+ entityLength = 0;
clearSym();
break;
./
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index 61f501f81b..31053f8e0b 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -774,9 +774,19 @@ public:
QHash<QStringView, Entity> entityHash;
QHash<QStringView, Entity> parameterEntityHash;
QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+ int entityExpansionLimit = 4096;
+ int entityLength = 0;
inline bool referenceEntity(Entity &entity) {
if (entity.isCurrentlyReferenced) {
- raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+ raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected."));
+ return false;
+ }
+ // entityLength represents the amount of additional characters the
+ // entity expands into (can be negative for e.g. &amp;). It's used to
+ // avoid DoS attacks through recursive entity expansions
+ entityLength += entity.value.size() - entity.name.size() - 2;
+ if (entityLength > entityExpansionLimit) {
+ raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit."));
return false;
}
entity.isCurrentlyReferenced = true;
@@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse()
case 10:
entityReferenceStack.pop()->isCurrentlyReferenced = false;
+ if (entityReferenceStack.isEmpty())
+ entityLength = 0;
clearSym();
break;
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index b57deacb57..3d9dfd8359 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -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
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 94eb471f5d..6aa0c0182f 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -394,7 +394,7 @@ void QCALayerBackingStore::beginPaint(const QRegion &region)
// 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);
@@ -523,9 +523,13 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
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
@@ -560,7 +564,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
// 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,
@@ -568,28 +572,10 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
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));
-
- // 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" << backBufferSurface
+ << "to" << flushedView.layer << "of" << flushedView;
- 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
@@ -601,6 +587,53 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
// 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 &region, const QPoint &offset,
QPlatformTextureList *textures, bool translucentBackground)
@@ -734,4 +767,6 @@ QImage *QCALayerBackingStore::GraphicsBuffer::asImage()
return &m_image;
}
+#include "moc_qcocoabackingstore.cpp"
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index 535e7d7aa6..cecbb17039 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -332,11 +332,8 @@ bool QIOSContext::verifyGraphicsHardwareAvailability()
);
});
- if (applicationBackgrounded) {
- static const char warning[] = "OpenGL ES calls are not allowed while an application is backgrounded";
- Q_ASSERT_X(!applicationBackgrounded, "QIOSContext", warning);
- qCWarning(lcQpaGLContext, warning);
- }
+ if (applicationBackgrounded)
+ qCWarning(lcQpaGLContext, "OpenGL ES calls are not allowed while an application is backgrounded");
return !applicationBackgrounded;
}
diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
index 8fdf91b090..1f9a0d575d 100644
--- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
+++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp
@@ -393,8 +393,6 @@ public:
return true;
}
- QXmlStreamReader reader(&inputFile);
-
/* See testcases.dtd which reads: 'Nonvalidating parsers
* must also accept "invalid" testcases, but validating ones must reject them.' */
if(type == QLatin1String("invalid") || type == QLatin1String("valid"))
@@ -580,6 +578,8 @@ private slots:
void roundTrip() const;
void roundTrip_data() const;
+ void entityExpansionLimit() const;
+
private:
static QByteArray readFile(const QString &filename);
@@ -1756,6 +1756,25 @@ void tst_QXmlStream::roundTrip_data() const
"</root>\n";
}
+void tst_QXmlStream::entityExpansionLimit() const
+{
+ QString xml = QStringLiteral("<?xml version=\"1.0\"?>"
+ "<!DOCTYPE foo ["
+ "<!ENTITY a \"0123456789\" >"
+ "<!ENTITY b \"&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;\" >"
+ "<!ENTITY c \"&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;\" >"
+ "<!ENTITY d \"&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;\" >"
+ "]>"
+ "<foo>&d;&d;&d;</foo>");
+ {
+ QXmlStreamReader reader(xml);
+ do {
+ reader.readNext();
+ } while (!reader.atEnd());
+ QCOMPARE(reader.error(), QXmlStreamReader::NotWellFormedError);
+ }
+}
+
void tst_QXmlStream::roundTrip() const
{
QFETCH(QString, in);