[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [elisa] /: fix an out of bonds access to QList in MediaPlayList
From:       Matthieu Gallien <matthieu_gallien () yahoo ! fr>
Date:       2016-12-06 20:59:44
Message-ID: E1cEMq0-0004iX-Td () code ! kde ! org
[Download RAW message or body]

Git commit 101280ae61728c66bf3026c40ba5c19d8f6f9d97 by Matthieu Gallien.
Committed on 06/12/2016 at 17:45.
Pushed by mgallien into branch 'master'.

fix an out of bonds access to QList in MediaPlayList

M  +134  -0    autotests/mediaplaylisttest.cpp
M  +21   -0    autotests/mediaplaylisttest.h
M  +4    -3    src/mediaplaylist.cpp

https://commits.kde.org/elisa/101280ae61728c66bf3026c40ba5c19d8f6f9d97

diff --git a/autotests/mediaplaylisttest.cpp b/autotests/mediaplaylisttest.cpp
index bf49c17..319ad9e 100644
--- a/autotests/mediaplaylisttest.cpp
+++ b/autotests/mediaplaylisttest.cpp
@@ -2243,6 +2243,140 @@ void MediaPlayListTest::enqueueClearAndEnqueue()
     QCOMPARE(myPlayList.data(myPlayList.index(3, 0), \
MediaPlayList::ArtistRole).toString(), QStringLiteral("artist1"));  }
 
+void MediaPlayListTest::crashOnEnqueue()
+{
+    MediaPlayList myPlayList;
+    DatabaseInterface myDatabaseContent;
+    DatabaseInterface myDatabaseView;
+    CrashEnqueuePlayList myCrash(&myPlayList);
+
+    connect(&myPlayList, &MediaPlayList::rowsInserted, &myCrash, \
&CrashEnqueuePlayList::crashMediaPlayList); +
+    QSignalSpy rowsAboutToBeMovedSpy(&myPlayList, \
&MediaPlayList::rowsAboutToBeMoved); +    QSignalSpy \
rowsAboutToBeRemovedSpy(&myPlayList, &MediaPlayList::rowsAboutToBeRemoved); +    \
QSignalSpy rowsAboutToBeInsertedSpy(&myPlayList, \
&MediaPlayList::rowsAboutToBeInserted); +    QSignalSpy rowsMovedSpy(&myPlayList, \
&MediaPlayList::rowsMoved); +    QSignalSpy rowsRemovedSpy(&myPlayList, \
&MediaPlayList::rowsRemoved); +    QSignalSpy rowsInsertedSpy(&myPlayList, \
&MediaPlayList::rowsInserted); +    QSignalSpy trackHasBeenAddedSpy(&myPlayList, \
&MediaPlayList::trackHasBeenAdded); +    QSignalSpy \
databaseInterfaceChangedSpy(&myPlayList, &MediaPlayList::databaseInterfaceChanged); + \
QSignalSpy persistentStateChangedSpy(&myPlayList, \
&MediaPlayList::persistentStateChanged); +    QSignalSpy dataChangedSpy(&myPlayList, \
&MediaPlayList::dataChanged); +
+    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeMovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
+    QCOMPARE(rowsRemovedSpy.count(), 0);
+    QCOMPARE(rowsMovedSpy.count(), 0);
+    QCOMPARE(rowsInsertedSpy.count(), 0);
+    QCOMPARE(trackHasBeenAddedSpy.count(), 0);
+    QCOMPARE(databaseInterfaceChangedSpy.count(), 0);
+    QCOMPARE(persistentStateChangedSpy.count(), 0);
+    QCOMPARE(dataChangedSpy.count(), 0);
+
+    myDatabaseContent.init(QStringLiteral("testDbDirectContent"));
+
+    myDatabaseView.init(QStringLiteral("testDbDirectView"));
+
+    connect(&myDatabaseContent, &DatabaseInterface::databaseChanged,
+            &myDatabaseView, &DatabaseInterface::databaseHasChanged);
+
+    myPlayList.setDatabaseInterface(&myDatabaseView);
+
+    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeMovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
+    QCOMPARE(rowsRemovedSpy.count(), 0);
+    QCOMPARE(rowsMovedSpy.count(), 0);
+    QCOMPARE(rowsInsertedSpy.count(), 0);
+    QCOMPARE(trackHasBeenAddedSpy.count(), 0);
+    QCOMPARE(databaseInterfaceChangedSpy.count(), 1);
+    QCOMPARE(persistentStateChangedSpy.count(), 0);
+    QCOMPARE(dataChangedSpy.count(), 0);
+
+    QCOMPARE(myPlayList.databaseInterface(), &myDatabaseView);
+
+    auto newTracks = QHash<QString, QVector<MusicAudioTrack>>();
+    auto newCovers = QHash<QString, QUrl>();
+
+    newTracks[QStringLiteral("album1")] = {
+        {true, QStringLiteral("$1"), QStringLiteral("0"), QStringLiteral("track1"),
+            QStringLiteral("artist1"), QStringLiteral("album1"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$1"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$1"))}}, +        {true, \
QStringLiteral("$2"), QStringLiteral("0"), QStringLiteral("track2"), +            \
QStringLiteral("artist1"), QStringLiteral("album1"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$2"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$2"))}}, +        {true, \
QStringLiteral("$3"), QStringLiteral("0"), QStringLiteral("track3"), +            \
QStringLiteral("artist1"), QStringLiteral("album1"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$3"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$3"))}}, +        {true, \
QStringLiteral("$4"), QStringLiteral("0"), QStringLiteral("track4"), +            \
QStringLiteral("artist1"), QStringLiteral("album1"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$4"))}, +            \
{QUrl::fromLocalFile(QStringLiteral("file://image$4"))}}, +    };
+
+    newTracks[QStringLiteral("album2")] = {
+        {true, QStringLiteral("$5"), QStringLiteral("0"), QStringLiteral("track1"),
+            QStringLiteral("artist1"), QStringLiteral("album2"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$5"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$5"))}}, +        {true, \
QStringLiteral("$6"), QStringLiteral("0"), QStringLiteral("track2"), +            \
QStringLiteral("artist1"), QStringLiteral("album2"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$6"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$6"))}}, +        {true, \
QStringLiteral("$7"), QStringLiteral("0"), QStringLiteral("track3"), +            \
QStringLiteral("artist1"), QStringLiteral("album2"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$7"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$7"))}}, +        {true, \
QStringLiteral("$8"), QStringLiteral("0"), QStringLiteral("track4"), +            \
QStringLiteral("artist1"), QStringLiteral("album2"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$8"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$8"))}}, +        {true, \
QStringLiteral("$9"), QStringLiteral("0"), QStringLiteral("track5"), +            \
QStringLiteral("artist1"), QStringLiteral("album2"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$9"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$9"))}}, +        {true, \
QStringLiteral("$10"), QStringLiteral("0"), QStringLiteral("track6"), +            \
QStringLiteral("artist1"), QStringLiteral("album2"), 1, {}, \
{QUrl::fromLocalFile(QStringLiteral("$10"))}, +    \
{QUrl::fromLocalFile(QStringLiteral("file://image$10"))}} +    };
+
+    newCovers[QStringLiteral("album1")] = \
QUrl::fromLocalFile(QStringLiteral("album1")); +    \
newCovers[QStringLiteral("album2")] = QUrl::fromLocalFile(QStringLiteral("album2")); \
+ +    myDatabaseContent.insertTracksList(newTracks, newCovers);
+
+    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeMovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeInsertedSpy.count(), 0);
+    QCOMPARE(rowsRemovedSpy.count(), 0);
+    QCOMPARE(rowsMovedSpy.count(), 0);
+    QCOMPARE(rowsInsertedSpy.count(), 0);
+    QCOMPARE(trackHasBeenAddedSpy.count(), 0);
+    QCOMPARE(databaseInterfaceChangedSpy.count(), 1);
+    QCOMPARE(persistentStateChangedSpy.count(), 0);
+    QCOMPARE(dataChangedSpy.count(), 0);
+
+    auto newTrackID = \
myDatabaseView.trackIdFromTitleAlbumArtist(QStringLiteral("track6"), \
QStringLiteral("album2"), QStringLiteral("artist1")); +    \
myPlayList.enqueue(newTrackID); +
+    QCOMPARE(rowsAboutToBeRemovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeMovedSpy.count(), 0);
+    QCOMPARE(rowsAboutToBeInsertedSpy.count(), 1);
+    QCOMPARE(rowsRemovedSpy.count(), 0);
+    QCOMPARE(rowsMovedSpy.count(), 0);
+    QCOMPARE(rowsInsertedSpy.count(), 1);
+    QCOMPARE(trackHasBeenAddedSpy.count(), 1);
+    QCOMPARE(databaseInterfaceChangedSpy.count(), 1);
+    QCOMPARE(persistentStateChangedSpy.count(), 1);
+    QCOMPARE(dataChangedSpy.count(), 0);
+}
+
+
+
+
+CrashEnqueuePlayList::CrashEnqueuePlayList(MediaPlayList *list, QObject *parent) : \
QObject(parent), mList(list) +{
+}
+
+void CrashEnqueuePlayList::crashMediaPlayList()
+{
+    mList->data(mList->index(0, 0), MediaPlayList::ResourceRole);
+}
 
 QTEST_MAIN(MediaPlayListTest)
 
diff --git a/autotests/mediaplaylisttest.h b/autotests/mediaplaylisttest.h
index 50a9eaf..ca34378 100644
--- a/autotests/mediaplaylisttest.h
+++ b/autotests/mediaplaylisttest.h
@@ -61,6 +61,27 @@ private Q_SLOTS:
 
     void enqueueClearAndEnqueue();
 
+    void crashOnEnqueue();
+
+};
+
+class MediaPlayList;
+
+class CrashEnqueuePlayList : public QObject
+{
+    Q_OBJECT
+
+public:
+
+    CrashEnqueuePlayList(MediaPlayList *list, QObject *parent = 0);
+
+public Q_SLOTS:
+
+    void crashMediaPlayList();
+
+private:
+
+    MediaPlayList *mList = nullptr;
 };
 
 #endif // MEDIAPLAYLISTTEST_H
diff --git a/src/mediaplaylist.cpp b/src/mediaplaylist.cpp
index 555b9f3..e1d435c 100644
--- a/src/mediaplaylist.cpp
+++ b/src/mediaplaylist.cpp
@@ -257,6 +257,7 @@ void MediaPlayList::enqueue(MediaPlayListEntry newEntry)
 
     beginInsertRows(QModelIndex(), d->mData.size(), d->mData.size());
     d->mData.push_back(newEntry);
+    d->mTrackData.push_back({});
     endInsertRows();
 
     emit persistentStateChanged();
@@ -266,14 +267,14 @@ void MediaPlayList::enqueue(MediaPlayListEntry newEntry)
 
         if (newTrackId != 0) {
             d->mData.last().mId = newTrackId;
-            d->mTrackData.push_back(d->mMusicDatabase->trackFromDatabaseId(newTrackId));
 +            d->mTrackData.last() = \
d->mMusicDatabase->trackFromDatabaseId(newTrackId);  d->mData.last().mIsValid = true;
 
             Q_EMIT dataChanged(index(rowCount() - 1, 0), index(rowCount() - 1, 0), \
{});  }
     } else {
         if (d->mMusicDatabase && newEntry.mIsValid) {
-            d->mTrackData.push_back(d->mMusicDatabase->trackFromDatabaseId(newEntry.mId));
 +            d->mTrackData.last() = \
d->mMusicDatabase->trackFromDatabaseId(newEntry.mId);  }
     }
 
@@ -506,7 +507,7 @@ void MediaPlayList::endTrackAdded(QVector<qulonglong> newTracks)
 
         if (newTrackId != 0) {
             oneEntry.mId = newTrackId;
-            d->mTrackData.push_back(d->mMusicDatabase->trackFromDatabaseId(newTrackId));
 +            d->mTrackData[i] = d->mMusicDatabase->trackFromDatabaseId(newTrackId);
             oneEntry.mIsValid = true;
 
             Q_EMIT dataChanged(index(i, 0), index(i, 0), {});


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic