Commit b67785f9 authored by Michael Pyne's avatar Michael Pyne
Browse files

Fix undefined behavior in PlaylistItem.

The PlaylistItem ctor meant to be called from its subclass's constructor
(CollectionListItem) copied the this pointer too early. When
PlaylistItem is being constructed, by C++ rules the PlaylistItem is not
a CollectionListItem yet. This was appropriately flagged by ubsan.

I fixed this by ensuring the only user of this subclass fixes up the
pointer as soon as it can, and making it a private constructor so it's
not used elsewhere by mistake.
parent 10110d76
......@@ -533,10 +533,11 @@ void CollectionListItem::repaint() const
// CollectionListItem protected methods
////////////////////////////////////////////////////////////////////////////////
CollectionListItem::CollectionListItem(CollectionList *parent, const FileHandle &file) :
PlaylistItem(parent),
m_shuttingDown(false)
CollectionListItem::CollectionListItem(CollectionList *parent, const FileHandle &file)
: PlaylistItem(parent)
, m_shuttingDown(false)
{
PlaylistItem::m_collectionItem = this;
parent->addToDict(file.absFilePath(), this);
sharedData()->fileHandle = file;
......
......@@ -233,12 +233,13 @@ PlaylistItem::PlaylistItem(CollectionListItem *item, Playlist *parent, QTreeWidg
// This constructor should only be used by the CollectionList subclass.
PlaylistItem::PlaylistItem(CollectionList *parent) :
QTreeWidgetItem(parent),
m_watched(0)
PlaylistItem::PlaylistItem(CollectionList *parent)
: QTreeWidgetItem(parent)
// We *will* be this but we aren't yet; subclass will fix
, m_collectionItem(nullptr)
, m_watched(false)
{
d = new Data;
m_collectionItem = static_cast<CollectionListItem *>(this);
setFlags(flags() | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
}
......
......@@ -163,11 +163,6 @@ protected:
PlaylistItem(CollectionListItem *item, Playlist *parent);
PlaylistItem(CollectionListItem *item, Playlist *parent, QTreeWidgetItem *after);
/**
* This is the constructor that should be used by subclasses.
*/
PlaylistItem(CollectionList *parent);
/**
* See the class documentation for an explanation of construction and deletion
* of PlaylistItems.
......@@ -200,6 +195,12 @@ protected:
private:
DataPtr d;
/**
* This is the constructor that should be used by CollectionList.
*/
PlaylistItem(CollectionList *parent);
friend class CollectionList;
void setup(CollectionListItem *item);
CollectionListItem *m_collectionItem;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment