diff options
author | Max Kellermann <max@musicpd.org> | 2021-02-16 13:47:22 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2021-02-16 13:52:25 +0100 |
commit | 80531ef8d801e3dc8e59afa1fd70d4710a80d358 (patch) | |
tree | 0165dd034b4321f8cfa124b70a91e1b05015202a /src/db/plugins/simple/ExportedSong.hxx | |
parent | a91fba6a3d84d033084fd9461b12b66df86e7f22 (diff) |
db/simple: fix ExportedSong move constructor for non-owning sources
If the constructor moves from an ExportedSong instance which refers to
somebody else's "Tag" instance, the newly constructed instance will
instead refer to its own empty "tag_buffer" field. This broke
SimpleDatabase::GetSong(), i.e. all songs on the queue restored from
the state file or added using the "addid" command.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1089
Diffstat (limited to 'src/db/plugins/simple/ExportedSong.hxx')
-rw-r--r-- | src/db/plugins/simple/ExportedSong.hxx | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/db/plugins/simple/ExportedSong.hxx b/src/db/plugins/simple/ExportedSong.hxx index 37e4109b5..9a2d54a85 100644 --- a/src/db/plugins/simple/ExportedSong.hxx +++ b/src/db/plugins/simple/ExportedSong.hxx @@ -29,6 +29,12 @@ * a #LightSong, e.g. a merged #Tag. */ class ExportedSong : public LightSong { + /** + * A reference target for LightSong::tag, but it is only used + * if this instance "owns" the #Tag. For instances referring + * to a foreign #Tag instance (e.g. a Song::tag), this field + * is not used (and empty). + */ Tag tag_buffer; public: @@ -42,10 +48,20 @@ public: points to this instance's #Tag field instead of leaving a dangling reference to the source object's #Tag field */ ExportedSong(ExportedSong &&src) noexcept - :LightSong(src, tag_buffer), + :LightSong(src, + /* refer to tag_buffer only if the + moved-from instance also owned the Tag + which its LightSong::tag field refers + to */ + OwnsTag() ? tag_buffer : src.tag), tag_buffer(std::move(src.tag_buffer)) {} ExportedSong &operator=(ExportedSong &&) = delete; + +private: + bool OwnsTag() const noexcept { + return &tag == &tag_buffer; + } }; #endif |