Merge "Merge remote-tracking branch 'origin/5.12.8' into 5.12"

This commit is contained in:
Qt Forward Merge Bot 2020-04-14 12:27:02 +02:00
commit 7d7afe1d2b
10 changed files with 269 additions and 91 deletions

5
configure vendored
View File

@ -271,12 +271,9 @@ macSDKify()
val=$(echo $sdk_val $(echo $val | cut -s -d ' ' -f 2-)) val=$(echo $sdk_val $(echo $val | cut -s -d ' ' -f 2-))
echo "$var=$val" echo "$var=$val"
;; ;;
QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*) QMAKE_CFLAGS=*|QMAKE_CXXFLAGS=*|QMAKE_LFLAGS=*)
echo "$line -isysroot $sysroot $version_min_flag" echo "$line -isysroot $sysroot $version_min_flag"
;; ;;
QMAKE_LFLAGS=*)
echo "$line -Wl,-syslibroot,$sysroot $version_min_flag"
;;
*) *)
echo "$line" echo "$line"
;; ;;

70
dist/changes-5.12.8 vendored Normal file
View File

@ -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

View File

@ -197,7 +197,7 @@ macx-xcode {
-isysroot$$xcodeSDKInfo(Path, $$sdk) -isysroot$$xcodeSDKInfo(Path, $$sdk)
QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \ QMAKE_XARCH_LFLAGS_$${arch} = $$version_min_flags \
-Xarch_$${arch} \ -Xarch_$${arch} \
-Wl,-syslibroot,$$xcodeSDKInfo(Path, $$sdk) -isysroot$$xcodeSDKInfo(Path, $$sdk)
QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch}) QMAKE_XARCH_CFLAGS += $(EXPORT_QMAKE_XARCH_CFLAGS_$${arch})
QMAKE_XARCH_LFLAGS += $(EXPORT_QMAKE_XARCH_LFLAGS_$${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 version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
QMAKE_CXXFLAGS += -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 # Enable precompiled headers for multiple architectures

View File

@ -724,54 +724,66 @@ public class QtNative
public static boolean hasClipboardText() public static boolean hasClipboardText()
{ {
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { try {
ClipData primaryClip = m_clipboardManager.getPrimaryClip(); if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
for (int i = 0; i < primaryClip.getItemCount(); ++i) ClipData primaryClip = m_clipboardManager.getPrimaryClip();
if (primaryClip.getItemAt(i).getText() != null) for (int i = 0; i < primaryClip.getItemCount(); ++i)
return true; if (primaryClip.getItemAt(i).getText() != null)
return true;
}
} catch (Exception e) {
Log.e(QtTAG, "Failed to get clipboard data", e);
} }
return false; return false;
} }
private static String getClipboardText() private static String getClipboardText()
{ {
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { try {
ClipData primaryClip = m_clipboardManager.getPrimaryClip(); if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
for (int i = 0; i < primaryClip.getItemCount(); ++i) ClipData primaryClip = m_clipboardManager.getPrimaryClip();
if (primaryClip.getItemAt(i).getText() != null) for (int i = 0; i < primaryClip.getItemCount(); ++i)
return primaryClip.getItemAt(i).getText().toString(); 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 ""; return "";
} }
private static void updatePrimaryClip(ClipData clipData) private static void updatePrimaryClip(ClipData clipData)
{ {
if (m_usePrimaryClip) { try {
ClipData clip = m_clipboardManager.getPrimaryClip(); if (m_usePrimaryClip) {
if (Build.VERSION.SDK_INT >= 26) { ClipData clip = m_clipboardManager.getPrimaryClip();
if (m_addItemMethod == null) { if (Build.VERSION.SDK_INT >= 26) {
Class[] cArg = new Class[2]; if (m_addItemMethod == null) {
cArg[0] = ContentResolver.class; Class[] cArg = new Class[2];
cArg[1] = ClipData.Item.class; cArg[0] = ContentResolver.class;
try { cArg[1] = ClipData.Item.class;
m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg); try {
} catch (Exception e) { m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg);
} catch (Exception e) {
}
} }
} }
} if (m_addItemMethod != null) {
if (m_addItemMethod != null) { try {
try { m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0));
m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0)); } catch (Exception e) {
} catch (Exception e) { e.printStackTrace();
e.printStackTrace(); }
} else {
clip.addItem(clipData.getItemAt(0));
} }
m_clipboardManager.setPrimaryClip(clip);
} else { } else {
clip.addItem(clipData.getItemAt(0)); m_clipboardManager.setPrimaryClip(clipData);
m_usePrimaryClip = true;
} }
m_clipboardManager.setPrimaryClip(clip); } catch (Exception e) {
} else { Log.e(QtTAG, "Failed to set clipboard data", e);
m_clipboardManager.setPrimaryClip(clipData);
m_usePrimaryClip = true;
} }
} }
@ -785,22 +797,30 @@ public class QtNative
public static boolean hasClipboardHtml() public static boolean hasClipboardHtml()
{ {
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { try {
ClipData primaryClip = m_clipboardManager.getPrimaryClip(); if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
for (int i = 0; i < primaryClip.getItemCount(); ++i) ClipData primaryClip = m_clipboardManager.getPrimaryClip();
if (primaryClip.getItemAt(i).getHtmlText() != null) for (int i = 0; i < primaryClip.getItemCount(); ++i)
return true; if (primaryClip.getItemAt(i).getHtmlText() != null)
return true;
}
} catch (Exception e) {
Log.e(QtTAG, "Failed to get clipboard data", e);
} }
return false; return false;
} }
private static String getClipboardHtml() private static String getClipboardHtml()
{ {
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { try {
ClipData primaryClip = m_clipboardManager.getPrimaryClip(); if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
for (int i = 0; i < primaryClip.getItemCount(); ++i) ClipData primaryClip = m_clipboardManager.getPrimaryClip();
if (primaryClip.getItemAt(i).getHtmlText() != null) for (int i = 0; i < primaryClip.getItemCount(); ++i)
return primaryClip.getItemAt(i).getHtmlText().toString(); 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 ""; return "";
} }
@ -816,11 +836,15 @@ public class QtNative
public static boolean hasClipboardUri() public static boolean hasClipboardUri()
{ {
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { try {
ClipData primaryClip = m_clipboardManager.getPrimaryClip(); if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
for (int i = 0; i < primaryClip.getItemCount(); ++i) ClipData primaryClip = m_clipboardManager.getPrimaryClip();
if (primaryClip.getItemAt(i).getUri() != null) for (int i = 0; i < primaryClip.getItemCount(); ++i)
return true; if (primaryClip.getItemAt(i).getUri() != null)
return true;
}
} catch (Exception e) {
Log.e(QtTAG, "Failed to get clipboard data", e);
} }
return false; return false;
} }
@ -828,11 +852,15 @@ public class QtNative
private static String[] getClipboardUris() private static String[] getClipboardUris()
{ {
ArrayList<String> uris = new ArrayList<String>(); ArrayList<String> uris = new ArrayList<String>();
if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { try {
ClipData primaryClip = m_clipboardManager.getPrimaryClip(); if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) {
for (int i = 0; i < primaryClip.getItemCount(); ++i) ClipData primaryClip = m_clipboardManager.getPrimaryClip();
if (primaryClip.getItemAt(i).getUri() != null) for (int i = 0; i < primaryClip.getItemCount(); ++i)
uris.add(primaryClip.getItemAt(i).getUri().toString()); 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()]; String[] strings = new String[uris.size()];
strings = uris.toArray(strings); strings = uris.toArray(strings);

View File

@ -277,9 +277,19 @@ public:
QHash<QStringView, Entity> entityHash; QHash<QStringView, Entity> entityHash;
QHash<QStringView, Entity> parameterEntityHash; QHash<QStringView, Entity> parameterEntityHash;
QXmlStreamSimpleStack<Entity *>entityReferenceStack; QXmlStreamSimpleStack<Entity *>entityReferenceStack;
int entityExpansionLimit = 4096;
int entityLength = 0;
inline bool referenceEntity(Entity &entity) { inline bool referenceEntity(Entity &entity) {
if (entity.isCurrentlyReferenced) { 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; return false;
} }
entity.isCurrentlyReferenced = true; entity.isCurrentlyReferenced = true;
@ -830,6 +840,8 @@ entity_done ::= ENTITY_DONE;
/. /.
case $rule_number: case $rule_number:
entityReferenceStack.pop()->isCurrentlyReferenced = false; entityReferenceStack.pop()->isCurrentlyReferenced = false;
if (entityReferenceStack.isEmpty())
entityLength = 0;
clearSym(); clearSym();
break; break;
./ ./

View File

@ -774,9 +774,19 @@ public:
QHash<QStringView, Entity> entityHash; QHash<QStringView, Entity> entityHash;
QHash<QStringView, Entity> parameterEntityHash; QHash<QStringView, Entity> parameterEntityHash;
QXmlStreamSimpleStack<Entity *>entityReferenceStack; QXmlStreamSimpleStack<Entity *>entityReferenceStack;
int entityExpansionLimit = 4096;
int entityLength = 0;
inline bool referenceEntity(Entity &entity) { inline bool referenceEntity(Entity &entity) {
if (entity.isCurrentlyReferenced) { 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; return false;
} }
entity.isCurrentlyReferenced = true; entity.isCurrentlyReferenced = true;
@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse()
case 10: case 10:
entityReferenceStack.pop()->isCurrentlyReferenced = false; entityReferenceStack.pop()->isCurrentlyReferenced = false;
if (entityReferenceStack.isEmpty())
entityLength = 0;
clearSym(); clearSym();
break; break;

View File

@ -47,6 +47,8 @@
#include <QScopedPointer> #include <QScopedPointer>
#include "qiosurfacegraphicsbuffer.h" #include "qiosurfacegraphicsbuffer.h"
#include <unordered_map>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QCocoaBackingStore : public QRasterBackingStore class QCocoaBackingStore : public QRasterBackingStore
@ -71,8 +73,9 @@ private:
void redrawRoundedBottomCorners(CGRect) const; void redrawRoundedBottomCorners(CGRect) const;
}; };
class QCALayerBackingStore : public QCocoaBackingStore class QCALayerBackingStore : public QObject, public QCocoaBackingStore
{ {
Q_OBJECT
public: public:
QCALayerBackingStore(QWindow *window); QCALayerBackingStore(QWindow *window);
~QCALayerBackingStore(); ~QCALayerBackingStore();
@ -119,6 +122,11 @@ private:
QMacNotificationObserver m_backingPropertiesObserver; QMacNotificationObserver m_backingPropertiesObserver;
std::list<std::unique_ptr<GraphicsBuffer>> m_buffers; 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 QT_END_NAMESPACE

View File

@ -394,7 +394,7 @@ void QCALayerBackingStore::beginPaint(const QRegion &region)
// Although undocumented, QBackingStore::beginPaint expects the painted region // Although undocumented, QBackingStore::beginPaint expects the painted region
// to be cleared before use if the window has a surface format with an alpha. // 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. // 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"; qCDebug(lcQpaBackingStore) << "Clearing" << region << "before use";
QPainter painter(m_buffers.back()->asImage()); QPainter painter(m_buffers.back()->asImage());
painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setCompositionMode(QPainter::CompositionMode_Source);
@ -523,9 +523,13 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
if (!prepareForFlush()) if (!prepareForFlush())
return; return;
if (flushedWindow != window()) {
flushSubWindow(flushedWindow);
return;
}
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view(); NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
// If the backingstore is just flushed, without being painted to first, then we may // 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 // 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 // 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. // with other pending view and layer updates.
backingStoreView.window.viewsNeedDisplay = YES; flushedView.window.viewsNeedDisplay = YES;
if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer) { if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer) {
// The private API [CALayer reloadValueForKeyPath:@"contents"] would be preferable, // 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; flushedView.layer.contents = nil;
} }
if (flushedView == backingStoreView) { qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface << "to" << flushedView.layer << "of" << flushedView;
<< "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 flushedView.layer.contents = backBufferSurface;
// 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);
}
// Since we may receive multiple flushes before a new frame is started, we do not // 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 // 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. // 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 #ifndef QT_NO_OPENGL
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset, void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
QPlatformTextureList *textures, bool translucentBackground) QPlatformTextureList *textures, bool translucentBackground)
@ -734,4 +767,6 @@ QImage *QCALayerBackingStore::GraphicsBuffer::asImage()
return &m_image; return &m_image;
} }
#include "moc_qcocoabackingstore.cpp"
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -332,11 +332,8 @@ bool QIOSContext::verifyGraphicsHardwareAvailability()
); );
}); });
if (applicationBackgrounded) { if (applicationBackgrounded)
static const char warning[] = "OpenGL ES calls are not allowed while an application is backgrounded"; qCWarning(lcQpaGLContext, "OpenGL ES calls are not allowed while an application is backgrounded");
Q_ASSERT_X(!applicationBackgrounded, "QIOSContext", warning);
qCWarning(lcQpaGLContext, warning);
}
return !applicationBackgrounded; return !applicationBackgrounded;
} }

View File

@ -393,8 +393,6 @@ public:
return true; return true;
} }
QXmlStreamReader reader(&inputFile);
/* See testcases.dtd which reads: 'Nonvalidating parsers /* See testcases.dtd which reads: 'Nonvalidating parsers
* must also accept "invalid" testcases, but validating ones must reject them.' */ * must also accept "invalid" testcases, but validating ones must reject them.' */
if(type == QLatin1String("invalid") || type == QLatin1String("valid")) if(type == QLatin1String("invalid") || type == QLatin1String("valid"))
@ -580,6 +578,8 @@ private slots:
void roundTrip() const; void roundTrip() const;
void roundTrip_data() const; void roundTrip_data() const;
void entityExpansionLimit() const;
private: private:
static QByteArray readFile(const QString &filename); static QByteArray readFile(const QString &filename);
@ -1756,6 +1756,25 @@ void tst_QXmlStream::roundTrip_data() const
"</root>\n"; "</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 void tst_QXmlStream::roundTrip() const
{ {
QFETCH(QString, in); QFETCH(QString, in);