diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2014-03-27 16:26:15 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-28 12:04:45 +0100 |
commit | 1967978f5d0b225aec561a0e1028b9e02f5cdce4 (patch) | |
tree | ac2fb549b19e0e9c327ffe018663b9dab0b1b10c | |
parent | 9b75f92b9a3ab3216da79f390b49919266ca258f (diff) | |
download | qtwebkit-1967978f5d0b225aec561a0e1028b9e02f5cdce4.tar.gz |
Fix crash on access of dead QMimeData
When we give a QMimeData to the system pasteboard, we should no longer
access it locally.
This patch ensures we invalidate the pointer to the QMimeDate once it
has been uploaded to the system clipboard. To ensure we can still read
values we have writen, the code to read the pasteboard data will now
read it from the system pasteboard when applicable. Several places
the latter was done manually have been removed.
Task-number: QTBUG-37904
Change-Id: I9c37b2fcc58ebbc387319be39c190fd7db6f70eb
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r-- | Source/WebCore/platform/Pasteboard.h | 1 | ||||
-rw-r--r-- | Source/WebCore/platform/qt/PasteboardQt.cpp | 65 |
2 files changed, 27 insertions, 39 deletions
diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h index 936b28469..8b17f47f8 100644 --- a/Source/WebCore/platform/Pasteboard.h +++ b/Source/WebCore/platform/Pasteboard.h @@ -110,6 +110,7 @@ public: void invalidateWritableData() const { m_writableData = 0; } bool isForDragAndDrop() const { return m_isForDragAndDrop; } bool isForCopyAndPaste() const { return !m_isForDragAndDrop; } + void updateSystemPasteboard(); #endif // Deprecated. Use createForCopyAndPaste instead. diff --git a/Source/WebCore/platform/qt/PasteboardQt.cpp b/Source/WebCore/platform/qt/PasteboardQt.cpp index e6e18c9a7..cf1c3a619 100644 --- a/Source/WebCore/platform/qt/PasteboardQt.cpp +++ b/Source/WebCore/platform/qt/PasteboardQt.cpp @@ -46,8 +46,6 @@ #include <qtextcodec.h> #include <qurl.h> -#define methodDebug() qDebug() << "PasteboardQt: " << __FUNCTION__; - namespace WebCore { static bool isTextMimeType(const String& type) @@ -67,16 +65,12 @@ PassOwnPtr<Pasteboard> Pasteboard::create(const QMimeData* readableClipboard, bo PassOwnPtr<Pasteboard> Pasteboard::createForCopyAndPaste() { -#ifndef QT_NO_CLIPBOARD - return create(QGuiApplication::clipboard()->mimeData()); -#else return create(); -#endif } PassOwnPtr<Pasteboard> Pasteboard::createPrivate() { - return create(); + return create(0, true /* Not really for drag-and-drop, but shouldn't actively update the system pasteboard */); } PassOwnPtr<Pasteboard> Pasteboard::createForDragAndDrop() @@ -133,18 +127,12 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, if (canSmartCopyOrDelete) m_writableData->setData(QStringLiteral("application/vnd.qtwebkit.smartpaste"), QByteArray()); -#ifndef QT_NO_CLIPBOARD if (isForCopyAndPaste()) - QGuiApplication::clipboard()->setMimeData(m_writableData, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); -#endif + updateSystemPasteboard(); } bool Pasteboard::canSmartReplace() { -#ifndef QT_NO_CLIPBOARD - if (isForCopyAndPaste() && QGuiApplication::clipboard()->mimeData()->hasFormat(QStringLiteral("application/vnd.qtwebkit.smartpaste"))) - return true; -#endif if (const QMimeData* data = readData()) return data->hasFormat(QStringLiteral("application/vnd.qtwebkit.smartpaste")); @@ -153,10 +141,6 @@ bool Pasteboard::canSmartReplace() String Pasteboard::plainText(Frame*) { -#ifndef QT_NO_CLIPBOARD - if (isForCopyAndPaste()) - return QGuiApplication::clipboard()->text(m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); -#endif if (const QMimeData* data = readData()) return data->text(); return String(); @@ -165,13 +149,7 @@ String Pasteboard::plainText(Frame*) PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) { -#ifndef QT_NO_CLIPBOARD - const QMimeData* mimeData = 0; - if (isForCopyAndPaste()) - mimeData = QGuiApplication::clipboard()->mimeData(m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); - else - mimeData = readData(); -#endif + const QMimeData* mimeData = readData(); if (!mimeData) return 0; @@ -220,10 +198,8 @@ void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartRepl m_writableData->setText(qtext); if (smartReplaceOption == CanSmartReplace) m_writableData->setData(QLatin1String("application/vnd.qtwebkit.smartpaste"), QByteArray()); -#ifndef QT_NO_CLIPBOARD if (isForCopyAndPaste()) - QGuiApplication::clipboard()->setMimeData(m_writableData, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); -#endif + updateSystemPasteboard(); } void Pasteboard::writeURL(const KURL& url, const String& title, Frame*) @@ -234,10 +210,8 @@ void Pasteboard::writeURL(const KURL& url, const String& title, Frame*) m_writableData = new QMimeData; m_writableData->setText(title); m_writableData->setUrls(QList<QUrl>() << url); -#ifndef QT_NO_CLIPBOARD if (isForCopyAndPaste()) - QGuiApplication::clipboard()->setMimeData(m_writableData, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); -#endif + updateSystemPasteboard(); } void Pasteboard::writeImage(Node* node, const KURL& url, const String& title) @@ -267,10 +241,8 @@ void Pasteboard::writeImage(Node* node, const KURL& url, const String& title) if (node->isHTMLElement()) m_writableData->setHtml(static_cast<HTMLElement*>(node)->outerHTML()); -#ifndef QT_NO_CLIPBOARD if (isForCopyAndPaste()) - QGuiApplication::clipboard()->setMimeData(m_writableData, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); -#endif + updateSystemPasteboard(); } bool Pasteboard::isSelectionMode() const @@ -285,8 +257,15 @@ void Pasteboard::setSelectionMode(bool selectionMode) const QMimeData* Pasteboard::readData() const { - ASSERT(!(m_readableData && m_writableData)); - return m_readableData ? m_readableData : m_writableData; + if (m_readableData) + return m_readableData; + if (m_writableData) + return m_writableData; +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + return QGuiApplication::clipboard()->mimeData(m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); +#endif + return 0; } bool Pasteboard::hasData() @@ -307,10 +286,8 @@ void Pasteboard::clear(const String& type) m_writableData = 0; } } -#ifndef QT_NO_CLIPBOARD if (isForCopyAndPaste()) - QGuiApplication::clipboard()->setMimeData(m_writableData); -#endif + updateSystemPasteboard(); } void Pasteboard::clear() @@ -396,11 +373,21 @@ void Pasteboard::setDragImage(DragImageRef, const IntPoint& hotSpot) notImplemented(); } +void Pasteboard::updateSystemPasteboard() +{ + ASSERT(isForCopyAndPaste()); +#ifndef QT_NO_CLIPBOARD + QGuiApplication::clipboard()->setMimeData(m_writableData, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); + invalidateWritableData(); +#endif +} + void Pasteboard::writePasteboard(const Pasteboard& sourcePasteboard) { ASSERT(isForCopyAndPaste()); #ifndef QT_NO_CLIPBOARD QGuiApplication::clipboard()->setMimeData(sourcePasteboard.clipboardData()); + sourcePasteboard.invalidateWritableData(); #endif } |