diff options
| author | jocelyn.turcotte@digia.com <jocelyn.turcotte@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | 2013-01-16 15:06:46 +0000 |
|---|---|---|
| committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-01-17 17:36:03 +0100 |
| commit | f755a72b77240ed0cfac92f0355aa0464279db62 (patch) | |
| tree | 3a79aeebbb8231a0fd025a274be1ee488aba9530 | |
| parent | dfa20637622bfadde8882afbf1e8b8500833b170 (diff) | |
| download | qtwebkit-f755a72b77240ed0cfac92f0355aa0464279db62.tar.gz | |
[Qt] Use the shared HistoryItem serialization for QWebHistory
https://bugs.webkit.org/show_bug.cgi?id=106671
Reviewed by Allan Sandfeld Jensen.
Source/WebCore:
This allows a few things missing from the previous serialization code
to function while using commonly maintained code:
- The itemSequenceNumber and documentSequenceNumber that were needed
to properly restore same-document navigations
- The form data
- The navigation hierarchy mapping the frame tree
* history/HistoryItem.h:
(HistoryItem):
* history/qt/HistoryItemQt.cpp:
(QDataStreamCoder):
(WebCore):
(WebCore::QDataStreamCoder::QDataStreamCoder):
(WebCore::QDataStreamCoder::encodeBytes):
(WebCore::QDataStreamCoder::encodeBool):
(WebCore::QDataStreamCoder::encodeUInt32):
(WebCore::QDataStreamCoder::encodeUInt64):
(WebCore::QDataStreamCoder::encodeInt32):
(WebCore::QDataStreamCoder::encodeInt64):
(WebCore::QDataStreamCoder::encodeFloat):
(WebCore::QDataStreamCoder::encodeDouble):
(WebCore::QDataStreamCoder::encodeString):
(WebCore::QDataStreamCoder::decodeBytes):
(WebCore::QDataStreamCoder::decodeBool):
(WebCore::QDataStreamCoder::decodeUInt32):
(WebCore::QDataStreamCoder::decodeUInt64):
(WebCore::QDataStreamCoder::decodeInt32):
(WebCore::QDataStreamCoder::decodeInt64):
(WebCore::QDataStreamCoder::decodeFloat):
(WebCore::QDataStreamCoder::decodeDouble):
(WebCore::QDataStreamCoder::decodeString):
(WebCore::HistoryItem::restoreState):
(WebCore::WebCore::HistoryItem::saveState):
Source/WebKit/qt:
Bump the serialization version and change the code to abort the
restore of a previous stream version rather than trying to keep the
support of restoring previous versions. This is mainly to simplify
things given that HistoryItem itself aborts in that case.
* Api/qwebhistory.cpp:
(operator<<):
(operator>>):
* tests/qwebhistory/tst_qwebhistory.cpp:
(tst_QWebHistory::serialize_2): Modify the test to cover same-document navigations.
(tst_QWebHistory::restoreIncompatibleVersion1): Add a previous version
hard-coded stream to verify that the deserialization doesn't hang or
crash.
Change-Id: Ic3944179b7f1cb490722c38adbcfef88e8aa1c08
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@139878 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
| -rw-r--r-- | Source/WebCore/ChangeLog | 41 | ||||
| -rw-r--r-- | Source/WebCore/history/HistoryItem.h | 2 | ||||
| -rw-r--r-- | Source/WebCore/history/qt/HistoryItemQt.cpp | 265 | ||||
| -rw-r--r-- | Source/WebKit/qt/Api/qwebhistory.cpp | 54 | ||||
| -rw-r--r-- | Source/WebKit/qt/ChangeLog | 21 | ||||
| -rw-r--r-- | Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp | 112 |
6 files changed, 369 insertions, 126 deletions
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 3157b7a39..0b3e57c34 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,5 +1,46 @@ 2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + [Qt] Use the shared HistoryItem serialization for QWebHistory + https://bugs.webkit.org/show_bug.cgi?id=106671 + + Reviewed by Allan Sandfeld Jensen. + + This allows a few things missing from the previous serialization code + to function while using commonly maintained code: + - The itemSequenceNumber and documentSequenceNumber that were needed + to properly restore same-document navigations + - The form data + - The navigation hierarchy mapping the frame tree + + * history/HistoryItem.h: + (HistoryItem): + * history/qt/HistoryItemQt.cpp: + (QDataStreamCoder): + (WebCore): + (WebCore::QDataStreamCoder::QDataStreamCoder): + (WebCore::QDataStreamCoder::encodeBytes): + (WebCore::QDataStreamCoder::encodeBool): + (WebCore::QDataStreamCoder::encodeUInt32): + (WebCore::QDataStreamCoder::encodeUInt64): + (WebCore::QDataStreamCoder::encodeInt32): + (WebCore::QDataStreamCoder::encodeInt64): + (WebCore::QDataStreamCoder::encodeFloat): + (WebCore::QDataStreamCoder::encodeDouble): + (WebCore::QDataStreamCoder::encodeString): + (WebCore::QDataStreamCoder::decodeBytes): + (WebCore::QDataStreamCoder::decodeBool): + (WebCore::QDataStreamCoder::decodeUInt32): + (WebCore::QDataStreamCoder::decodeUInt64): + (WebCore::QDataStreamCoder::decodeInt32): + (WebCore::QDataStreamCoder::decodeInt64): + (WebCore::QDataStreamCoder::decodeFloat): + (WebCore::QDataStreamCoder::decodeDouble): + (WebCore::QDataStreamCoder::decodeString): + (WebCore::HistoryItem::restoreState): + (WebCore::WebCore::HistoryItem::saveState): + +2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + [Qt] Crash in WebCore::CachedFrame::destroy https://bugs.webkit.org/show_bug.cgi?id=104525 diff --git a/Source/WebCore/history/HistoryItem.h b/Source/WebCore/history/HistoryItem.h index 2472aa3fa..79c43c939 100644 --- a/Source/WebCore/history/HistoryItem.h +++ b/Source/WebCore/history/HistoryItem.h @@ -201,7 +201,7 @@ public: QVariant userData() const { return m_userData; } void setUserData(const QVariant& userData) { m_userData = userData; } - bool restoreState(QDataStream& buffer, int version); + static PassRefPtr<HistoryItem> restoreState(QDataStream& buffer, int version); QDataStream& saveState(QDataStream& out, int version) const; #endif diff --git a/Source/WebCore/history/qt/HistoryItemQt.cpp b/Source/WebCore/history/qt/HistoryItemQt.cpp index 5528eeb0c..5a54516f3 100644 --- a/Source/WebCore/history/qt/HistoryItemQt.cpp +++ b/Source/WebCore/history/qt/HistoryItemQt.cpp @@ -21,22 +21,13 @@ #include "HistoryItem.h" #include "FormData.h" +#include <wtf/Decoder.h> +#include <wtf/Encoder.h> #include <wtf/text/CString.h> -static QDataStream& operator<<(QDataStream& stream, const WebCore::IntPoint& point) -{ - stream << point.x() << point.y(); - return stream; -} +using namespace WTF; -static QDataStream& operator>>(QDataStream& stream, WebCore::IntPoint& point) -{ - int x, y; - stream >> x >> y; - point.setX(x); - point.setY(y); - return stream; -} +namespace WebCore { static QDataStream& operator<<(QDataStream& stream, const String& str) { @@ -54,117 +45,190 @@ static QDataStream& operator>>(QDataStream& stream, String& str) return stream; } -template<typename T> -QDataStream& operator<<(QDataStream& stream, const Vector<T>& data) +class QDataStreamCoder : public WTF::Encoder, public WTF::Decoder { +public: + QDataStreamCoder(QDataStream&); + +private: + virtual void encodeBytes(const uint8_t*, size_t); + virtual void encodeBool(bool); + virtual void encodeUInt32(uint32_t); + virtual void encodeUInt64(uint64_t); + virtual void encodeInt32(int32_t); + virtual void encodeInt64(int64_t); + virtual void encodeFloat(float); + virtual void encodeDouble(double); + virtual void encodeString(const String&); + + virtual bool decodeBytes(Vector<uint8_t>&); + virtual bool decodeBool(bool&); + virtual bool decodeUInt32(uint32_t&); + virtual bool decodeUInt64(uint64_t&); + virtual bool decodeInt32(int32_t&); + virtual bool decodeInt64(int64_t&); + virtual bool decodeFloat(float&); + virtual bool decodeDouble(double&); + virtual bool decodeString(String&); + + QDataStream& m_stream; +}; + +QDataStreamCoder::QDataStreamCoder(QDataStream& stream) + : m_stream(stream) { - stream << qint64(data.size()); - foreach (const T& i, data) - stream << i; - return stream; } -template<typename T> -QDataStream& operator>>(QDataStream& stream, Vector<T>& data) +void QDataStreamCoder::encodeBytes(const uint8_t* bytes, size_t size) { - data.clear(); + m_stream << qint64(size); + for (; size > 0; --size) + m_stream << bytes++; +} + +void QDataStreamCoder::encodeBool(bool value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeUInt32(uint32_t value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeUInt64(uint64_t value) +{ + m_stream << static_cast<quint64>(value); +} + +void QDataStreamCoder::encodeInt32(int32_t value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeInt64(int64_t value) +{ + m_stream << static_cast<qint64>(value); +} + +void QDataStreamCoder::encodeFloat(float value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeDouble(double value) +{ + m_stream << value; +} + +void QDataStreamCoder::encodeString(const String& value) +{ + m_stream << value; +} + +bool QDataStreamCoder::decodeBytes(Vector<uint8_t>& out) +{ + out.clear(); qint64 count; - T item; - stream >> count; - data.reserveCapacity(count); + uint8_t byte; + m_stream >> count; + out.reserveCapacity(count); for (qint64 i = 0; i < count; ++i) { - stream >> item; - data.append(item); + m_stream >> byte; + out.append(byte); } - return stream; + return m_stream.status() == QDataStream::Ok; } -bool WebCore::HistoryItem::restoreState(QDataStream& in, int version) +bool QDataStreamCoder::decodeBool(bool& out) { - // we only support version 1 for now + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} - if (version != 1) - return false; +bool QDataStreamCoder::decodeUInt32(uint32_t& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} - WTF::String url; - WTF::String title; - WTF::String altTitle; - WTF::String orginalUrl; - WTF::String referrer; - WTF::String target; - WTF::String parrent; - double lastVisitedTime; - bool validUserData; - WTF::String parent; - bool lastVisitWasHTTPNonGet; - bool lastVisitWasFailure; - bool isTargetItem; - int visitCount; - WTF::Vector<WTF::String> documentState; - WebCore::IntPoint scrollPoint; - qreal pageScaleFactor; - WTF::Vector<int> weeklyVisitCounts; - WTF::Vector<int> dailyVisitCounts; - // bool loadFormdata; - // WTF::String formContentType; - // WTF::Vector<char> formData; - - in >> url >> title >> altTitle >> lastVisitedTime >> orginalUrl >> referrer >> target >> parent; - in >> lastVisitWasHTTPNonGet >> lastVisitWasFailure >> isTargetItem >> visitCount >> documentState; - in >> scrollPoint >> pageScaleFactor >> dailyVisitCounts >> weeklyVisitCounts; - /*in >> loadFormdata; - if (loadFormdata) { - in >> formContentType >> formData; - // direct assigned (!) - m_formContentType = formContentType; - m_formData = FormData::create(CString(formData)); - }*/ - // use setters - adoptVisitCounts(dailyVisitCounts, weeklyVisitCounts); - setScrollPoint(scrollPoint); - setPageScaleFactor(pageScaleFactor); - setDocumentState(documentState); - setVisitCount(visitCount); - setIsTargetItem(isTargetItem); - setLastVisitWasFailure(lastVisitWasFailure); - setLastVisitWasHTTPNonGet(lastVisitWasHTTPNonGet); - setParent(parent); - setTarget(target); - setReferrer(referrer); - setOriginalURLString(orginalUrl); - setURLString(url); - setLastVisitedTime(lastVisitedTime); - setTitle(title); - setAlternateTitle(altTitle); +bool QDataStreamCoder::decodeUInt64(uint64_t& out) +{ + quint64 tmp; + m_stream >> tmp; + // quint64 is defined to "long long unsigned", incompatible with uint64_t defined as "long unsigned" on 64bits archs. + out = tmp; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeInt32(int32_t& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeInt64(int64_t& out) +{ + qint64 tmp; + m_stream >> tmp; + // qint64 is defined to "long long", incompatible with int64_t defined as "long" on 64bits archs. + out = tmp; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeFloat(float& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeDouble(double& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +bool QDataStreamCoder::decodeString(String& out) +{ + m_stream >> out; + return m_stream.status() == QDataStream::Ok; +} + +PassRefPtr<HistoryItem> HistoryItem::restoreState(QDataStream& in, int version) +{ + ASSERT(version == 2); + + String url; + String title; + String originalURL; + in >> url >> title >> originalURL; + + QDataStreamCoder decoder(in); + RefPtr<HistoryItem> item = decodeBackForwardTree(url, title, originalURL, decoder); + // decodeBackForwardTree has its own stream version. An incompatible input stream version will return null here. + if (!item) + return 0; // at the end load userData + bool validUserData; in >> validUserData; if (validUserData) { QVariant tmp; in >> tmp; - setUserData(tmp); + item->setUserData(tmp); } - return in.status() == QDataStream::Ok; + return item; } QDataStream& WebCore::HistoryItem::saveState(QDataStream& out, int version) const { - // we only support version 1 for now. - if (version != 1) - return out; - - out << urlString() << title() << alternateTitle() << lastVisitedTime(); - out << originalURLString() << referrer() << target() << parent(); - out << lastVisitWasHTTPNonGet() << lastVisitWasFailure() << isTargetItem(); - out << visitCount() << documentState() << scrollPoint(); - out << qreal(pageScaleFactor()) << dailyVisitCounts() << weeklyVisitCounts(); - /*if (m_formData) { - out << true; - out << formContentType(); - out << m_formData->flatten(); - } else { - out << false; - }*/ + ASSERT(version == 2); + + out << urlString() << title() << originalURLString(); + + QDataStreamCoder encoder(out); + encodeBackForwardTree(encoder); + // save user data if (userData().isValid()) out << true << userData(); @@ -174,3 +238,4 @@ QDataStream& WebCore::HistoryItem::saveState(QDataStream& out, int version) cons return out; } +} // namespace WebCore diff --git a/Source/WebKit/qt/Api/qwebhistory.cpp b/Source/WebKit/qt/Api/qwebhistory.cpp index a02083307..be0905eb7 100644 --- a/Source/WebKit/qt/Api/qwebhistory.cpp +++ b/Source/WebKit/qt/Api/qwebhistory.cpp @@ -35,10 +35,7 @@ #include <QSharedData> #include <QDebug> -enum { - InitialHistoryVersion = 1, - DefaultHistoryVersion = InitialHistoryVersion -}; +static const int HistoryStreamVersion = 2; /*! \class QWebHistoryItem @@ -496,7 +493,7 @@ QDataStream& operator<<(QDataStream& target, const QWebHistory& history) { QWebHistoryPrivate* d = history.d; - int version = DefaultHistoryVersion; + int version = HistoryStreamVersion; target << version; target << history.count() << history.currentItemIndex(); @@ -521,29 +518,42 @@ QDataStream& operator<<(QDataStream& target, const QWebHistory& history) QDataStream& operator>>(QDataStream& source, QWebHistory& history) { QWebHistoryPrivate* d = history.d; + // Clear first, to have the same behavior if our version doesn't match and if the HistoryItem's version doesn't. + history.clear(); + // This version covers every field we serialize in qwebhistory.cpp and HistoryItemQt.cpp (like the HistoryItem::userData()). + // HistoryItem has its own version in the stream covering the work done in encodeBackForwardTree. + // If any of those two stream version changes, the effect should be the same and the QWebHistory should fail to restore. int version; - source >> version; + if (version != HistoryStreamVersion) { + // We do not try to decode previous history stream versions. + // Make sure that our history is cleared and mark the rest of the stream as invalid. + ASSERT(history.count() == 1); + source.setStatus(QDataStream::ReadCorruptData); + return source; + } - if (version == 1) { - int count; - int currentIndex; - source >> count >> currentIndex; - - history.clear(); - // only if there are elements - if (count) { - // after clear() is new clear HistoryItem (at the end we had to remove it) - WebCore::HistoryItem* nullItem = d->lst->currentItem(); - for (int i = 0; i < count; i++) { - WTF::PassRefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); - item->restoreState(source, version); - d->lst->addItem(item); + int count; + int currentIndex; + source >> count >> currentIndex; + + // only if there are elements + if (count) { + // after clear() is new clear HistoryItem (at the end we had to remove it) + WebCore::HistoryItem* nullItem = d->lst->currentItem(); + for (int i = 0; i < count; i++) { + WTF::RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::restoreState(source, version); + if (!item) { + // The HistoryItem internal version might have changed, do the same as when our own version change. + history.clear(); + source.setStatus(QDataStream::ReadCorruptData); + return source; } - d->lst->removeItem(nullItem); - history.goToItem(history.itemAt(currentIndex)); + d->lst->addItem(item); } + d->lst->removeItem(nullItem); + history.goToItem(history.itemAt(currentIndex)); } d->page()->updateNavigationActions(); diff --git a/Source/WebKit/qt/ChangeLog b/Source/WebKit/qt/ChangeLog index 291c43a24..012485d9a 100644 --- a/Source/WebKit/qt/ChangeLog +++ b/Source/WebKit/qt/ChangeLog @@ -1,5 +1,26 @@ 2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + [Qt] Use the shared HistoryItem serialization for QWebHistory + https://bugs.webkit.org/show_bug.cgi?id=106671 + + Reviewed by Allan Sandfeld Jensen. + + Bump the serialization version and change the code to abort the + restore of a previous stream version rather than trying to keep the + support of restoring previous versions. This is mainly to simplify + things given that HistoryItem itself aborts in that case. + + * Api/qwebhistory.cpp: + (operator<<): + (operator>>): + * tests/qwebhistory/tst_qwebhistory.cpp: + (tst_QWebHistory::serialize_2): Modify the test to cover same-document navigations. + (tst_QWebHistory::restoreIncompatibleVersion1): Add a previous version + hard-coded stream to verify that the deserialization doesn't hang or + crash. + +2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> + [Qt] Crash in WebCore::CachedFrame::destroy https://bugs.webkit.org/show_bug.cgi?id=104525 diff --git a/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp b/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp index 06c292908..4c839fec3 100644 --- a/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp +++ b/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp @@ -65,6 +65,7 @@ private Q_SLOTS: void popPushState_data(); void popPushState(); void clear(); + void restoreIncompatibleVersion1(); private: @@ -237,16 +238,20 @@ void tst_QWebHistory::serialize_2() QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded - int oldCurrentIndex = hist->currentItemIndex(); + // Force a "same document" navigation. + frame->load(frame->url().toString() + QLatin1String("#dummyAnchor")); + + int initialCurrentIndex = hist->currentItemIndex(); hist->back(); + hist->back(); waitForLoadFinished.exec(); hist->back(); waitForLoadFinished.exec(); //check if current index was changed (make sure that it is not last item) - QVERIFY(hist->currentItemIndex() != oldCurrentIndex); + QVERIFY(hist->currentItemIndex() != initialCurrentIndex); //save current index - oldCurrentIndex = hist->currentItemIndex(); + int oldCurrentIndex = hist->currentItemIndex(); save << *hist; QVERIFY(save.status() == QDataStream::Ok); @@ -255,6 +260,13 @@ void tst_QWebHistory::serialize_2() //check current index QCOMPARE(hist->currentItemIndex(), oldCurrentIndex); + + hist->forward(); + waitForLoadFinished.exec(); + hist->forward(); + waitForLoadFinished.exec(); + hist->forward(); + QCOMPARE(hist->currentItemIndex(), initialCurrentIndex); } /** @@ -414,5 +426,99 @@ void tst_QWebHistory::clear() delete page2; } +// static void dumpCurrentVersion(QWebHistory* history) +// { +// QByteArray buffer; +// saveHistory(history, &buffer); +// printf(" static const char version1Dump[] = {"); +// for (int i = 0; i < buffer.size(); ++i) { +// bool newLine = !(i % 15); +// bool last = i == buffer.size() - 1; +// printf("%s0x%.2x%s", newLine ? "\n " : "", (unsigned char)buffer[i], last ? "" : ", "); +// } +// printf("};\n"); +// } + +void tst_QWebHistory::restoreIncompatibleVersion1() +{ + // Uncomment this code to generate a dump similar to the one below with the current stream version. + // dumpCurrentVersion(hist); + static const char version1Dump[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, + 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, + 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x68, + 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, + 0x67, 0x00, 0x65, 0x00, 0x31, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, + 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, + 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, + 0x31, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, + 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, + 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x68, 0x00, + 0x74, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, + 0x00, 0x65, 0x00, 0x32, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, + 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, + 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x32, + 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, + 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, + 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, + 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x33, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, + 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, + 0x65, 0x00, 0x33, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, + 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, + 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x33, 0x00, + 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, + 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, + 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, + 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x34, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, + 0x6d, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, + 0x00, 0x34, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, + 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x34, 0x00, 0x2e, + 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x71, 0x00, + 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x6f, + 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x70, 0x00, + 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x68, 0x00, 0x74, 0x00, 0x6d, + 0x00, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, + 0x35, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x71, 0x00, 0x72, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x72, 0x00, + 0x65, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, + 0x00, 0x2f, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x35, 0x00, 0x2e, 0x00, + 0x68, 0x00, 0x74, 0x00, 0x6d, 0x00, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + QByteArray version1(version1Dump, sizeof(version1Dump)); + QDataStream stream(&version1, QIODevice::ReadOnly); + + // This should fail to load, the history should be cleared and the stream should be broken. + stream >> *hist; + QVERIFY(!hist->canGoBack()); + QVERIFY(!hist->canGoForward()); + QVERIFY(stream.status() == QDataStream::ReadCorruptData); +} + QTEST_MAIN(tst_QWebHistory) #include "tst_qwebhistory.moc" |
